Changeset View
Changeset View
Standalone View
Standalone View
swh/web/tests/strategies.py
# Copyright (C) 2018 The Software Heritage developers | # Copyright (C) 2018 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU Affero General Public License version 3, or any later version | # License: GNU Affero General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import random | import random | ||||
from collections import defaultdict | from collections import defaultdict | ||||
from datetime import datetime | from datetime import datetime | ||||
from hypothesis import settings | from hypothesis import settings | ||||
from hypothesis.strategies import ( | from hypothesis.strategies import ( | ||||
just, sampled_from, lists, composite, datetimes | just, sampled_from, lists, composite, datetimes | ||||
) | ) | ||||
from string import ascii_letters, hexdigits | from string import ascii_letters, hexdigits | ||||
from swh.model.hashutil import hash_to_hex | from swh.model.hashutil import hash_to_hex, hash_to_bytes | ||||
from swh.model.identifiers import directory_identifier | |||||
from swh.storage.algos.revisions_walker import get_revisions_walker | from swh.storage.algos.revisions_walker import get_revisions_walker | ||||
from swh.storage.tests.algos.test_snapshot import origins | from swh.storage.tests.algos.test_snapshot import origins as new_origin # noqa | ||||
from swh.web.tests.data import get_tests_data | from swh.web.tests.data import get_tests_data | ||||
# Module dedicated to the generation of input data for tests through | # Module dedicated to the generation of input data for tests through | ||||
# the use of hypothesis. | # the use of hypothesis. | ||||
# Some of these data are sampled from a test archive created and populated | # Some of these data are sampled from a test archive created and populated | ||||
# in the swh.web.tests.data module. | # in the swh.web.tests.data module. | ||||
# Set some hypothesis settings | # Set some hypothesis settings | ||||
settings.register_profile("swh-web", settings(deadline=None, max_examples=1)) | settings.register_profile("swh-web", settings(deadline=None, max_examples=1)) | ||||
settings.load_profile("swh-web") | settings.load_profile("swh-web") | ||||
# The following strategies exploit the hypothesis capabilities | # The following strategies exploit the hypothesis capabilities | ||||
def _known_swh_object(object_type): | def _known_swh_object(object_type): | ||||
tests_data = get_tests_data() | tests_data = get_tests_data() | ||||
return sampled_from(tests_data[object_type]) | return sampled_from(tests_data[object_type]) | ||||
def _unknown_swh_object(draw, object_type): | def _unknown_swh_object(draw, object_type): | ||||
tests_data = get_tests_data() | tests_data = get_tests_data() | ||||
storage = tests_data['storage'] | |||||
while True: | while True: | ||||
sha1_git = draw(sha1()) | sha1_git = draw(sha1()) | ||||
if sha1_git not in tests_data[object_type]: | # some tests will use the generated id to create a revision on the fly | ||||
if object_type == 'revisions': | |||||
obj = next(storage.revision_get([hash_to_bytes(sha1_git)])) | |||||
if obj is None: | |||||
return sha1_git | |||||
elif sha1_git not in tests_data[object_type]: | |||||
return sha1_git | return sha1_git | ||||
def sha1(): | def sha1(): | ||||
""" | """ | ||||
Hypothesis strategy returning a valid hexadecimal sha1 value. | Hypothesis strategy returning a valid hexadecimal sha1 value. | ||||
""" | """ | ||||
sha1 = ''.join(random.choice(hexdigits) for x in range(40)) | sha1 = ''.join(random.choice(hexdigits) for x in range(40)) | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
def directory(): | def directory(): | ||||
""" | """ | ||||
Hypothesis strategy returning a random directory ingested | Hypothesis strategy returning a random directory ingested | ||||
into the test archive. | into the test archive. | ||||
""" | """ | ||||
return _known_swh_object('directories') | return _known_swh_object('directories') | ||||
def empty_directory(): | |||||
""" | |||||
Hypothesis strategy returning the empty directory ingested | |||||
into the test archive. | |||||
""" | |||||
return just(directory_identifier({'entries': []})) | |||||
@composite | @composite | ||||
def unknown_directory(draw): | def unknown_directory(draw): | ||||
""" | """ | ||||
Hypothesis strategy returning a random directory not ingested | Hypothesis strategy returning a random directory not ingested | ||||
into the test archive. | into the test archive. | ||||
""" | """ | ||||
return _unknown_swh_object(draw, 'directories') | return _unknown_swh_object(draw, 'directories') | ||||
def origin(): | def origin(): | ||||
""" | """ | ||||
Hypothesis strategy returning a random origin not ingested | Hypothesis strategy returning a random origin not ingested | ||||
into the test archive. | into the test archive. | ||||
""" | """ | ||||
return origins() | return _known_swh_object('origins') | ||||
def visit_dates(): | def visit_dates(): | ||||
""" | """ | ||||
Hypothesis strategy returning a list of visit dates. | Hypothesis strategy returning a list of visit dates. | ||||
""" | """ | ||||
return lists(datetimes(min_value=datetime(2015, 1, 1, 0, 0), | return lists(datetimes(min_value=datetime(2015, 1, 1, 0, 0), | ||||
max_value=datetime(2018, 12, 31, 0, 0)), | max_value=datetime(2018, 12, 31, 0, 0)), | ||||
Show All 29 Lines | |||||
def unknown_revision(draw): | def unknown_revision(draw): | ||||
""" | """ | ||||
Hypothesis strategy returning a random revision not ingested | Hypothesis strategy returning a random revision not ingested | ||||
into the test archive. | into the test archive. | ||||
""" | """ | ||||
return _unknown_swh_object(draw, 'revisions') | return _unknown_swh_object(draw, 'revisions') | ||||
def revisions(): | |||||
""" | |||||
Hypothesis strategy returning random revisions ingested | |||||
into the test archive. | |||||
""" | |||||
return lists(revision(), min_size=2, max_size=8) | |||||
def unknown_revisions(): | |||||
""" | |||||
Hypothesis strategy returning random revisions not ingested | |||||
into the test archive. | |||||
""" | |||||
return lists(unknown_revision(), min_size=2, max_size=8) | |||||
def snapshot(): | def snapshot(): | ||||
""" | """ | ||||
Hypothesis strategy returning a random snapshot ingested | Hypothesis strategy returning a random snapshot ingested | ||||
into the test archive. | into the test archive. | ||||
""" | """ | ||||
return _known_swh_object('snapshots') | return _known_swh_object('snapshots') | ||||
@composite | @composite | ||||
def unknown_snapshot(draw): | def unknown_snapshot(draw): | ||||
""" | """ | ||||
Hypothesis strategy returning a random revision not ingested | Hypothesis strategy returning a random revision not ingested | ||||
into the test archive. | into the test archive. | ||||
""" | """ | ||||
return _unknown_swh_object(draw, 'snapshots') | return _unknown_swh_object(draw, 'snapshots') | ||||
def _get_origin_dfs_revisions_walker(): | def _get_origin_dfs_revisions_walker(): | ||||
storage = get_tests_data()['storage'] | storage = get_tests_data()['storage'] | ||||
origin = random.choice(get_tests_data()['origins']) | origin = random.choice(get_tests_data()['origins'][:-1]) | ||||
snapshot = storage.snapshot_get_latest(origin['id']) | snapshot = storage.snapshot_get_latest(origin['id']) | ||||
head = snapshot['branches'][b'HEAD']['target'] | head = snapshot['branches'][b'HEAD']['target'] | ||||
return get_revisions_walker('dfs', storage, head) | return get_revisions_walker('dfs', storage, head) | ||||
def ancestor_revisions(): | def ancestor_revisions(): | ||||
""" | """ | ||||
Hypothesis strategy returning a pair of revisions ingested into the | Hypothesis strategy returning a pair of revisions ingested into the | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | return just({ | ||||
'9b3557f1ab4111c8607a4f2ea3c1e53c6992916c', | '9b3557f1ab4111c8607a4f2ea3c1e53c6992916c', | ||||
'9c20da07ed14dc4fcd3ca2b055af99b2598d8bdd', | '9c20da07ed14dc4fcd3ca2b055af99b2598d8bdd', | ||||
'c20ceebd6ec6f7a19b5c3aebc512a12fbdc9234b', | 'c20ceebd6ec6f7a19b5c3aebc512a12fbdc9234b', | ||||
'e89e55a12def4cd54d5bff58378a3b5119878eb7', | 'e89e55a12def4cd54d5bff58378a3b5119878eb7', | ||||
'e8c0654fe2d75ecd7e0b01bee8a8fc60a130097e', | 'e8c0654fe2d75ecd7e0b01bee8a8fc60a130097e', | ||||
'eb6595e559a1d34a2b41e8d4835e0e4f98a5d2b5'], | 'eb6595e559a1d34a2b41e8d4835e0e4f98a5d2b5'], | ||||
'symbol_name': 'ABS' | 'symbol_name': 'ABS' | ||||
}) | }) | ||||
def revision_with_submodules(): | |||||
""" | |||||
Hypothesis strategy returning a revision that is known to | |||||
point to a directory with revision entries (aka git submodule) | |||||
""" | |||||
return just({ | |||||
'rev_sha1_git': 'ffcb69001f3f6745dfd5b48f72ab6addb560e234', | |||||
'rev_dir_sha1_git': 'd92a21446387fa28410e5a74379c934298f39ae2', | |||||
'rev_dir_rev_path': 'libtess2' | |||||
}) |