def test_can_truncate_template_record(): class Breakable(GenericStateMachine): counter_start = 0 def __init__(self): self.counter = type(self).counter_start def steps(self): return integers() def execute_step(self, step): self.counter += 1 if self.counter > 10: assert step < 0 runner = Breakable.find_breaking_runner() strat = StateMachineSearchStrategy() r = Random(1) simplifiers = list(strat.simplifiers(r, runner)) assert simplifiers assert any(u'convert_simplifier' in s.__name__ for s in simplifiers) while runner.record: runner.record.pop() assert not runner.record for s in simplifiers: for t in s(r, runner): pass
def test_can_truncate_template_record(): class Breakable(GenericStateMachine): counter_start = 0 def __init__(self): self.counter = type(self).counter_start def steps(self): return integers() def execute_step(self, step): self.counter += 1 if self.counter > 10: assert step < 0 runner = Breakable.find_breaking_runner() strat = StateMachineSearchStrategy() r = Random(1) simplifiers = list(strat.simplifiers(r, runner)) assert simplifiers assert any(u'convert_simplifier' in s.__name__ for s in simplifiers) while runner.record: runner.record.pop() assert not runner.record for s in simplifiers: for t in s(r, runner): pass
def test_can_shrink_deserialized_execution_without_running(machine): runner = machine.find_breaking_runner() strategy = StateMachineSearchStrategy() new_runner = strategy.from_basic(strategy.to_basic(runner)) r = Random(1) for simplifier in strategy.simplifiers(r, new_runner): try: next(simplifier(r, new_runner)) except StopIteration: pass
def test_can_shrink_deserialized_execution_without_running(machine): runner = machine.find_breaking_runner() strategy = StateMachineSearchStrategy() new_runner = strategy.from_basic(strategy.to_basic(runner)) r = Random(1) for simplifier in strategy.simplifiers(r, new_runner): try: next(simplifier(r, new_runner)) except StopIteration: pass
def test_can_serialize_statemachine_execution(machine): runner = machine.find_breaking_runner() strategy = StateMachineSearchStrategy() new_runner = strategy.from_basic(strategy.to_basic(runner)) with raises(AssertionError): new_runner.run(machine()) r = Random(1) for simplifier in strategy.simplifiers(r, new_runner): try: next(simplifier(r, new_runner)) except StopIteration: pass
def test_can_serialize_statemachine_execution(machine): runner = machine.find_breaking_runner() strategy = StateMachineSearchStrategy() new_runner = strategy.from_basic(strategy.to_basic(runner)) with raises(AssertionError): new_runner.run(machine()) r = Random(1) for simplifier in strategy.simplifiers(r, new_runner): try: next(simplifier(r, new_runner)) except StopIteration: pass
def test_rejects_invalid_step_sizes_in_data(): runner = DepthMachine.find_breaking_runner() strategy = StateMachineSearchStrategy() basic = strategy.to_basic(runner) assert isinstance(basic[2], int) basic[2] = -1 with pytest.raises(BadData): strategy.from_basic(basic) basic[2] = 1000000 with pytest.raises(BadData): strategy.from_basic(basic)
def test_rejects_invalid_step_sizes_in_data(): runner = DepthMachine.find_breaking_runner() strategy = StateMachineSearchStrategy() basic = strategy.to_basic(runner) assert isinstance(basic[2], int) basic[2] = -1 with raises(BadData): strategy.from_basic(basic) basic[2] = 1000000 with raises(BadData): strategy.from_basic(basic)
generate=lambda r, p: r.getrandbits(128), simplify=simplify_bitfield, copy=lambda x: x, )) TestBitfieldJustGenerate = strategy_test_suite( basic(generate=lambda r, p: r.getrandbits(128), )) TestBitfieldWithParameter = strategy_test_suite( basic( generate_parameter=lambda r: r.getrandbits(128), generate=lambda r, p: r.getrandbits(128) & p, )) TestStatemachine = strategy_test_suite(StateMachineSearchStrategy()) def test_repr_has_specifier_in_it(): suite = TestComplex('test_can_round_trip_through_the_database') assert repr(suite) == 'strategy_test_suite(%r)' % (complex_numbers(), ) def test_can_mutate_non_basic(): mutate_basic(1.0, Random(0)) def test_can_mutate_large_int(): r = Random(0) for _ in hrange(20): mutate_basic(1 << 1024, r)
def test_can_full_simplify_breaking_example(machine): runner = machine.find_breaking_runner() strategy = StateMachineSearchStrategy() r = Random(1) for _ in strategy.full_simplify(r, runner): pass
def test_can_full_simplify_breaking_example(machine): runner = machine.find_breaking_runner() strategy = StateMachineSearchStrategy() r = Random(1) for _ in strategy.full_simplify(r, runner): pass
class HypothesisSpec(RuleBasedStateMachine): def __init__(self): super(HypothesisSpec, self).__init__() self.database = None strategies = Bundle(u'strategy') strategy_tuples = Bundle(u'tuples') objects = Bundle(u'objects') streaming_strategies = Bundle(u'streams') basic_data = Bundle(u'basic') varied_floats = Bundle(u'varied_floats') strats_with_parameters = Bundle(u'strats_with_parameters') strats_with_templates = Bundle(u'strats_with_templates') strats_with_2_templates = Bundle(u'strats_with_2_templates') def teardown(self): self.clear_database() @rule(target=basic_data, st=strats_with_templates) def to_basic(self, st): return st[0].to_basic(st[1]) @rule(data=basic_data, strat=strategies) def from_basic(self, data, strat): try: template = strat.from_basic(data) except BadData: return strat.reify(template) @rule(target=basic_data, data=basic_data, r=randoms()) def mess_with_basic(self, data, r): return mutate_basic(data, r) @rule() def clear_database(self): if self.database is not None: self.database.close() self.database = None @rule() def set_database(self): self.teardown() self.database = ExampleDatabase() @rule(st=strats_with_templates) def reify(self, st): strat, temp = st strat.reify(temp) @rule(target=strats_with_templates, st=strats_with_templates) def via_basic(self, st): strat, temp = st temp = strat.from_basic(strat.to_basic(temp)) return (strat, temp) @rule(targets=(strategies, streaming_strategies), strat=strategies) def build_stream(self, strat): return strategy(streaming(strat)) @rule(targets=(strategies, streaming_strategies), strat=strategies, i=integers(1, 10)) def evalled_stream(self, strat, i): return strategy(streaming(strat)).map(lambda x: list(x[:i]) and x) @rule(stream_strat=streaming_strategies, index=integers(0, 50)) def eval_stream(self, stream_strat, index): try: stream = stream_strat.example() list(stream[:index]) except NoExamples: pass @rule(target=strats_with_templates, st=strats_with_templates, r=randoms()) def simplify(self, st, r): strat, temp = st for temp in strat.full_simplify(r, temp): break return (strat, temp) @rule(strat=strategies, r=randoms(), mshr=integers(0, 100)) def find_constant_failure(self, strat, r, mshr): with Settings( verbosity=Verbosity.quiet, max_examples=1, min_satisfying_examples=0, database=self.database, max_shrinks=mshr, ): @given( strat, random=r, ) def test(x): assert False try: test() except AssertionError: pass @rule(strat=strategies, r=randoms(), p=floats(0, 1), mex=integers(1, 10), mshr=integers(1, 100)) def find_weird_failure(self, strat, r, mex, p, mshr): with Settings( verbosity=Verbosity.quiet, max_examples=mex, min_satisfying_examples=0, database=self.database, max_shrinks=mshr, ): @given( strat, random=r, ) def test(x): assert Random(hashlib.md5( show(x).encode(u'utf-8')).digest()).random() <= p try: test() except AssertionError: pass @rule(target=strats_with_parameters, strat=strategies, r=randoms()) def draw_parameter(self, strat, r): return (strat, strat.draw_parameter(r)) @rule(target=strats_with_templates, sp=strats_with_parameters, r=randoms()) def draw_template(self, sp, r): strat, param = sp return (strat, strat.draw_template(r, param)) @rule(target=strats_with_2_templates, sp=strats_with_parameters, r=randoms()) def draw_templates(self, sp, r): strat, param = sp return ( strat, strat.draw_template(r, param), strat.draw_template(r, param), ) @rule(st=strats_with_templates) def check_serialization(self, st): strat, template = st as_basic = strat.to_basic(template) assert show(strat.reify(template)) == show( strat.reify(strat.from_basic(as_basic))) assert as_basic == strat.to_basic(strat.from_basic(as_basic)) @rule(target=strategies, spec=sampled_from(( integers(), booleans(), floats(), complex_numbers(), fractions(), decimals(), text(), binary(), none(), StateMachineSearchStrategy(), tuples(), ))) def strategy(self, spec): return spec @rule(target=strategies, values=lists(integers() | text(), min_size=1)) def sampled_from_strategy(self, values): return sampled_from(values) @rule(target=strategies, spec=strategy_tuples) def strategy_for_tupes(self, spec): return tuples(*spec) @rule(target=strategies, source=strategies, level=integers(1, 10), mixer=text()) def filtered_strategy(s, source, level, mixer): def is_good(x): return bool( Random( hashlib.md5( (mixer + show(x)).encode(u'utf-8')).digest()).randint( 0, level)) return source.filter(is_good) @rule(target=strategies, elements=strategies) def list_strategy(self, elements): return lists(elements, average_size=AVERAGE_LIST_LENGTH) @rule(target=strategies, l=strategies, r=strategies) def or_strategy(self, l, r): return l | r @rule(target=strategies, source=strategies, result=strategies, mixer=text()) def mapped_strategy(self, source, result, mixer): cache = {} def do_map(value): rep = show(value) try: return deepcopy(cache[rep]) except KeyError: pass random = Random( hashlib.md5((mixer + rep).encode(u'utf-8')).digest()) outcome_template = result.draw_and_produce(random) cache[rep] = result.reify(outcome_template) return deepcopy(cache[rep]) return source.map(do_map) @rule(target=varied_floats, source=floats()) def float(self, source): return source @rule(target=varied_floats, source=varied_floats, offset=integers(-100, 100)) def adjust_float(self, source, offset): return int_to_float(clamp(0, float_to_int(source) + offset, 2**64 - 1)) @rule(target=strategies, left=varied_floats, right=varied_floats) def float_range(self, left, right): for f in (math.isnan, math.isinf): for x in (left, right): assume(not f(x)) left, right = sorted((left, right)) assert left <= right return strategy(floats(left, right)) @rule(target=strategies, source=strategies, result1=strategies, result2=strategies, mixer=text(), p=floats(0, 1)) def flatmapped_strategy(self, source, result1, result2, mixer, p): assume(result1 is not result2) def do_map(value): rep = show(value) random = Random( hashlib.md5((mixer + rep).encode(u'utf-8')).digest()) if random.random() <= p: return result1 else: return result2 return source.flatmap(do_map) @rule(target=strategies, value=objects) def just_strategy(self, value): return strategy(just(value)) @rule(target=strategy_tuples, source=strategies) def single_tuple(self, source): return (source, ) @rule(target=strategy_tuples, l=strategy_tuples, r=strategy_tuples) def cat_tuples(self, l, r): return l + r @rule(target=objects, strat=strategies) def get_example(self, strat): try: strat.example() except NoExamples: # Because of filtering some strategies we look for don't actually # have any examples. pass @rule(target=strategies, left=integers(), right=integers()) def integer_range(self, left, right): left, right = sorted((left, right)) return strategy(integers(left, right)) @rule(strat=strategies) def repr_is_good(self, strat): assert u' at 0x' not in repr(strat) @rule(strat=strategies) def template_upper_bound_is_valid(self, strat): ub = strat.template_upper_bound assert ub >= 0 if isinstance(ub, float): assert math.isinf(ub) else: assert isinstance(ub, int) @rule(strat=strategies, r=randoms()) def can_find_as_many_templates_as_size(self, strat, r): tempstrat = templates_for(strat) n = min(10, strat.template_upper_bound) found = [] with Settings(verbosity=Verbosity.quiet, timeout=2.0): for i in range(n): try: x = find( tempstrat, lambda t: t not in found, random=r, ) except: print(u'Exception at %d/%d. template_upper_bound=%r' % (i, n, strat.template_upper_bound)) raise found.append(x)