Files
scylladb/test/conftest.py
Andrei Chekun a20d848c01 test.py: Refactor test/conftest.py
Move functions responsible for preparation of the environment to the util file.
This is extracted from https://github.com/scylladb/scylladb/pull/22894 to make it easier to work together.

Closes scylladb/scylladb#23221
2025-03-17 11:31:00 +02:00

115 lines
4.6 KiB
Python

#
# Copyright (C) 2024-present ScyllaDB
#
# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
#
from __future__ import annotations
import asyncio
import os
import sys
from typing import TYPE_CHECKING
import pytest
from test import TEST_RUNNER
from test.pylib.report_plugin import ReportPlugin
from test.pylib.suite.base import TestSuite, init_testsuite_globals
from test.pylib.util import get_configured_modes, prepare_dirs, start_s3_mock_services
if TYPE_CHECKING:
from asyncio import AbstractEventLoop
ALL_MODES = {'debug': 'Debug',
'release': 'RelWithDebInfo',
'dev': 'Dev',
'sanitize': 'Sanitize',
'coverage': 'Coverage'}
def pytest_addoption(parser):
parser.addoption('--mode', choices=ALL_MODES.keys(), action="append", dest="modes",
help="Run only tests for given build mode(s)")
parser.addoption('--tmpdir', action='store', default='testlog', help='''Path to temporary test data and log files. The data is
further segregated per build mode. Default: ./testlog.''', )
parser.addoption('--run_id', action='store', default=None, help='Run id for the test run')
# Following option is to use with bare pytest command.
#
# For compatibility with reasons need to run bare pytest with --test-py-init option
# to run a test.py-compatible pytest session.
#
# TODO: remove this when we'll completely switch to bare pytest runner.
parser.addoption('--test-py-init', action='store_true', default=False,
help='Run pytest session in test.py-compatible mode. I.e., start all required services, etc.')
@pytest.fixture(scope="session")
def build_mode(request):
"""
This fixture returns current build mode.
This is for running tests through the test.py script, where only one mode is passed to the test
"""
# to avoid issues when there's no provided mode parameter, do it in two steps: get the parameter and if it's not
# None, get the first value from the list
mode = request.config.getoption("modes")
if mode:
return mode[0]
return mode
def pytest_configure(config):
config.pluginmanager.register(ReportPlugin())
def pytest_collection_modifyitems(config, items):
"""
This is a standard pytest method.
This is needed to modify the test names with dev mode and run id to differ them one from another
"""
run_id = config.getoption('run_id', None)
for item in items:
# check if this is custom cpp tests that have additional attributes for name modification
if hasattr(item, 'mode'):
# modify name with mode that is always present in cpp tests
item.nodeid = f'{item.nodeid}.{item.mode}'
item.name = f'{item.name}.{item.mode}'
if item.run_id:
item.nodeid = f'{item.nodeid}.{item.run_id}'
item.name = f'{item.name}.{item.run_id}'
else:
# here go python tests that are executed through test.py
# since test.py is responsible for creating several tests with the required mode,
# a list with modes contains only one value,
# that's why in name modification the first element is used
modes = config.getoption('modes')
if modes:
item._nodeid = f'{item._nodeid}.{modes[0]}'
item.name = f'{item.name}.{modes[0]}'
if run_id:
item._nodeid = f'{item._nodeid}.{run_id}'
item.name = f'{item.name}.{run_id}'
def pytest_sessionstart(session: pytest.Session) -> None:
# test.py starts S3 mock and create/cleanup testlog by itself. Also, if we run with --collect-only option,
# we don't need this stuff.
if TEST_RUNNER != "pytest" or session.config.getoption("--collect-only"):
return
if not session.config.getoption("--test-py-init"):
return
init_testsuite_globals()
TestSuite.artifacts.add_exit_artifact(None, TestSuite.hosts.cleanup)
# Run stuff just once for the pytest session even running under xdist.
if "xdist" not in sys.modules or not sys.modules["xdist"].is_xdist_worker(request_or_session=session):
temp_dir = os.path.join(session.config.rootpath, "..", session.config.getoption("--tmpdir"))
prepare_dirs(tempdir_base=temp_dir, modes=session.config.getoption("--mode") or get_configured_modes())
start_s3_mock_services(minio_tempdir_base=temp_dir)
def pytest_sessionfinish() -> None:
if getattr(TestSuite, "artifacts", None) is not None:
asyncio.get_event_loop().run_until_complete(TestSuite.artifacts.cleanup_before_exit())