mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-25 11:00:35 +00:00
Move starting LDAP to the method where the rest of the services are started. This will unify the way of starting the 3rd party services. Fix LDAP tests flakiness due not possible to connect to LDAP server Add catching stdout and stderr of toxiproxy-cli in case of errors
122 lines
4.9 KiB
Python
122 lines
4.9 KiB
Python
#
|
|
# Copyright (C) 2024-present ScyllaDB
|
|
#
|
|
# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
|
|
#
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from argparse import BooleanOptionalAction
|
|
from pathlib import Path
|
|
from random import randint
|
|
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_3rd_party_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')
|
|
parser.addoption('--byte-limit', action="store", default=randint(0, 2000), type=int,
|
|
help="Specific byte limit for failure injection (random by default)")
|
|
|
|
# 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 = Path(session.config.getoption("--tmpdir")).absolute()
|
|
prepare_dirs(tempdir_base=temp_dir, modes=session.config.getoption("--mode") or get_configured_modes())
|
|
start_3rd_party_services(tempdir_base=temp_dir, toxyproxy_byte_limit=session.config.getoption('byte_limit'))
|
|
|
|
|
|
def pytest_sessionfinish() -> None:
|
|
if getattr(TestSuite, "artifacts", None) is not None:
|
|
asyncio.get_event_loop().run_until_complete(TestSuite.artifacts.cleanup_before_exit())
|