def test_build_fuzzers_from_commit(self): """Tests if the fuzzers can build at a proper commit. This is done by using a known regression range for a specific test case. The old commit should show the error when its fuzzers run and the new one should not. """ project_name = 'yara' old_commit = 'f79be4f2330f4b89ea2f42e1c44ca998c59a0c0f' new_commit = 'f50a39051ea8c7f10d6d8db9656658b49601caef' fuzzer = 'rules_fuzzer' test_data = 'infra/yara_test_data' build_fuzzer_from_commit( project_name, old_commit, '/usr/local/google/home/lneat/Documents/oss-fuzz/infra/tmp', sanitizer='address') old_error_code = self.reproduce_error(project_name, test_data, fuzzer) build_fuzzer_from_commit( project_name, new_commit, '/usr/local/google/home/lneat/Documents/oss-fuzz/infra/tmp', sanitizer='address') new_error_code = self.reproduce_error(project_name, test_data, fuzzer) self.assertNotEqual(new_error_code, old_error_code)
def bisect(commit_old, commit_new, testcase, fuzz_target, build_data): """From a commit range, this function caluclates which introduced a specific error from a fuzz testcase. Args: commit_old: The oldest commit in the error regression range commit_new: The newest commit in the error regression range testcase: 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 """ local_store_path = tempfile.mkdtemp() repo_url = build_specified_commit.infer_main_repo(build_data.project_name, local_store_path, commit_old) bisect_repo_manager = repo_manager.RepoManager(repo_url, local_store_path) commit_list = bisect_repo_manager.get_commit_list(commit_old, commit_new) build_specified_commit.build_fuzzer_from_commit( build_data.project_name, commit_list[0], bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer, build_data.architecture, bisect_repo_manager) error_code = helper.reproduce_impl(build_data.project_name, fuzz_target, False, [], [], testcase) old_idx = len(commit_list) - 1 new_idx = 0 if len(commit_list) == 1: if not error_code: return None return commit_list[0] while old_idx - new_idx != 1: curr_idx = (old_idx + new_idx) // 2 build_specified_commit.build_fuzzer_from_commit( build_data.project_name, commit_list[curr_idx], bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer, build_data.architecture, bisect_repo_manager) error_exists = ( helper.reproduce_impl(build_data.project_name, fuzz_target, False, [], [], testcase) == error_code) if error_exists == error_code: new_idx = curr_idx else: old_idx = curr_idx return commit_list[new_idx]
def test_build_fuzzers_from_commit(self): """Tests if the fuzzers can build at a proper commit. This is done by using a known regression range for a specific test case. The old commit should show the error when its fuzzers run and the new one should not. """ project_name = 'yara' old_commit = 'f79be4f2330f4b89ea2f42e1c44ca998c59a0c0f' new_commit = 'f50a39051ea8c7f10d6d8db9656658b49601caef' fuzzer = 'rules_fuzzer' test_data = 'infra/yara_test_data' build_specified_commit.build_fuzzer_from_commit( project_name, old_commit, 'tmp', sanitizer='address') old_error_code = helper.reproduce_impl(project_name, fuzzer, False, [], [], test_data) build_specified_commit.build_fuzzer_from_commit( project_name, new_commit, 'tmp', sanitizer='address') new_error_code = helper.reproduce_impl(project_name, fuzzer, False, [], [], test_data) self.assertNotEqual(new_error_code, old_error_code)
def bisect(commit_old, commit_new, testcase, fuzz_target, build_data): """From a commit range, this function caluclates which introduced a specific error from a fuzz testcase. Args: commit_old: The oldest commit in the error regression range commit_new: The newest commit in the error regression range testcase: 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 """ with tempfile.TemporaryDirectory() as tmp_dir: repo_url, repo_name = build_specified_commit.detect_main_repo_from_docker( build_data.project_name, commit_old) if not repo_url or not repo_name: raise ValueError('Main git repo can not be determined.') bisect_repo_manager = repo_manager.RepoManager( repo_url, tmp_dir, repo_name=repo_name) commit_list = bisect_repo_manager.get_commit_list(commit_old, commit_new) old_idx = len(commit_list) - 1 new_idx = 0 build_specified_commit.build_fuzzer_from_commit( build_data.project_name, commit_list[new_idx], bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer, build_data.architecture, bisect_repo_manager) expected_error_code = helper.reproduce_impl(build_data.project_name, fuzz_target, False, [], [], testcase) # Check if the error is persistent through the commit range build_specified_commit.build_fuzzer_from_commit( build_data.project_name, commit_list[old_idx], bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer, build_data.architecture, bisect_repo_manager) oldest_error_code = helper.reproduce_impl(build_data.project_name, fuzz_target, False, [], [], testcase) if expected_error_code == oldest_error_code: return commit_list[old_idx] while old_idx - new_idx > 1: curr_idx = (old_idx + new_idx) // 2 build_specified_commit.build_fuzzer_from_commit( build_data.project_name, commit_list[curr_idx], bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer, build_data.architecture, bisect_repo_manager) error_code = helper.reproduce_impl(build_data.project_name, fuzz_target, False, [], [], testcase) if expected_error_code == error_code: new_idx = curr_idx else: old_idx = curr_idx return commit_list[new_idx]