aboutsummaryrefslogtreecommitdiffhomepage
path: root/infra/cifuzz
diff options
context:
space:
mode:
authorGravatar Leo Neat <lneat@google.com>2020-03-10 15:59:43 -0700
committerGravatar GitHub <noreply@github.com>2020-03-10 15:59:43 -0700
commite58ee49e2029a2ddaf3a801b1332b1677e6854f8 (patch)
treea8747cc078f1b49564a5f1d1359ff21704ceb8d6 /infra/cifuzz
parente8ebda10eed8f3657753d5e7f67e32396567bfae (diff)
Revert "[CIFuzz] Affected fuzzers (#3450)" (#3488)
Diffstat (limited to 'infra/cifuzz')
-rw-r--r--infra/cifuzz/cifuzz.py79
-rw-r--r--infra/cifuzz/cifuzz_test.py63
2 files changed, 11 insertions, 131 deletions
diff --git a/infra/cifuzz/cifuzz.py b/infra/cifuzz/cifuzz.py
index 733d74d8..bceb58c1 100644
--- a/infra/cifuzz/cifuzz.py
+++ b/infra/cifuzz/cifuzz.py
@@ -163,8 +163,6 @@ def build_fuzzers(project_name,
if helper.docker_run(command):
logging.error('Building fuzzers failed.')
return False
- remove_unaffected_fuzzers(project_name, out_dir,
- build_repo_manager.get_git_diff(), src_in_docker)
return True
@@ -295,23 +293,23 @@ def get_target_coverage_report(latest_cov_info, target_name):
return get_json_from_url(target_url)
-def get_files_covered_by_target(latest_cov_info, target_name, src_in_docker):
+def get_files_covered_by_target(latest_cov_info, target_name,
+ oss_fuzz_project_base):
"""Gets a list of files covered by the specific fuzz target.
Args:
latest_cov_info: A dict containing a project's latest cov report info.
target_name: The name of the fuzz target whose coverage is requested.
- src_in_docker: The location of the source dir in the docker image.
+ oss_fuzz_project_base: The location where OSS-Fuzz project is cloned to for
+ the projects build.
Returns:
A list of files that the fuzzer covers or None.
Raises:
- ValueError: When the src_in_docker is not defined.
+ ValueError: When the oss_fuzz_project_base is not defined.
"""
- if not src_in_docker:
- logging.error('Project souce location in docker is not found.'
- 'Can\'t get coverage information from OSS-Fuzz.')
+ if not oss_fuzz_project_base:
return None
target_cov = get_target_coverage_report(latest_cov_info, target_name)
if not target_cov:
@@ -321,80 +319,25 @@ def get_files_covered_by_target(latest_cov_info, target_name, src_in_docker):
logging.info('No files found in coverage report.')
return None
- # Make sure cases like /src/curl and /src/curl/ are both handled.
- norm_src_in_docker = os.path.normpath(src_in_docker)
- if not norm_src_in_docker.endswith('/'):
- norm_src_in_docker += '/'
+ # Cases like curl there is /src/curl and /src/curl_fuzzers/ are handled.
+ if not oss_fuzz_project_base.endswith('/'):
+ oss_fuzz_project_base += '/'
affected_file_list = []
for file in coverage_per_file:
- norm_file_path = os.path.normpath(file['filename'])
- if not norm_file_path.startswith(norm_src_in_docker):
+ if not file['filename'].startswith(oss_fuzz_project_base):
continue
if not file['summary']['regions']['count']:
# Don't consider a file affected if code in it is never executed.
continue
- relative_path = file['filename'].replace(norm_src_in_docker, '')
+ relative_path = file['filename'].replace(oss_fuzz_project_base, '')
affected_file_list.append(relative_path)
if not affected_file_list:
return None
return affected_file_list
-def remove_unaffected_fuzzers(project_name, out_dir, files_changed,
- src_in_docker):
- """Removes all non affected fuzzers in the out directory.
-
- Args:
- project_name: The name of the relevant OSS-Fuzz project.
- out_dir: The location of the fuzzer binaries.
- files_changed: A list of files changed compared to HEAD.
- src_in_docker: The location of the source dir in the docker image.
- """
- if not files_changed:
- logging.info('No files changed compared to HEAD.')
- return
- fuzzer_paths = utils.get_fuzz_targets(out_dir)
- if not fuzzer_paths:
- logging.error('No fuzzers found in out dir.')
- return
-
- latest_cov_report_info = get_latest_cov_report_info(project_name)
- if not latest_cov_report_info:
- logging.error('Could not download latest coverage report.')
- return
- affected_fuzzers = []
- for fuzzer in fuzzer_paths:
- covered_files = get_files_covered_by_target(latest_cov_report_info,
- os.path.basename(fuzzer),
- src_in_docker)
- if not covered_files:
- # Assume a fuzzer is affected if we can't get its coverage from OSS-Fuzz.
- affected_fuzzers.append(os.path.basename(fuzzer))
- continue
-
- for file in files_changed:
- if file in covered_files:
- affected_fuzzers.append(os.path.basename(fuzzer))
-
- if not affected_fuzzers:
- logging.info('No affected fuzzers detected, keeping all as fallback.')
- return
- logging.info('Using affected fuzzers.\n %s fuzzers affected by pull request',
- ' '.join(affected_fuzzers))
-
- all_fuzzer_names = map(os.path.basename, fuzzer_paths)
-
- # Remove all the fuzzers that are not affected.
- for fuzzer in all_fuzzer_names:
- if fuzzer not in affected_fuzzers:
- try:
- os.remove(os.path.join(out_dir, fuzzer))
- except OSError as error:
- logging.error('%s occured while removing file %s', error, fuzzer)
-
-
def get_json_from_url(url):
"""Gets a json object from a specified http url.
diff --git a/infra/cifuzz/cifuzz_test.py b/infra/cifuzz/cifuzz_test.py
index 47c9a6e1..a73b94eb 100644
--- a/infra/cifuzz/cifuzz_test.py
+++ b/infra/cifuzz/cifuzz_test.py
@@ -361,68 +361,5 @@ class GetLatestCoverageReportUnitTest(unittest.TestCase):
self.assertIsNone(cifuzz.get_latest_cov_report_info(''))
-class KeepAffectedFuzzersUnitTest(unittest.TestCase):
- """Test the keep_affected_fuzzer method in the CIFuzz module."""
-
- test_fuzzer_1 = os.path.join(TEST_FILES_PATH, 'out', 'example_crash_fuzzer')
- test_fuzzer_2 = os.path.join(TEST_FILES_PATH, 'out', 'example_nocrash_fuzzer')
- example_file_changed = 'test.txt'
-
- def test_keeping_fuzzer_w_no_coverage(self):
- """Tests that a specific fuzzer is kept if it is deemed affected."""
- with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
- cifuzz, 'get_latest_cov_report_info', return_value=1):
- shutil.copy(self.test_fuzzer_1, tmp_dir)
- shutil.copy(self.test_fuzzer_2, tmp_dir)
- with unittest.mock.patch.object(cifuzz,
- 'get_files_covered_by_target',
- side_effect=[[self.example_file_changed],
- None]):
- cifuzz.remove_unaffected_fuzzers(EXAMPLE_PROJECT, tmp_dir,
- [self.example_file_changed], '')
- self.assertEqual(2, len(os.listdir(tmp_dir)))
-
- def test_keeping_specific_fuzzer(self):
- """Tests that a specific fuzzer is kept if it is deemed affected."""
- with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
- cifuzz, 'get_latest_cov_report_info', return_value=1):
- shutil.copy(self.test_fuzzer_1, tmp_dir)
- shutil.copy(self.test_fuzzer_2, tmp_dir)
- with unittest.mock.patch.object(cifuzz,
- 'get_files_covered_by_target',
- side_effect=[[self.example_file_changed],
- ['not/a/real/file']]):
- cifuzz.remove_unaffected_fuzzers(EXAMPLE_PROJECT, tmp_dir,
- [self.example_file_changed], '')
- self.assertEqual(1, len(os.listdir(tmp_dir)))
-
- def test_no_fuzzers_kept_fuzzer(self):
- """Tests that if there is no affected then all fuzzers are kept."""
- with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
- cifuzz, 'get_latest_cov_report_info', return_value=1):
- shutil.copy(self.test_fuzzer_1, tmp_dir)
- shutil.copy(self.test_fuzzer_2, tmp_dir)
- with unittest.mock.patch.object(cifuzz,
- 'get_files_covered_by_target',
- side_effect=[None, None]):
- cifuzz.remove_unaffected_fuzzers(EXAMPLE_PROJECT, tmp_dir,
- [self.example_file_changed], '')
- self.assertEqual(2, len(os.listdir(tmp_dir)))
-
- def test_both_fuzzers_kept_fuzzer(self):
- """Tests that if both fuzzers are affected then both fuzzers are kept."""
- with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
- cifuzz, 'get_latest_cov_report_info', return_value=1):
- shutil.copy(self.test_fuzzer_1, tmp_dir)
- shutil.copy(self.test_fuzzer_2, tmp_dir)
- with unittest.mock.patch.object(
- cifuzz,
- 'get_files_covered_by_target',
- side_effect=[self.example_file_changed, self.example_file_changed]):
- cifuzz.remove_unaffected_fuzzers(EXAMPLE_PROJECT, tmp_dir,
- [self.example_file_changed], '')
- self.assertEqual(2, len(os.listdir(tmp_dir)))
-
-
if __name__ == '__main__':
unittest.main()