def build_chooser(stream): index = [-1] choice_count = [0] context = current_build_context() context.mark_captured() def choice(values): if not values: raise IndexError('Cannot choose from empty sequence') k = len(values) - 1 if k == 0: chosen = 0 else: mask = _right_saturate(k) while True: index[0] += 1 probe = stream[index[0]] & mask if probe <= k: chosen = probe break choice_count[0] += 1 result = values[chosen] with context.local(): note('Choice #%d: %r' % (choice_count[0], result)) return result return choice
def run_state_machine(factory, data): machine = factory() check_type(GenericStateMachine, machine, "state_machine_factory()") data.conjecture_data.hypothesis_runner = machine n_steps = settings.stateful_step_count should_continue = cu.many(data.conjecture_data, min_size=1, max_size=n_steps, average_size=n_steps) print_steps = (current_build_context().is_final or current_verbosity() >= Verbosity.debug) try: if print_steps: machine.print_start() machine.check_invariants() while should_continue.more(): value = data.conjecture_data.draw(machine.steps()) if print_steps: machine.print_step(value) machine.execute_step(value) machine.check_invariants() finally: if print_steps: machine.print_end() machine.teardown()
def run_state_machine(factory, data): machine = factory() check_type(GenericStateMachine, machine, "state_machine_factory()") data.conjecture_data.hypothesis_runner = machine n_steps = settings.stateful_step_count should_continue = cu.many( data.conjecture_data, min_size=1, max_size=n_steps, average_size=n_steps ) print_steps = ( current_build_context().is_final or current_verbosity() >= Verbosity.debug ) try: if print_steps: machine.print_start() machine.check_invariants() while should_continue.more(): value = data.conjecture_data.draw(machine.steps()) if print_steps: machine.print_step(value) machine.execute_step(value) machine.check_invariants() finally: if print_steps: machine.print_end() machine.teardown()
def reify(self, template): context = current_build_context() context.mark_captured() def do_reify(t): with context.local(): return self.source_strategy.reify(t) return template.stream.map(do_reify)
def reify(self, value): context = current_build_context() if not hasattr(context, SHARED_STRATEGY_ATTRIBUTE): setattr(context, SHARED_STRATEGY_ATTRIBUTE, {}) sharing = getattr(context, SHARED_STRATEGY_ATTRIBUTE) key = self.key or self if key in sharing: value.used = False else: value.used = True sharing[key] = self.base.reify(value.base) return sharing[key]
def run_state_machine(factory, data): machine = factory() if isinstance(machine, GenericStateMachine) and not isinstance( machine, RuleBasedStateMachine): note_deprecation( "%s inherits from GenericStateMachine, which is deprecated. Use a " "RuleBasedStateMachine, or a test function with st.data(), instead." % (type(machine).__name__, ), since="2019-05-29", ) else: check_type(RuleBasedStateMachine, machine, "state_machine_factory()") data.conjecture_data.hypothesis_runner = machine n_steps = settings.stateful_step_count should_continue = cu.many(data.conjecture_data, min_size=1, max_size=n_steps, average_size=n_steps) print_steps = (current_build_context().is_final or current_verbosity() >= Verbosity.debug) try: if print_steps: machine.print_start() machine.check_invariants() while should_continue.more(): value = data.conjecture_data.draw(machine.steps()) # Assign 'result' here in case 'execute_step' fails below result = multiple() try: result = machine.execute_step(value) finally: if print_steps: # 'result' is only used if the step has target bundles. # If it does, and the result is a 'MultipleResult', # then 'print_step' prints a multi-variable assignment. machine.print_step(value, result) machine.check_invariants() finally: if print_steps: machine.print_end() machine.teardown()
def check_invariants(self, settings): for invar in self.invariants(): if self._initialize_rules_to_run and not invar.check_during_init: continue if not all(precond(self) for precond in invar.preconditions): continue if (current_build_context().is_final or settings.verbosity >= Verbosity.debug): report(f"state.{invar.function.__name__}()") result = invar.function(self) if result is not None: fail_health_check( settings, "The return value of an @invariant is always ignored, but " f"{invar.function.__qualname__} returned {result!r} " "instead of None", HealthCheck.return_value, )
def run_state_machine(factory, data): machine = factory() if isinstance(machine, GenericStateMachine) and not isinstance( machine, RuleBasedStateMachine ): note_deprecation( "%s inherits from GenericStateMachine, which is deprecated. Use a " "RuleBasedStateMachine, or a test function with st.data(), instead." % (type(machine).__name__,), since="2019-05-29", ) else: check_type(RuleBasedStateMachine, machine, "state_machine_factory()") data.conjecture_data.hypothesis_runner = machine n_steps = settings.stateful_step_count should_continue = cu.many( data.conjecture_data, min_size=1, max_size=n_steps, average_size=n_steps ) print_steps = ( current_build_context().is_final or current_verbosity() >= Verbosity.debug ) try: if print_steps: machine.print_start() machine.check_invariants() while should_continue.more(): value = data.conjecture_data.draw(machine.steps()) if print_steps: machine.print_step(value) machine.execute_step(value) machine.check_invariants() finally: if print_steps: machine.print_end() machine.teardown()
def test_current_build_context_is_current(): with bc() as a: assert current_build_context() is a
def test_raises_if_current_build_context_out_of_context(): with pytest.raises(InvalidArgument): current_build_context()
def do_draw(self, data): return Chooser(current_build_context(), data)
def execute_step(self, step): assert current_build_context().is_final
def run_state_machine(factory, data): machine = factory() if not isinstance(machine, _GenericStateMachine): raise InvalidArgument( "Expected RuleBasedStateMachine but state_machine_factory() " "returned %r (type=%s)" % (machine, type(machine).__name__)) data.conjecture_data.hypothesis_runner = machine print_steps = (current_build_context().is_final or current_verbosity() >= Verbosity.debug) try: if print_steps: machine.print_start() machine.check_invariants() max_steps = settings.stateful_step_count steps_run = 0 cd = data.conjecture_data while True: # We basically always want to run the maximum number of steps, # but need to leave a small probability of terminating early # in order to allow for reducing the number of steps once we # find a failing test case, so we stop with probability of # 2 ** -16 during normal operation but force a stop when we've # generated enough steps. cd.start_example(STATE_MACHINE_RUN_LABEL) if steps_run == 0: cd.draw_bits(16, forced=1) elif steps_run >= max_steps: cd.draw_bits(16, forced=0) break else: # All we really care about is whether this value is zero # or non-zero, so if it's > 1 we discard it and insert a # replacement value after cd.start_example(SHOULD_CONTINUE_LABEL) should_continue_value = cd.draw_bits(16) if should_continue_value > 1: cd.stop_example(discard=True) cd.draw_bits(16, forced=int(bool(should_continue_value))) else: cd.stop_example() if should_continue_value == 0: break steps_run += 1 value = data.conjecture_data.draw(machine.steps()) # Assign 'result' here in case 'execute_step' fails below result = multiple() try: result = machine.execute_step(value) finally: if print_steps: # 'result' is only used if the step has target bundles. # If it does, and the result is a 'MultipleResult', # then 'print_step' prints a multi-variable assignment. machine.print_step(value, result) machine.check_invariants() data.conjecture_data.stop_example() finally: if print_steps: machine.print_end() machine.teardown()
def execute_step(self, step): cb = current_build_context() if not cb.is_final: assert 0 not in bytearray(step)
def steps(self): cb = current_build_context() if cb.is_final: return binary(min_size=1, max_size=1) else: return binary(min_size=1024, max_size=1024)
def action(self, d): if current_build_context().is_final: d.draw(binary(min_size=1, max_size=1)) else: buffer = binary(min_size=1024, max_size=1024) assert 0 not in buffer
def action(self): assert current_build_context().is_final
def run_state_machine(factory, data): cd = data.conjecture_data machine = factory() check_type(RuleBasedStateMachine, machine, "state_machine_factory()") cd.hypothesis_runner = machine print_steps = (current_build_context().is_final or current_verbosity() >= Verbosity.debug) try: if print_steps: report("state = %s()" % (machine.__class__.__name__, )) machine.check_invariants() max_steps = settings.stateful_step_count steps_run = 0 while True: # We basically always want to run the maximum number of steps, # but need to leave a small probability of terminating early # in order to allow for reducing the number of steps once we # find a failing test case, so we stop with probability of # 2 ** -16 during normal operation but force a stop when we've # generated enough steps. cd.start_example(STATE_MACHINE_RUN_LABEL) if steps_run == 0: cd.draw_bits(16, forced=1) elif steps_run >= max_steps: cd.draw_bits(16, forced=0) break else: # All we really care about is whether this value is zero # or non-zero, so if it's > 1 we discard it and insert a # replacement value after cd.start_example(SHOULD_CONTINUE_LABEL) should_continue_value = cd.draw_bits(16) if should_continue_value > 1: cd.stop_example(discard=True) cd.draw_bits(16, forced=int(bool(should_continue_value))) else: cd.stop_example() if should_continue_value == 0: break steps_run += 1 # Choose a rule to run, preferring an initialize rule if there are # any which have not been run yet. if machine._initialize_rules_to_run: init_rules = [ st.tuples(st.just(rule), st.fixed_dictionaries(rule.arguments)) for rule in machine._initialize_rules_to_run ] rule, data = cd.draw(st.one_of(init_rules)) machine._initialize_rules_to_run.remove(rule) else: rule, data = cd.draw(machine._rules_strategy) # Pretty-print the values this rule was called with *before* calling # _add_result_to_targets, to avoid printing arguments which are also # a return value using the variable name they are assigned to. # See https://github.com/HypothesisWorks/hypothesis/issues/2341 if print_steps: data_to_print = { k: machine._pretty_print(v) for k, v in data.items() } # Assign 'result' here in case executing the rule fails below result = multiple() try: data = dict(data) for k, v in list(data.items()): if isinstance(v, VarReference): data[k] = machine.names_to_values[v.name] result = rule.function(machine, **data) if rule.targets: if isinstance(result, MultipleResults): for single_result in result.values: machine._add_result_to_targets( rule.targets, single_result) else: machine._add_result_to_targets( rule.targets, result) finally: if print_steps: # 'result' is only used if the step has target bundles. # If it does, and the result is a 'MultipleResult', # then 'print_step' prints a multi-variable assignment. machine._print_step(rule, data_to_print, result) machine.check_invariants() cd.stop_example() finally: if print_steps: report("state.teardown()") machine.teardown()