Esempio n. 1
0
def simplify_template_such_that(
    search_strategy, random, t, f, tracker, settings, start_time
):
    """Perform a greedy search to produce a "simplest" version of a template
    that satisfies some predicate.

    Care is taken to avoid cycles in simplify.

    f should produce the same result deterministically. This function may
    raise an error given f such that f(t) returns False sometimes and True
    some other times.

    If f throws UnsatisfiedAssumption this will be treated the same as if
    it returned False.

    """
    assert isinstance(random, Random)

    yield t
    successful_shrinks = 0

    changed = True
    while changed and successful_shrinks < settings.max_shrinks:
        changed = False
        for simplify in search_strategy.simplifiers(random, t):
            debug_report('Applying simplification pass %s' % (
                simplify.__name__,
            ))
            while True:
                simpler = simplify(random, t)
                for s in simpler:
                    if tracker.track(s) > 1:
                        continue
                    try:
                        if f(s):
                            successful_shrinks += 1
                            changed = True
                            yield s
                            t = s
                            break
                    except UnsatisfiedAssumption:
                        pass
                    if time_to_call_it_a_day(settings, start_time):
                        return
                else:
                    break

            if successful_shrinks >= settings.max_shrinks:
                break
Esempio n. 2
0
def find_satisfying_template(
    search_strategy, random, condition, tracker, settings, storage=None,
    max_parameter_tries=None,
):
    """Attempt to find a template for search_strategy such that condition is
    truthy.

    Exceptions other than UnsatisfiedAssumption will be immediately propagated.
    UnsatisfiedAssumption will indicate that similar examples should be avoided
    in future.

    Returns such a template as soon as it is found, otherwise stops after
    settings.max_examples examples have been considered or settings.timeout
    seconds have passed (if settings.timeout > 0).

    May raise a variety of exceptions depending on exact circumstances, but
    these will all subclass either Unsatisfiable (to indicate not enough
    examples were found which did not raise UnsatisfiedAssumption to consider
    this a valid test) or NoSuchExample (to indicate that this probably means
    that condition is true with very high probability).

    """
    satisfying_examples = 0
    examples_considered = 0
    timed_out = False
    max_iterations = max(settings.max_iterations, settings.max_examples)
    max_examples = min(max_iterations, settings.max_examples)
    min_satisfying_examples = min(
        settings.min_satisfying_examples,
        max_examples,
    )
    start_time = time.time()

    if storage:
        for example in storage.fetch(search_strategy):
            if examples_considered >= max_iterations:
                break
            examples_considered += 1
            if time_to_call_it_a_day(settings, start_time):
                break
            tracker.track(example)
            try:
                if condition(example):
                    return example
                satisfying_examples += 1
            except UnsatisfiedAssumption:
                pass
            if satisfying_examples >= max_examples:
                break

    parameter_source = ParameterSource(
        random=random, strategy=search_strategy,
        max_tries=max_parameter_tries,
    )

    assert search_strategy.template_upper_bound >= 0
    if isinstance(search_strategy.template_upper_bound, float):
        assert math.isinf(search_strategy.template_upper_bound)
    else:
        assert isinstance(search_strategy.template_upper_bound, int)

    for parameter in parameter_source:  # pragma: no branch
        if len(tracker) >= search_strategy.template_upper_bound:
            break
        if examples_considered >= max_iterations:
            break
        if satisfying_examples >= max_examples:
            break
        if time_to_call_it_a_day(settings, start_time):
            break
        examples_considered += 1

        try:
            example = search_strategy.draw_template(
                random, parameter
            )
        except BadTemplateDraw:
            debug_report(u'Failed attempt to draw a template')
            parameter_source.mark_bad()
            continue
        if tracker.track(example) > 1:
            debug_report(u'Skipping duplicate example')
            parameter_source.mark_bad()
            continue
        try:
            if condition(example):
                return example
        except UnsatisfiedAssumption:
            parameter_source.mark_bad()
            continue
        satisfying_examples += 1
    run_time = time.time() - start_time
    timed_out = settings.timeout >= 0 and run_time >= settings.timeout
    if (
        satisfying_examples and
        len(tracker) >= search_strategy.template_upper_bound
    ):
        raise DefinitelyNoSuchExample(
            get_pretty_function_description(condition),
            satisfying_examples,
        )
    elif satisfying_examples < min_satisfying_examples:
        if timed_out:
            raise Timeout((
                u'Ran out of time before finding a satisfying example for '
                u'%s. Only found %d examples (%d satisfying assumptions) in ' +
                u'%.2fs.'
            ) % (
                get_pretty_function_description(condition),
                len(tracker), satisfying_examples, run_time
            ))
        else:
            raise Unsatisfiable((
                u'Unable to satisfy assumptions of hypothesis %s. ' +
                u'Only %d out of %d examples considered satisfied assumptions'
            ) % (
                get_pretty_function_description(condition),
                satisfying_examples, len(tracker)))
    else:
        raise NoSuchExample(get_pretty_function_description(condition))
Esempio n. 3
0
def simplify_template_such_that(
    search_strategy, random, t, f, tracker, settings, start_time
):
    """Perform a greedy search to produce a "simplest" version of a template
    that satisfies some predicate.

    Care is taken to avoid cycles in simplify.

    f should produce the same result deterministically. This function may
    raise an error given f such that f(t) returns False sometimes and True
    some other times.

    If f throws UnsatisfiedAssumption this will be treated the same as if
    it returned False.

    """
    assert isinstance(random, Random)

    yield t
    successful_shrinks = 0

    changed = True
    max_warmup = 5
    warmup = 0
    while (
        (changed or warmup < max_warmup) and
        successful_shrinks < settings.max_shrinks
    ):
        changed = False
        warmup += 1
        if warmup < max_warmup:
            debug_report(u'Running warmup simplification round %d' % (
                warmup
            ))
        elif warmup == max_warmup:
            debug_report(u'Warmup is done. Moving on to fully simplifying')

        any_simplifiers = False
        for simplify in search_strategy.simplifiers(random, t):
            debug_report(u'Applying simplification pass %s' % (
                simplify.__name__,
            ))
            any_simplifiers = True
            any_shrinks = False
            while True:
                simpler = simplify(random, t)
                if warmup < max_warmup:
                    simpler = islice(simpler, warmup)
                for s in simpler:
                    any_shrinks = True
                    if time_to_call_it_a_day(settings, start_time):
                        return
                    if tracker.track(s) > 1:
                        debug_report(
                            u'Skipping simplifying to duplicate %s' % (
                                unicode_safe_repr(s),
                            ))
                        continue
                    try:
                        if f(s):
                            successful_shrinks += 1
                            changed = True
                            yield s
                            t = s
                            break
                        else:
                            yield t
                    except UnsatisfiedAssumption:
                        pass
                else:
                    break
            if not any_shrinks:
                debug_report(u'No shrinks possible')
            if successful_shrinks >= settings.max_shrinks:
                break
        if not any_simplifiers:
            debug_report(u'No simplifiers for template %s' % (
                unicode_safe_repr(t),
            ))
            break
def test_does_print_debug_in_debug():
    with settings(verbosity=Verbosity.debug):
        with capture_out() as o:
            debug_report(u'Hi')
    assert u'Hi' in o.getvalue()
def test_does_not_print_debug_in_verbose():
    with settings(verbosity=Verbosity.verbose):
        with capture_out() as o:
            debug_report(u'Hi')
    assert not o.getvalue()
Esempio n. 6
0
 def debug(self, message):
     with self.settings:
         debug_report(message)
 def f(x):
     debug_report('Hi')
Esempio n. 8
0
 def f(x):
     debug_report('Hi')
Esempio n. 9
0
 def debug(self, message):
     with local_settings(self.settings):
         debug_report(message)
Esempio n. 10
0
def test_does_print_debug_in_debug():
    with settings(verbosity=Verbosity.debug):
        with capture_out() as o:
            debug_report(u'Hi')
    assert u'Hi' in o.getvalue()
Esempio n. 11
0
def test_does_not_print_debug_in_verbose():
    with settings(verbosity=Verbosity.verbose):
        with capture_out() as o:
            debug_report(u'Hi')
    assert not o.getvalue()
Esempio n. 12
0
 def f(x):
     debug_report("Hi")
 def f(x):
     debug_report("Hi")
Esempio n. 14
0
 def debug(self, message):
     with self.settings:
         debug_report(message)
Esempio n. 15
0
def find_satisfying_template(
    search_strategy,
    random,
    condition,
    tracker,
    settings,
    storage=None,
    max_parameter_tries=None,
):
    """Attempt to find a template for search_strategy such that condition is
    truthy.

    Exceptions other than UnsatisfiedAssumption will be immediately propagated.
    UnsatisfiedAssumption will indicate that similar examples should be avoided
    in future.

    Returns such a template as soon as it is found, otherwise stops after
    settings.max_examples examples have been considered or settings.timeout
    seconds have passed (if settings.timeout > 0).

    May raise a variety of exceptions depending on exact circumstances, but
    these will all subclass either Unsatisfiable (to indicate not enough
    examples were found which did not raise UnsatisfiedAssumption to consider
    this a valid test) or NoSuchExample (to indicate that this probably means
    that condition is true with very high probability).

    """
    satisfying_examples = 0
    examples_considered = 0
    timed_out = False
    max_iterations = max(settings.max_iterations, settings.max_examples)
    max_examples = min(max_iterations, settings.max_examples)
    min_satisfying_examples = min(
        settings.min_satisfying_examples,
        max_examples,
    )
    start_time = time.time()

    if storage:
        for example in storage.fetch(search_strategy):
            if examples_considered >= max_iterations:
                break
            examples_considered += 1
            if time_to_call_it_a_day(settings, start_time):
                break
            tracker.track(example)
            try:
                if condition(example):
                    return example
                satisfying_examples += 1
            except UnsatisfiedAssumption:
                pass
            if satisfying_examples >= max_examples:
                break

    parameter_source = ParameterSource(
        random=random,
        strategy=search_strategy,
        max_tries=max_parameter_tries,
    )

    assert search_strategy.template_upper_bound >= 0
    if isinstance(search_strategy.template_upper_bound, float):
        assert math.isinf(search_strategy.template_upper_bound)
    else:
        assert isinstance(search_strategy.template_upper_bound, int)

    for parameter in parameter_source:  # pragma: no branch
        if len(tracker) >= search_strategy.template_upper_bound:
            break
        if examples_considered >= max_iterations:
            break
        if satisfying_examples >= max_examples:
            break
        if time_to_call_it_a_day(settings, start_time):
            break
        examples_considered += 1

        try:
            example = search_strategy.draw_template(random, parameter)
        except BadTemplateDraw:
            debug_report('Failed attempt to draw a template')
            parameter_source.mark_bad()
            continue
        if tracker.track(example) > 1:
            debug_report('Skipping duplicate example')
            parameter_source.mark_bad()
            continue
        try:
            if condition(example):
                return example
        except UnsatisfiedAssumption:
            parameter_source.mark_bad()
            continue
        satisfying_examples += 1
    run_time = time.time() - start_time
    timed_out = settings.timeout >= 0 and run_time >= settings.timeout
    if (satisfying_examples
            and len(tracker) >= search_strategy.template_upper_bound):
        raise DefinitelyNoSuchExample(
            get_pretty_function_description(condition),
            satisfying_examples,
        )
    elif satisfying_examples < min_satisfying_examples:
        if timed_out:
            raise Timeout(
                ('Ran out of time before finding a satisfying example for '
                 '%s. Only found %d examples (%d satisfying assumptions) in ' +
                 '%.2fs.') % (get_pretty_function_description(condition),
                              len(tracker), satisfying_examples, run_time))
        else:
            raise Unsatisfiable(
                ('Unable to satisfy assumptions of hypothesis %s. ' +
                 'Only %d out of %d examples considered satisfied assumptions')
                % (get_pretty_function_description(condition),
                   satisfying_examples, len(tracker)))
    else:
        raise NoSuchExample(get_pretty_function_description(condition))
Esempio n. 16
0
def simplify_template_such_that(search_strategy, random, t, f, tracker,
                                settings, start_time):
    """Perform a greedy search to produce a "simplest" version of a template
    that satisfies some predicate.

    Care is taken to avoid cycles in simplify.

    f should produce the same result deterministically. This function may
    raise an error given f such that f(t) returns False sometimes and True
    some other times.

    If f throws UnsatisfiedAssumption this will be treated the same as if
    it returned False.

    """
    yield t

    try:
        if settings.max_shrinks <= 0 or not f(t):
            return
    except UnsatisfiedAssumption:
        return

    successful_shrinks = 0

    changed = True
    max_warmup = 5
    warmup = 0
    while ((changed or warmup < max_warmup)
           and successful_shrinks < settings.max_shrinks):
        changed = False
        warmup += 1
        if warmup < max_warmup:
            debug_report('Running warmup simplification round %d' % (warmup))
        elif warmup == max_warmup:
            debug_report('Warmup is done. Moving on to fully simplifying')

        any_simplifiers = False
        for simplify in search_strategy.simplifiers(random, t):
            debug_report('Applying simplification pass %s' %
                         (simplify.__name__, ))
            any_simplifiers = True
            any_shrinks = False
            while successful_shrinks < settings.max_shrinks:
                simpler = simplify(random, t)
                if warmup < max_warmup:
                    simpler = islice(simpler, warmup)
                for s in simpler:
                    any_shrinks = True
                    if time_to_call_it_a_day(settings, start_time):
                        return
                    if tracker.track(s) > 1:
                        debug_report('Skipping simplifying to duplicate %s' %
                                     (repr(s), ))
                        continue
                    try:
                        if f(s):
                            successful_shrinks += 1
                            changed = True
                            yield s
                            t = s
                            break
                        else:
                            yield t
                    except UnsatisfiedAssumption:
                        pass
                else:
                    break
            if not any_shrinks:
                debug_report('No shrinks possible')
        if not any_simplifiers:
            debug_report('No simplifiers for template %s' % (repr(t), ))
            break