From d446c30d36b22e7d00aa3cd2d0926b74b2ba266e Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Tue, 28 May 2024 15:31:14 -0400 Subject: [PATCH] Fix typing in grizzly reducer This found a bug in how the cache was being synced between grizzly and lithium. --- grizzly/reduce/core.py | 5 ++++- grizzly/reduce/strategies/__init__.py | 5 +++++ grizzly/reduce/strategies/lithium.py | 6 +++--- grizzly/reduce/test_reduce.py | 5 +++-- setup.cfg | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/grizzly/reduce/core.py b/grizzly/reduce/core.py index 4975cac0..22ac878a 100644 --- a/grizzly/reduce/core.py +++ b/grizzly/reduce/core.py @@ -24,6 +24,7 @@ FilesystemReporter, FuzzManagerReporter, Quality, + Reporter, ) from ..common.status import STATUS_DB_REDUCE, ReductionStatus from ..common.status_reporter import ReductionStatusReporter @@ -540,6 +541,7 @@ def run( not self._any_crash and self._signature_desc is None ): + assert first_expected is not None # mypy bug sig = first_expected.report.short_signature self._signature_desc = sig self._status.report() @@ -689,7 +691,7 @@ def run( # this is only possible if --no-analysis is given # just give None instead of trying to format the CrashSignature self._status.signature_info["any"] = self._any_crash - self._status.signature_info["description"] = self._signature_desc + self._status.signature_info["description"] = str(self._signature_desc) self._status.signature_info["given"] = sig_given # log a summary of what was done. @@ -717,6 +719,7 @@ def report( testcases: Testcases used to trigger results. update_status: Whether to update status "Latest Reports" """ + reporter: Reporter new_reports: List[str] = [] status = self._status.copy() # copy implicitly closes open counters for result in results: diff --git a/grizzly/reduce/strategies/__init__.py b/grizzly/reduce/strategies/__init__.py index a5512530..85d45a6b 100644 --- a/grizzly/reduce/strategies/__init__.py +++ b/grizzly/reduce/strategies/__init__.py @@ -67,6 +67,11 @@ def __init__(self, testcases: List[TestCase]) -> None: testcases: Testcases to reduce. The object does not take ownership of the testcases. """ + # Tuple[str, bytes] is str(path.relative_to(tc_root)) -> hash(testfile data) + # for each test file in tc_root (see calculate_testcase_hash below) + # Tuple[above, ...] is all the test files for a set of test cases meaning: + # 0/**, 1/**, etc. + # Set[above] is the unique test case sets which have been tried self._tried: Set[Tuple[Tuple[str, bytes], ...]] = set() self._testcase_root = Path(mkdtemp(prefix="tc_", dir=grz_tmp("reduce"))) self.dump_testcases(testcases) diff --git a/grizzly/reduce/strategies/lithium.py b/grizzly/reduce/strategies/lithium.py index a1898246..eb2b75af 100644 --- a/grizzly/reduce/strategies/lithium.py +++ b/grizzly/reduce/strategies/lithium.py @@ -113,9 +113,9 @@ def __iter__(self) -> Generator[List[TestCase], None, None]: strategy = self.strategy_cls() # pylint: disable=not-callable self._current_reducer = strategy.reduce(lithium_testcase) - # populate the lithium strategy "tried" cache - # use all cache values where all hashes other than the current file match - # the current testcase_root state. + # Populate the lithium strategy "tried" cache. + # Use all cache values where all hashes other than the current file match + # the current testcase_root state. current_tc_hash_map = dict(self._calculate_testcase_hash()) del current_tc_hash_map[str(file.relative_to(self._testcase_root))] this_tc_tried = set() diff --git a/grizzly/reduce/test_reduce.py b/grizzly/reduce/test_reduce.py index 1b8160ee..f0f04072 100644 --- a/grizzly/reduce/test_reduce.py +++ b/grizzly/reduce/test_reduce.py @@ -483,12 +483,13 @@ def wrapped(_): detect_failure=bool, interesting_str="%r != ''", is_expected=lambda contents: contents == "1\n2\n3\n", - expected_run_calls=16, + expected_run_calls=12, n_reports=1, reports={"1\n2\n3\n"}, n_other=2, other_reports={ "1\n", + "1\n2\n3", }, result=0, ), @@ -511,7 +512,7 @@ def wrapped(_): original=b"1\n2\n3\n", strategies=["check", "lines", "lines"], detect_failure=_ignore_arg( - partial([True, False, False, False, False, False, True, True].pop, 0) + partial([True, False, False, False, False, True, True, True].pop, 0) ), interesting_str="%r is anything, only in second strategy", is_expected=lambda _: True, diff --git a/setup.cfg b/setup.cfg index 80c8a687..5d4493a9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,7 +27,7 @@ install_requires = ffpuppet >= 0.11.1 FuzzManager jsbeautifier - lithium-reducer >= 0.5.3 + lithium-reducer >= 2.0.0 prefpicker >= 1.1.0 psutil >= 5.9.0 packages =