diff options
author | Oliver Chang <oliverchang@users.noreply.github.com> | 2020-04-21 10:11:29 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-21 10:11:29 +1000 |
commit | ed292c0b4036c4dd84d230be64d8504623070c47 (patch) | |
tree | 61098180cda60bd00e3e0bb0a2cecb8394b315b7 /infra/build_specified_commit.py | |
parent | d5ad37e6921938d83a368c09d86f48f3b6dec6b6 (diff) | |
download | oss-fuzz-ed292c0b4036c4dd84d230be64d8504623070c47.tar.gz |
Bisector: Be a bit smarter about picking which OSS-Fuzz commit to build with. (#3665)
When the build fails against HEAD OSS-Fuzz, we find the date of the
commit for the project, and use the latest revision of OSS-Fuzz before
it to rebuild the project builder container.
Subsequent runs will use the last built container, and if that fails
that will again find the closest revision of OSS-Fuzz.
Also factor BaseRepoManager out of RepoManager to provide a generic repo
manager class for dealing with existing checkouts (which don't need a
clone).
Diffstat (limited to 'infra/build_specified_commit.py')
-rw-r--r-- | infra/build_specified_commit.py | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/infra/build_specified_commit.py b/infra/build_specified_commit.py index 5a0123449..23b47eaad 100644 --- a/infra/build_specified_commit.py +++ b/infra/build_specified_commit.py @@ -21,8 +21,10 @@ import os import collections import logging import re +import shutil import helper +import repo_manager import utils BuildData = collections.namedtuple( @@ -49,7 +51,7 @@ def copy_src_from_docker(project_name, host_dir): def build_fuzzers_from_commit(commit, build_repo_manager, host_src_path, build_data): - """Builds a OSS-Fuzz fuzzer at a specific commit SHA. + """Builds a OSS-Fuzz fuzzer at a specific commit SHA. Args: commit: The commit SHA to build the fuzzers at. @@ -58,15 +60,51 @@ def build_fuzzers_from_commit(commit, build_repo_manager, host_src_path, Returns: 0 on successful build or error code on failure. """ - build_repo_manager.checkout_commit(commit, clean=False) - result = helper.build_fuzzers_impl(project_name=build_data.project_name, - clean=True, - engine=build_data.engine, - sanitizer=build_data.sanitizer, - architecture=build_data.architecture, - env_to_add=None, - source_path=host_src_path, - mount_location=os.path.join('/src')) + oss_fuzz_repo_manager = repo_manager.BaseRepoManager(helper.OSS_FUZZ_DIR) + num_retry = 1 + + for i in range(num_retry + 1): + build_repo_manager.checkout_commit(commit, clean=False) + result = helper.build_fuzzers_impl(project_name=build_data.project_name, + clean=True, + engine=build_data.engine, + sanitizer=build_data.sanitizer, + architecture=build_data.architecture, + env_to_add=None, + source_path=host_src_path, + mount_location='/src') + if result == 0 or i == num_retry: + break + + # Retry with an OSS-Fuzz builder container that's closer to the project + # commit date. + commit_date = build_repo_manager.commit_date(commit) + projects_dir = os.path.join('projects', build_data.project_name) + + # Find first change in the projects/<PROJECT> directory before the project + # commit date. + oss_fuzz_commit, _, _ = oss_fuzz_repo_manager.git([ + 'log', '--before=' + commit_date.isoformat(), '-n1', '--format=%H', + projects_dir + ], + check_result=True) + oss_fuzz_commit = oss_fuzz_commit.strip() + + logging.info('Build failed. Retrying on earlier OSS-Fuzz commit %s.', + oss_fuzz_commit) + + # Check out projects/<PROJECT> dir to the commit that was found. + oss_fuzz_repo_manager.git(['checkout', oss_fuzz_commit, projects_dir], + check_result=True) + + # Rebuild image and re-copy src dir since things in /src could have changed. + if not helper.build_image_impl(build_data.project_name): + raise RuntimeError('Failed to rebuild image.') + + shutil.rmtree(host_src_path, ignore_errors=True) + copy_src_from_docker(build_data.project_name, + os.path.dirname(host_src_path)) + return result == 0 |