def test_keeps_using_solid_passes_while_they_shrink_size(): good = { hbytes([0, 1, 2, 3, 4, 5]), hbytes([0, 1, 2, 3, 5]), hbytes([0, 1, 3, 5]), hbytes([1, 3, 5]), hbytes([1, 5]), } initial = max(good, key=sort_key) @shrinking_from(initial) def shrinker(data): while True: data.draw_bits(8) if hbytes(data.buffer) in good: data.mark_interesting() shrinker.clear_passes() d1 = shrinker.add_new_pass(block_program('X')) d2 = shrinker.add_new_pass(block_program('-')) for _ in range(3): shrinker.single_greedy_shrink_iteration() assert d1.classification == PassClassification.HOPEFUL assert d2.classification == PassClassification.CANDIDATE
def test_block_deletion_can_delete_short_ranges(monkeypatch): @shrinking_from([ v for i in range(5) for _ in range(i + 1) for v in [0, i]] ) def shrinker(data): while True: n = data.draw_bits(16) for _ in range(n): if data.draw_bits(16) != n: data.mark_invalid() if n == 4: data.mark_interesting() for i in range(1, 5): block_program('X' * i)(shrinker) assert list(shrinker.shrink_target.buffer) == [0, 4] * 5
def test_will_enable_previously_bad_passes_when_failing_to_shrink(): # We lead the shrinker down the garden path a bit where it keeps making # progress but only lexically. When it finally gets down to the minimum good = { hbytes([1, 2, 3, 4, 5, 6]), hbytes([1, 2, 3, 4, 5, 5]), hbytes([1, 2, 2, 4, 5, 5]), hbytes([1, 2, 2, 4, 4, 5]), hbytes([0, 2, 2, 4, 4, 5]), hbytes([0, 1, 2, 4, 4, 5]), } initial = max(good) final = min(good) @shrinking_from(initial + hbytes([0, 7])) def shrinker(data): string = hbytes([data.draw_bits(8) for _ in range(6)]) if string in good: n = 0 while data.draw_bits(8) != 7: n += 1 if not (string == final or n > 0): data.mark_invalid() data.mark_interesting() # In order to get to the minimized result we want to run both of these, # but the second pass starts out as disabled (and anyway won't work until # the first has hit fixity). shrinker.clear_passes() shrinker.add_new_pass(block_program('-')) shrinker.add_new_pass(block_program('X')) shrinker.shrink() assert shrinker.shrink_target.buffer == final + hbytes([7])
def test_passes_can_come_back_to_life(): initial = hbytes([1, 2, 3, 4, 5, 6]) buf1 = hbytes([0, 1, 3, 4, 5, 6]) buf2 = hbytes([0, 1, 3, 4, 4, 6]) good = { initial, buf1, buf2 } @shrinking_from(initial) def shrinker(data): string = hbytes([data.draw_bits(8) for _ in range(6)]) if string in good: data.mark_interesting() shrinker.clear_passes() shrinker.add_new_pass(block_program('--')) shrinker.add_new_pass(block_program('-')) shrinker.single_greedy_shrink_iteration() assert shrinker.shrink_target.buffer == buf1 shrinker.single_greedy_shrink_iteration() assert shrinker.shrink_target.buffer == buf2