def test_avoids_zig_zag_trap(p): b, marker, lower_bound = p b = hbytes(b) marker = hbytes(marker) n_bits = 8 * (len(b) + 1) def test_function(data): m = data.draw_bits(n_bits) if m < lower_bound: data.mark_invalid() n = data.draw_bits(n_bits) if data.draw_bytes(len(marker)) != marker: data.mark_invalid() if abs(m - n) == 1: data.mark_interesting() runner = ConjectureRunner(test_function, database_key=None, settings=settings(database=None, max_shrinks=100, verbosity=Verbosity.debug)) runner.debug = note original_debug_data = runner.debug_data def debug_interesting(data): if data.status == Status.INTERESTING: original_debug_data(data) runner.debug_data = debug_interesting runner.test_function( ConjectureData.for_buffer(b + hbytes([0]) + b + hbytes([1]) + marker)) assert runner.interesting_examples runner.run() v, = runner.interesting_examples.values() data = ConjectureData.for_buffer(v.buffer) m = data.draw_bits(n_bits) n = data.draw_bits(n_bits) assert m == lower_bound if m == 0: assert n == 1 else: assert n == m - 1
def test_always_reduces_integers_to_smallest_suitable_sizes(problem): n, blob = problem try: d = ConjectureData.for_buffer(blob) k = d.draw(st.integers()) stop = blob[len(d.buffer)] except (StopTest, IndexError): reject() assume(k > n) assume(stop > 0) def f(data): k = data.draw(st.integers()) data.output = repr(k) if data.draw_bits(8) == stop and k >= n: data.mark_interesting() runner = ConjectureRunner(f, random=Random(0), settings=settings( suppress_health_check=HealthCheck.all(), timeout=unlimited, phases=(Phase.shrink,), database=None, verbosity=Verbosity.quiet )) runner.test_function(ConjectureData.for_buffer(blob)) assert runner.interesting_examples runner.run() v, = runner.interesting_examples.values() runner.debug = note runner.debug_data(v) m = ConjectureData.for_buffer(v.buffer).draw(st.integers()) assert m == n # Upper bound on the length needed is calculated as follows: # * We have an initial byte at the beginning to decide the length of the # integer. # * We have a terminal byte as the stop value. # * The rest is the integer payload. This should be n. Including the sign # bit, n needs (1 + n.bit_length()) / 8 bytes (rounded up). But we only # have power of two sizes, so it may be up to a factor of two more than # that. assert len(v.buffer) <= 2 + 2 * max(1, ceil((1 + n.bit_length()) / 8))