1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
# This file is part of Hypothesis, which may be found at
# https://github.com/HypothesisWorks/hypothesis/
#
# Copyright the Hypothesis Authors.
# Individual contributors are listed in AUTHORS.rst and the git log.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.
import pytest
from hypothesis import assume, core, find, given, settings, strategies as st
from hypothesis.database import (
DirectoryBasedExampleDatabase,
GitHubArtifactDatabase,
InMemoryExampleDatabase,
ReadOnlyDatabase,
)
from hypothesis.errors import NoSuchExample, Unsatisfiable
from hypothesis.internal.entropy import deterministic_PRNG
from tests.common.utils import (
Why,
all_values,
non_covering_examples,
skipif_threading,
xfail_on_crosshair,
)
def has_a_non_zero_byte(x):
return any(bytes(x))
def test_saves_incremental_steps_in_database():
key = b"a database key"
database = InMemoryExampleDatabase()
find(
st.binary(min_size=10),
has_a_non_zero_byte,
settings=settings(database=database),
database_key=key,
)
assert len(all_values(database)) > 1
@xfail_on_crosshair(Why.symbolic_outside_context, strict=False)
def test_clears_out_database_as_things_get_boring():
key = b"a database key"
database = InMemoryExampleDatabase()
do_we_care = True
def stuff():
try:
find(
st.binary(min_size=50),
lambda x: do_we_care and has_a_non_zero_byte(x),
settings=settings(database=database, max_examples=10),
database_key=key,
)
except NoSuchExample:
pass
stuff()
assert len(non_covering_examples(database)) > 1
do_we_care = False
stuff()
initial = len(non_covering_examples(database))
assert initial > 0
for _ in range(initial):
stuff()
keys = len(non_covering_examples(database))
if not keys:
break
else:
raise AssertionError
@xfail_on_crosshair(Why.other, strict=False)
def test_trashes_invalid_examples():
key = b"a database key"
database = InMemoryExampleDatabase()
invalid = set()
def stuff():
try:
def condition(x):
assume(x not in invalid)
return not invalid and has_a_non_zero_byte(x)
return find(
st.binary(min_size=5),
condition,
settings=settings(database=database),
database_key=key,
)
except (Unsatisfiable, NoSuchExample):
pass
with deterministic_PRNG():
value = stuff()
original = len(all_values(database))
assert original > 1
invalid.add(value)
with deterministic_PRNG():
stuff()
assert len(all_values(database)) < original
@pytest.mark.skipif(
settings._current_profile == "crosshair",
reason="condition is easy for crosshair, stops early",
)
def test_respects_max_examples_in_database_usage():
key = b"a database key"
database = InMemoryExampleDatabase()
do_we_care = True
counter = 0
def check(x):
nonlocal counter
counter += 1
return do_we_care and has_a_non_zero_byte(x)
def stuff():
try:
find(
st.binary(min_size=100),
check,
settings=settings(database=database, max_examples=10),
database_key=key,
)
except NoSuchExample:
pass
with deterministic_PRNG():
stuff()
assert len(all_values(database)) > 10
do_we_care = False
counter = 0
with deterministic_PRNG():
stuff()
assert counter == 10
def test_does_not_use_database_when_seed_is_forced(monkeypatch):
monkeypatch.setattr(core, "global_force_seed", 42)
database = InMemoryExampleDatabase()
database.fetch = None # type: ignore
@settings(database=database)
@given(st.integers())
def test(i):
pass
test()
@skipif_threading # pytest .mktemp is not thread safe
@given(st.binary(), st.binary())
def test_database_not_created_when_not_used(tmp_path_factory, key, value):
path = tmp_path_factory.mktemp("hypothesis") / "examples"
assert not path.exists()
database = DirectoryBasedExampleDatabase(path)
assert not list(database.fetch(key))
assert not path.exists()
database.save(key, value)
assert path.exists()
assert list(database.fetch(key)) == [value]
@skipif_threading
def test_ga_database_not_created_when_not_used(tmp_path_factory):
path = tmp_path_factory.mktemp("hypothesis") / "github-actions"
assert not path.exists()
ReadOnlyDatabase(GitHubArtifactDatabase("mock", "mock", path=path))
assert not path.exists()
|