Changeset View
Changeset View
Standalone View
Standalone View
swh/web/tests/conftest.py
# Copyright (C) 2018-2021 The Software Heritage developers | # Copyright (C) 2018-2021 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 | ||||
from collections import defaultdict | from collections import defaultdict | ||||
from datetime import timedelta | from datetime import timedelta | ||||
import functools | import functools | ||||
import json | import json | ||||
import os | import os | ||||
import random | import random | ||||
import shutil | import shutil | ||||
from subprocess import PIPE, run | from subprocess import PIPE, run | ||||
import sys | import sys | ||||
import time | |||||
from typing import Any, Dict, List, Optional | from typing import Any, Dict, List, Optional | ||||
from _pytest.python import Function | from _pytest.python import Function | ||||
from hypothesis import HealthCheck, settings | from hypothesis import HealthCheck, settings | ||||
import pytest | import pytest | ||||
from django.contrib.auth.models import User | from django.contrib.auth.models import User | ||||
from django.core.cache import cache | from django.core.cache import cache | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
settings.register_profile( | settings.register_profile( | ||||
"swh-web-fast", | "swh-web-fast", | ||||
settings( | settings( | ||||
deadline=None, max_examples=5, suppress_health_check=suppress_health_check, | deadline=None, max_examples=5, suppress_health_check=suppress_health_check, | ||||
), | ), | ||||
) | ) | ||||
def pytest_addoption(parser): | |||||
parser.addoption("--swh-web-random-seed", action="store", default=None) | |||||
def pytest_configure(config): | def pytest_configure(config): | ||||
# Use fast hypothesis profile by default if none has been | # Use fast hypothesis profile by default if none has been | ||||
# explicitly specified in pytest option | # explicitly specified in pytest option | ||||
if config.getoption("--hypothesis-profile") is None: | if config.getoption("--hypothesis-profile") is None: | ||||
settings.load_profile("swh-web-fast") | settings.load_profile("swh-web-fast") | ||||
# Small hack in order to be able to run the unit tests | # Small hack in order to be able to run the unit tests | ||||
# without static assets generated by webpack. | # without static assets generated by webpack. | ||||
Show All 36 Lines | for bundle in bundles: | ||||
"name": asset, | "name": asset, | ||||
"publicPath": f"/static/{asset}", | "publicPath": f"/static/{asset}", | ||||
} | } | ||||
with open(webpack_stats, "w") as outfile: | with open(webpack_stats, "w") as outfile: | ||||
json.dump(mock_webpack_stats, outfile) | json.dump(mock_webpack_stats, outfile) | ||||
_swh_web_custom_section = "swh-web custom section" | |||||
_random_seed_cache_key = "swh-web/random-seed" | |||||
@pytest.fixture(scope="function", autouse=True) | |||||
def random_seed(pytestconfig): | |||||
state = random.getstate() | |||||
seed = pytestconfig.getoption("--swh-web-random-seed") | |||||
if seed is None: | |||||
seed = time.time() | |||||
seed = int(seed) | |||||
cache.set(_random_seed_cache_key, seed) | |||||
random.seed(seed) | |||||
yield seed | |||||
random.setstate(state) | |||||
def pytest_report_teststatus(report, config): | |||||
if report.when == "call" and report.outcome == "failed": | |||||
seed = cache.get(_random_seed_cache_key, None) | |||||
line = ( | |||||
f'FAILED {report.nodeid}: Use "pytest --swh-web-random-seed={seed} ' | |||||
f'{report.nodeid}" to reproduce that test failure with same inputs' | |||||
) | |||||
report.sections.append((_swh_web_custom_section, line)) | |||||
def pytest_terminal_summary(terminalreporter, exitstatus, config): | |||||
reports = terminalreporter.getreports("failed") | |||||
content = os.linesep.join( | |||||
text | |||||
for report in reports | |||||
for secname, text in report.sections | |||||
if secname == _swh_web_custom_section | |||||
) | |||||
if content: | |||||
terminalreporter.ensure_newline() | |||||
terminalreporter.section(_swh_web_custom_section, sep="-", blue=True, bold=True) | |||||
terminalreporter.line(content) | |||||
# Clear Django cache before each test | # Clear Django cache before each test | ||||
@pytest.fixture(autouse=True) | @pytest.fixture(autouse=True) | ||||
def django_cache_cleared(): | def django_cache_cleared(): | ||||
cache.clear() | cache.clear() | ||||
# Alias rf fixture from pytest-django | # Alias rf fixture from pytest-django | ||||
@pytest.fixture | @pytest.fixture | ||||
▲ Show 20 Lines • Show All 1,007 Lines • Show Last 20 Lines |