def test_shrinker_skips_stale_examples(monkeypatch, pass_name): # Pretend that all example identifiers are stale, to test that this case # is handled cleanly. monkeypatch.setattr( Shrinker, "example_for_stable_identifier", counts_calls(lambda self, x: None) ) # For "example_deletion_with_block_lowering", also pretend that all blocks # are shrinking blocks, so that steps can be generated. monkeypatch.setattr( Shrinker, "is_shrinking_block", counts_calls(lambda self, i: True) ) # Declare a test function that should satisfy step generation for all of # the relevant shrink passes. @shrinking_from([255] * 5) def shrinker(data): total = 0 data.start_example(0) for _ in range(5): data.start_example(0) total += data.draw_bits(8) data.stop_example(0) data.stop_example(0) data.mark_interesting() # Run the shrink pass; this should not throw. shrinker.fixate_shrink_passes([pass_name]) # Confirm that the pass had to deal with stale examples. assert Shrinker.example_for_stable_identifier.calls > 0
def test_block_programs_fail_efficiently(monkeypatch): # Create 256 byte-sized blocks. None of the blocks can be deleted, and # every deletion attempt produces a different buffer. @shrinking_from(bytes(range(256))) def shrinker(data): values = set() for _ in range(256): v = data.draw_bits(8) values.add(v) if len(values) == 256: data.mark_interesting() monkeypatch.setattr( Shrinker, "run_block_program", counts_calls(Shrinker.run_block_program) ) shrinker.max_stall = 500 shrinker.fixate_shrink_passes([block_program("XX")]) assert shrinker.shrinks == 0 assert 250 <= shrinker.calls <= 260 # The block program should have been run roughly 255 times, with a little # bit of wiggle room for implementation details. # - Too many calls mean that failing steps are doing too much work. # - Too few calls mean that this test is probably miscounting and buggy. assert 250 <= Shrinker.run_block_program.calls <= 260
def test_block_programs_fail_efficiently(monkeypatch): # Create 256 byte-sized blocks. None of the blocks can be deleted, and # every deletion attempt produces a different buffer. @shrinking_from(hbytes(hrange(256))) def shrinker(data): values = set() for _ in hrange(256): v = data.draw_bits(8) values.add(v) if len(values) == 256: data.mark_interesting() monkeypatch.setattr( Shrinker, "run_block_program", counts_calls(Shrinker.run_block_program) ) shrinker.fixate_shrink_passes([block_program("XX")]) assert shrinker.shrinks == 0 assert 250 <= shrinker.calls <= 260 # The block program should have been run roughly 255 times, with a little # bit of wiggle room for implementation details. # - Too many calls mean that failing steps are doing too much work. # - Too few calls mean that this test is probably miscounting and buggy. assert 250 <= Shrinker.run_block_program.calls <= 260