Example #1
0
    def accept(f):
        if getattr(f, RULE_MARKER, None) or getattr(f, INITIALIZE_RULE_MARKER,
                                                    None):
            raise InvalidDefinition(
                "A function cannot be used for both a rule and an invariant.",
                Settings.default,
            )
        existing_invariant = getattr(f, INVARIANT_MARKER, None)
        if existing_invariant is not None:
            raise InvalidDefinition(
                "A function cannot be used for two distinct invariants.",
                Settings.default,
            )
        preconditions = getattr(f, PRECONDITIONS_MARKER, ())
        invar = Invariant(
            function=f,
            preconditions=preconditions,
            check_during_init=check_during_init,
        )

        @proxies(f)
        def invariant_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        setattr(invariant_wrapper, INVARIANT_MARKER, invar)
        return invariant_wrapper
Example #2
0
    def accept(f):
        if getattr(f, INVARIANT_MARKER, None):
            raise InvalidDefinition(
                "A function cannot be used for both a rule and an invariant.",
                Settings.default,
            )
        existing_rule = getattr(f, RULE_MARKER, None)
        existing_initialize_rule = getattr(f, INITIALIZE_RULE_MARKER, None)
        if existing_rule is not None or existing_initialize_rule is not None:
            raise InvalidDefinition(
                "A function cannot be used for two distinct rules. ",
                Settings.default)
        preconditions = getattr(f, PRECONDITIONS_MARKER, ())
        rule = Rule(
            targets=converted_targets,
            arguments=kwargs,
            function=f,
            preconditions=preconditions,
        )

        @proxies(f)
        def rule_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        setattr(rule_wrapper, RULE_MARKER, rule)
        return rule_wrapper
Example #3
0
    def accept(f):
        existing_rule = getattr(f, RULE_MARKER, None)
        existing_initialize_rule = getattr(f, INITIALIZE_RULE_MARKER, None)
        if existing_rule is not None or existing_initialize_rule is not None:
            raise InvalidDefinition(
                "A function cannot be used for two distinct rules. ",
                Settings.default)
        precondition = getattr(f, PRECONDITION_MARKER, None)
        if precondition:
            raise InvalidDefinition(
                "An initialization rule cannot have a precondition. ",
                Settings.default)
        rule = Rule(
            targets=converted_targets,
            arguments=kwargs,
            function=f,
            precondition=precondition,
        )

        @proxies(f)
        def rule_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        setattr(rule_wrapper, INITIALIZE_RULE_MARKER, rule)
        return rule_wrapper
Example #4
0
    def steps(self):
        # Pick initialize rules first
        if self._initialize_rules_to_run:
            return one_of([
                tuples(just(rule), fixed_dictionaries(rule.arguments))
                for rule in self._initialize_rules_to_run
            ])

        # All initialize rules has been run once, go with the regular rules
        strategies = []
        for rule in self.rules():
            converted_arguments = {}
            valid = True
            if rule.precondition and not rule.precondition(self):
                continue
            for k, v in sorted(rule.arguments.items()):
                if isinstance(v, Bundle):
                    bundle = self.bundle(v.name)
                    if not bundle:
                        valid = False
                        break
                    v = BundleReferenceStrategy(v.name)
                converted_arguments[k] = v
            if valid:
                strategies.append(
                    tuples(just(rule),
                           fixed_dictionaries(converted_arguments)))
        if not strategies:
            raise InvalidDefinition(u'No progress can be made from state %r' %
                                    (self, ))

        return one_of(strategies)
Example #5
0
    def decorator(f):
        @proxies(f)
        def precondition_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        existing_initialize_rule = getattr(f, INITIALIZE_RULE_MARKER, None)
        if existing_initialize_rule is not None:
            raise InvalidDefinition(
                "An initialization rule cannot have a precondition. ",
                Settings.default)

        rule = getattr(f, RULE_MARKER, None)
        invariant = getattr(f, INVARIANT_MARKER, None)
        if rule is not None:
            assert invariant is None
            new_rule = attr.evolve(rule,
                                   preconditions=rule.preconditions +
                                   (precond, ))
            setattr(precondition_wrapper, RULE_MARKER, new_rule)
        elif invariant is not None:
            assert rule is None
            new_invariant = attr.evolve(invariant,
                                        preconditions=invariant.preconditions +
                                        (precond, ))
            setattr(precondition_wrapper, INVARIANT_MARKER, new_invariant)
        else:
            setattr(
                precondition_wrapper,
                PRECONDITIONS_MARKER,
                getattr(f, PRECONDITIONS_MARKER, ()) + (precond, ),
            )

        return precondition_wrapper
    def steps(self):
        strategies = []
        for rule in self.rules():
            converted_arguments = {}
            valid = True
            if rule.precondition and not rule.precondition(self):
                continue
            for k, v in sorted(rule.arguments.items()):
                if isinstance(v, Bundle):
                    bundle = self.bundle(v.name)
                    if not bundle:
                        valid = False
                        break
                converted_arguments[k] = v
            if valid:
                strategies.append(TupleStrategy((
                    just(rule),
                    FixedKeysDictStrategy(converted_arguments)
                ), tuple))
        if not strategies:
            raise InvalidDefinition(
                u'No progress can be made from state %r' % (self,)
            )

        for name, bundle in self.bundles.items():
            if len(bundle) > 1:
                strategies.append(
                    builds(
                        ShuffleBundle, just(name),
                        lists(integers(0, len(bundle) - 1))))

        return one_of(strategies)
Example #7
0
    def decorator(f):
        @proxies(f)
        def precondition_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        existing_initialize_rule = getattr(f, INITIALIZE_RULE_MARKER, None)
        if existing_initialize_rule is not None:
            raise InvalidDefinition(
                "An initialization rule cannot have a precondition. ",
                Settings.default)

        rule = getattr(f, RULE_MARKER, None)
        if rule is None:
            setattr(precondition_wrapper, PRECONDITION_MARKER, precond)
        else:
            new_rule = Rule(
                targets=rule.targets,
                arguments=rule.arguments,
                function=rule.function,
                precondition=precond,
            )
            setattr(precondition_wrapper, RULE_MARKER, new_rule)

        invariant = getattr(f, INVARIANT_MARKER, None)
        if invariant is not None:
            new_invariant = Invariant(function=invariant.function,
                                      precondition=precond)
            setattr(precondition_wrapper, INVARIANT_MARKER, new_invariant)

        return precondition_wrapper
Example #8
0
 def steps(self):
     strategies = []
     for rule in self.rules():
         converted_arguments = {}
         valid = True
         if rule.precondition is not None and not rule.precondition(self):
             continue
         for k, v in sorted(rule.arguments.items()):
             if isinstance(v, Bundle):
                 bundle = self.bundle(v.name)
                 if not bundle:
                     valid = False
                     break
                 else:
                     v = sampled_from(bundle)
             converted_arguments[k] = v
         if valid:
             strategies.append(
                 TupleStrategy((just(rule),
                                FixedKeysDictStrategy(converted_arguments)),
                               tuple))
     if not strategies:
         raise InvalidDefinition(u'No progress can be made from state %r' %
                                 (self, ))
     return one_of(*strategies)
Example #9
0
 def __init__(self):
     if not self.rules():
         raise InvalidDefinition(u'Type %s defines no rules' %
                                 (type(self).__name__, ))
     self.bundles = {}
     self.name_counter = 1
     self.names_to_values = {}
Example #10
0
 def do_draw(self, data):
     try:
         rule = data.draw(st.sampled_from(self.rules).filter(self.is_valid))
     except HypothesisException:
         # FailedHealthCheck or UnsatisfiedAssumption depending on user settings.
         msg = u"No progress can be made from state %r" % (self.machine, )
         quiet_raise(InvalidDefinition(msg))
     return (rule, data.draw(rule.arguments_strategy))
Example #11
0
 def __init__(self):
     if not self.rules():
         raise InvalidDefinition(u'Type %s defines no rules' %
                                 (type(self).__name__, ))
     self.bundles = {}  # type: Dict[Text, list]
     self.name_counter = 1
     self.names_to_values = {}  # type: Dict[Text, Any]
     self.__stream = CUnicodeIO()
     self.__printer = RepresentationPrinter(self.__stream)
Example #12
0
 def __init__(self):
     if not self.rules():
         raise InvalidDefinition("Type %s defines no rules" % (type(self).__name__,))
     self.bundles = {}  # type: Dict[str, list]
     self.name_counter = 1
     self.names_to_values = {}  # type: Dict[str, Any]
     self.__stream = StringIO()
     self.__printer = RepresentationPrinter(self.__stream)
     self._initialize_rules_to_run = copy(self.initialize_rules())
     self._rules_strategy = RuleStrategy(self)
Example #13
0
    def accept(f):
        existing_invariant = getattr(f, INVARIANT_MARKER, None)
        if existing_invariant is not None:
            raise InvalidDefinition(
                "A function cannot be used for two distinct invariants.",
                Settings.default,
            )
        precondition = getattr(f, PRECONDITION_MARKER, None)
        rule = Invariant(function=f, precondition=precondition)

        @proxies(f)
        def invariant_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        setattr(invariant_wrapper, INVARIANT_MARKER, rule)
        return invariant_wrapper
Example #14
0
    def accept(f):
        existing_rule = getattr(f, RULE_MARKER, None)
        if existing_rule is not None:
            raise InvalidDefinition(
                'A function cannot be used for two distinct rules. ',
                Settings.default,
            )
        precondition = getattr(f, PRECONDITION_MARKER, None)
        rule = Rule(targets=tuple(converted_targets), arguments=kwargs,
                    function=f, precondition=precondition)

        @proxies(f)
        def rule_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        setattr(rule_wrapper, RULE_MARKER, rule)
        return rule_wrapper
Example #15
0
    def do_draw(self, data):
        if not any(self.is_valid(rule) for rule in self.rules):
            msg = "No progress can be made from state %r" % (self.machine, )
            raise InvalidDefinition(msg) from None

        feature_flags = data.draw(self.enabled_rules_strategy)

        # Note: The order of the filters here is actually quite important,
        # because checking is_enabled makes choices, so increases the size of
        # the choice sequence. This means that if we are in a case where many
        # rules are invalid we will make a lot more choices if we ask if they
        # are enabled before we ask if they are valid, so our test cases will
        # be artificially large.
        rule = data.draw(
            st.sampled_from(self.rules).filter(self.is_valid).filter(
                lambda r: feature_flags.is_enabled(r.function.__name__)))

        return (rule, data.draw(rule.arguments_strategy))
Example #16
0
 def do_draw(self, data):
     # This strategy is slightly strange in its implementation.
     # We don't want the interpretation of the rule we draw to change based
     # on whether other rules satisfy their preconditions or have data in
     # their bundles. Therefore the index into the rule list needs to stay
     # stable. BUT we don't want to draw invalid rules. So what we do is we
     # draw an index. We *could* just loop until it's valid, but if most
     # rules are invalid then that could result in a very long loop.
     # So what we do is the following:
     #
     #   1. We first draw a rule unconditionally, and check if it's valid.
     #      If it is, great. Nothing more to do, that's our rule.
     #   2. If it is invalid, we now calculate the list of valid rules and
     #      draw from that list (if there are none, that's an error in the
     #      definition of the machine and we complain to the user about it).
     #   3. Once we've drawn a valid rule, we write that back to the byte
     #      stream. As a result, when shrinking runs the shrinker can delete
     #      the initial failed draw + the draw that lead to us finding an
     #      index into valid_rules, leaving just the written value of i.
     #      When this is run, it will look as we got lucky and just happened
     #      to pick a valid rule.
     #
     # Easy, right?
     n = len(self.rules)
     i = cu.integer_range(data, 0, n - 1)
     u, v = data.blocks[-1]
     block_length = v - u
     rule = self.rules[i]
     if not self.is_valid(rule):
         valid_rules = [
             j for j, r in enumerate(self.rules) if self.is_valid(r)
         ]
         if not valid_rules:
             raise InvalidDefinition(
                 u'No progress can be made from state %r' %
                 (self.machine, ))
         i = valid_rules[cu.integer_range(data, 0, len(valid_rules) - 1)]
         data.write(int_to_bytes(i, block_length))
         rule = self.rules[i]
     return (rule, data.draw(rule.arguments_strategy))
Example #17
0
 def steps(self):
     strategies = []
     for rule in self.rules():
         converted_arguments = {}
         valid = True
         for k, v in rule.arguments.items():
             if isinstance(v, Bundle):
                 bundle = self.bundle(v.name)
                 if not bundle:
                     valid = False
                     break
                 else:
                     v = SimpleSampledFromStrategy(bundle)
             converted_arguments[k] = v
         if valid:
             strategies.append(
                 TupleStrategy((JustStrategy(rule),
                                FixedKeysDictStrategy(converted_arguments)),
                               tuple))
     if not strategies:
         raise InvalidDefinition('No progress can be made from state %r' %
                                 (self, ))
     return one_of_strategies(strategies)
Example #18
0
 def do_draw(self, data):
     if not any(self.is_valid(rule) for rule in self.rules):
         msg = u"No progress can be made from state %r" % (self.machine,)
         quiet_raise(InvalidDefinition(msg))
     rule = data.draw(st.sampled_from(self.rules).filter(self.is_valid))
     return (rule, data.draw(rule.arguments_strategy))