def test_can_reduce_poison_from_any_subtree(size, seed): """This test validates that we can minimize to any leaf node of a binary tree, regardless of where in the tree the leaf is.""" random = Random(seed) # Initially we create the minimal tree of size n, regardless of whether it # is poisoned (which it won't be - the poison event essentially never # happens when drawing uniformly at random). # Choose p so that the expected size of the tree is equal to the desired # size. p = 1.0 / (2.0 - 1.0 / size) strat = PoisonedTree(p) def test_function(data): v = data.draw(strat) if len(v) >= size: data.mark_interesting() runner = ConjectureRunner(test_function, random=random, settings=TEST_SETTINGS) runner.generate_new_examples() runner.shrink_interesting_examples() (data,) = runner.interesting_examples.values() assert len(ConjectureData.for_buffer(data.buffer).draw(strat)) == size starts = [b.start for b in data.blocks if b.length == 2] assert len(starts) % 2 == 0 for i in range(0, len(starts), 2): # Now for each leaf position in the tree we try inserting a poison # value artificially. Additionally, we add a marker to the end that # must be preserved. The marker means that we are not allow to rely on # discarding the end of the buffer to get the desired shrink. u = starts[i] marker = bytes([1, 2, 3, 4]) def test_function_with_poison(data): v = data.draw(strat) m = data.draw_bytes(len(marker)) if POISON in v and m == marker: data.mark_interesting() runner = ConjectureRunner( test_function_with_poison, random=random, settings=TEST_SETTINGS ) runner.cached_test_function( data.buffer[:u] + bytes([255]) * 4 + data.buffer[u + 4 :] + marker ) assert runner.interesting_examples runner.shrink_interesting_examples() (shrunk,) = runner.interesting_examples.values() assert ConjectureData.for_buffer(shrunk.buffer).draw(strat) == (POISON,)
def generate_new_examples(self): def draw_bytes(data, n): return uniform(self.random, n) while not self.interesting_examples: self.test_function( ConjectureData(draw_bytes=draw_bytes, max_length=self.settings.buffer_size))
def test_minimal_poisoned_containers(seed, size, p, strategy_class, monkeypatch): elements = Poisoned(p) strategy = strategy_class(elements, size) def test_function(data): v = data.draw(strategy) data.output = repr(v) if POISON in v: data.mark_interesting() runner = TrialRunner(test_function, random=Random(seed), settings=TRIAL_SETTINGS) runner.run() (v,) = runner.interesting_examples.values() result = ConjectureData.for_buffer(v.buffer).draw(strategy) assert len(result) == 1
def test_minimal_poisoned_containers(seed, size, p, strategy_class, monkeypatch): elements = Poisoned(p) strategy = strategy_class(elements, size) def test_function(data): v = data.draw(strategy) data.output = repr(v) if POISON in v: data.mark_interesting() runner = TrialRunner(test_function, random=Random(seed), settings=TRIAL_SETTINGS) runner.run() v, = runner.interesting_examples.values() result = ConjectureData.for_buffer(v.buffer).draw(strategy) assert len(result) == 1
def test_minimal_poisoned_containers(seed, size, p, strategy_class, monkeypatch): # Disable emergency measures for these tests, as they're ones that we # should be able to perform without them. monkeypatch.setattr(Shrinker, 'emergency_measures', lambda self: None) elements = Poisoned(p) strategy = strategy_class(elements, size) def test_function(data): v = data.draw(strategy) data.output = repr(v) if POISON in v: data.mark_interesting() runner = TrialRunner(test_function, random=Random(seed), settings=TRIAL_SETTINGS) runner.run() v, = runner.interesting_examples.values() result = ConjectureData.for_buffer(v.buffer).draw(strategy) assert len(result) == 1
def test_can_reduce_poison_from_any_subtree(size, seed): """This test validates that we can minimize to any leaf node of a binary tree, regardless of where in the tree the leaf is.""" random = Random(seed) # Initially we create the minimal tree of size n, regardless of whether it # is poisoned (which it won't be - the poison event essentially never # happens when drawing uniformly at random). # Choose p so that the expected size of the tree is equal to the desired # size. p = 1.0 / (2.0 - 1.0 / size) strat = PoisonedTree(p) def test_function(data): v = data.draw(strat) if len(v) >= size: data.mark_interesting() runner = ConjectureRunner( test_function, random=random, settings=settings(TEST_SETTINGS, buffer_size=LOTS) ) while not runner.interesting_examples: runner.test_function( runner.new_conjecture_data(lambda data, n: uniform(random, n)) ) runner.shrink_interesting_examples() data, = runner.interesting_examples.values() assert len(ConjectureData.for_buffer(data.buffer).draw(strat)) == size starts = [b.start for b in data.blocks if b.length == 2] assert len(starts) % 2 == 0 for i in hrange(0, len(starts), 2): # Now for each leaf position in the tree we try inserting a poison # value artificially. Additionally, we add a marker to the end that # must be preserved. The marker means that we are not allow to rely on # discarding the end of the buffer to get the desired shrink. u = starts[i] marker = hbytes([1, 2, 3, 4]) def test_function_with_poison(data): v = data.draw(strat) m = data.draw_bytes(len(marker)) if POISON in v and m == marker: data.mark_interesting() runner = ConjectureRunner( test_function_with_poison, random=random, settings=TEST_SETTINGS ) runner.cached_test_function( data.buffer[:u] + hbytes([255]) * 4 + data.buffer[u + 4 :] + marker ) assert runner.interesting_examples runner.shrink_interesting_examples() shrunk, = runner.interesting_examples.values() assert ConjectureData.for_buffer(shrunk.buffer).draw(strat) == (POISON,)