diff --git a/tests/conftest.py b/tests/conftest.py index 2118d241a7..203efeb986 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,19 +1,40 @@ # -# Pytest hooks shared across the netlab test tree +# Shared pytest configuration for the netlab test suite. +# +# 1. Prepend the repository root (the directory containing the 'netsim' +# package) to sys.path so 'cd tests && pytest' inside a git worktree +# imports this checkout's netsim/, not the venv egg-link's (which +# usually points at the main checkout). +# +# 2. Anchor the working directory to tests/ so the test bodies' relative +# globs (e.g. glob.glob('topology/input/*yml')) resolve no matter +# where pytest is invoked from. +# +# 3. Surface a UserWarning when ruamel.yaml is installed -- the +# transformation tests will be slower and create-error-tests.sh is +# unsupported (see https://github.com/ipspace/netlab/issues/3345). # +import os +import pathlib +import sys + import pytest -from utils import HAS_RUAMEL + +_HERE = pathlib.Path(__file__).resolve().parent +sys.path.insert(0, str(_HERE.parent)) + +from utils import HAS_RUAMEL # noqa: E402 -- requires sys.path tweak above def pytest_configure(config: pytest.Config) -> None: - if not HAS_RUAMEL: - return - config.issue_config_time_warning( - UserWarning( - "ruamel.yaml is installed; transformation tests will be slower and " - "`create-error-tests.sh` is unsupported " - "(see https://github.com/ipspace/netlab/issues/3345)." - ), - stacklevel=2, - ) + os.chdir(_HERE) + if HAS_RUAMEL: + config.issue_config_time_warning( + UserWarning( + "ruamel.yaml is installed; transformation tests will be slower and " + "`create-error-tests.sh` is unsupported " + "(see https://github.com/ipspace/netlab/issues/3345)." + ), + stacklevel=2, + ) diff --git a/tests/test_transformation.py b/tests/test_transformation.py index 08037d75ad..0a37c5d8c0 100755 --- a/tests/test_transformation.py +++ b/tests/test_transformation.py @@ -63,12 +63,11 @@ def run_transformation_test(test_case: str, tmpdir: str = '/tmp') -> None: assert result == expected print("... succeeded, string length = %d" % len(result)) - + @pytest.mark.filterwarnings("ignore::PendingDeprecationWarning") -def test_xform_cases(tmpdir: str) -> None: - print("Starting transformation test cases") - for test_case in list(glob.glob('topology/input/*yml')): - run_transformation_test(test_case) +@pytest.mark.parametrize('test_case',sorted(glob.glob('topology/input/*yml'))) +def test_xform_cases(test_case: str, tmpdir: str) -> None: + run_transformation_test(test_case) # Verbose test cases are executed only when we're doing a coverage report # @@ -76,7 +75,8 @@ def test_coverage_verbose_cases(tmpdir: str) -> None: if not sys.gettrace(): return log.set_verbose() - test_xform_cases(tmpdir) + for test_case in sorted(glob.glob('topology/input/*yml')): + run_transformation_test(test_case) def run_error_case(test_case: str) -> None: log.set_flag(raise_error = True) @@ -97,22 +97,16 @@ def run_error_case(test_case: str) -> None: assert error_log == log_lines @pytest.mark.filterwarnings("ignore::PendingDeprecationWarning") -def test_error_cases() -> None: - print("Starting error test cases") - for test_case in list(glob.glob('errors/*yml')): - run_error_case(test_case) +@pytest.mark.parametrize('test_case',sorted(glob.glob('errors/*yml'))) +def test_error_cases(test_case: str) -> None: + run_error_case(test_case) @pytest.mark.filterwarnings("ignore::PendingDeprecationWarning") -def test_coverage_xf_cases() -> None: - for test_case in list(glob.glob('coverage/input/*yml')): - run_transformation_test(test_case) +@pytest.mark.parametrize('test_case',sorted(glob.glob('coverage/input/*yml'))) +def test_coverage_xf_cases(test_case: str) -> None: + run_transformation_test(test_case) @pytest.mark.filterwarnings("ignore::PendingDeprecationWarning") -def test_coverage_errors() -> None: - for test_case in list(glob.glob('coverage/errors/*yml')): - run_error_case(test_case) - -if __name__ == "__main__": - test_xform_cases("/tmp") -# test_error_cases() -# test_minimal_cases() +@pytest.mark.parametrize('test_case',sorted(glob.glob('coverage/errors/*yml'))) +def test_coverage_errors(test_case: str) -> None: + run_error_case(test_case)