From ed292c0b4036c4dd84d230be64d8504623070c47 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Tue, 21 Apr 2020 10:11:29 +1000 Subject: 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). --- infra/bisector.py | 55 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 19 deletions(-) (limited to 'infra/bisector.py') diff --git a/infra/bisector.py b/infra/bisector.py index 1b06997d..ee13be3d 100644 --- a/infra/bisector.py +++ b/infra/bisector.py @@ -94,35 +94,23 @@ def main(): return 0 -def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data): # pylint: disable=too-many-locals - """From a commit range, this function caluclates which introduced a - specific error from a fuzz test_case_path. - - Args: - old_commit: The oldest commit in the error regression range. - new_commit: The newest commit in the error regression range. - test_case_path: The file path of the test case that triggers the error - fuzz_target: The name of the fuzzer to be tested. - build_data: a class holding all of the input parameters for bisection. - - Returns: - A Result. - - Raises: - ValueError: when a repo url can't be determine from the project. - """ +def _bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data): # pylint: disable=too-many-locals + """Perform the bisect.""" with tempfile.TemporaryDirectory() as tmp_dir: repo_url, repo_path = build_specified_commit.detect_main_repo( build_data.project_name, commit=new_commit) if not repo_url or not repo_path: raise ValueError('Main git repo can not be determined.') + # Copy /src from the built Docker container to ensure all dependencies + # exist. This will be mounted when running them. host_src_dir = build_specified_commit.copy_src_from_docker( build_data.project_name, tmp_dir) - bisect_repo_manager = repo_manager.RepoManager( - repo_url, host_src_dir, repo_name=os.path.basename(repo_path)) + bisect_repo_manager = repo_manager.BaseRepoManager( + os.path.join(host_src_dir, os.path.basename(repo_path))) commit_list = bisect_repo_manager.get_commit_list(new_commit, old_commit) + old_idx = len(commit_list) - 1 new_idx = 0 logging.info('Testing against new_commit (%s)', commit_list[new_idx]) @@ -166,5 +154,34 @@ def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data): # return Result(repo_url, commit_list[new_idx]) +def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data): # pylint: disable=too-many-locals + """From a commit range, this function caluclates which introduced a + specific error from a fuzz test_case_path. + + Args: + old_commit: The oldest commit in the error regression range. + new_commit: The newest commit in the error regression range. + test_case_path: The file path of the test case that triggers the error + fuzz_target: The name of the fuzzer to be tested. + build_data: a class holding all of the input parameters for bisection. + + Returns: + The commit SHA that introduced the error or None. + + Raises: + ValueError: when a repo url can't be determine from the project. + """ + result = _bisect(old_commit, new_commit, test_case_path, fuzz_target, + build_data) + + # Clean up projects/ as _bisect may have modified it. + oss_fuzz_repo_manager = repo_manager.BaseRepoManager(helper.OSS_FUZZ_DIR) + oss_fuzz_repo_manager.git(['reset', 'projects']) + oss_fuzz_repo_manager.git(['checkout', 'projects']) + oss_fuzz_repo_manager.git(['clean', '-fxd', 'projects']) + + return result + + if __name__ == '__main__': main() -- cgit v1.2.3