From 8084b677d9b5ebfe4f77f9c55604ea9579acfdcd Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Thu, 3 Aug 2023 19:26:38 -0400 Subject: [PATCH] test(generate_classes): parametrize, allow configuring via CLI/env (#1903) --- autotest/conftest.py | 8 ++++ autotest/test_generate_classes.py | 80 +++++++++++++++++++++++-------- 2 files changed, 69 insertions(+), 19 deletions(-) diff --git a/autotest/conftest.py b/autotest/conftest.py index a9d817c8d..b85458c04 100644 --- a/autotest/conftest.py +++ b/autotest/conftest.py @@ -118,6 +118,14 @@ def pytest_addoption(parser): "but automated tests should probably also check patch collections or figure & axis properties.)", ) + # for test_generate_classes.py + parser.addoption( + "--ref", + action="append", + type=str, + help="Include extra refs to test. Useful for testing branches on a fork, e.g. /modflow6/.", + ) + def pytest_report_header(config): """Header for pytest to show versions of packages.""" diff --git a/autotest/test_generate_classes.py b/autotest/test_generate_classes.py index 06527a56f..e48c73eb1 100644 --- a/autotest/test_generate_classes.py +++ b/autotest/test_generate_classes.py @@ -1,15 +1,62 @@ import sys +from datetime import datetime +from os import environ from pathlib import Path from pprint import pprint +from typing import Iterable +from warnings import warn import pytest +def nonempty(itr: Iterable): + for x in itr: + if x: + yield x + + +def pytest_generate_tests(metafunc): + # defaults + ref = [ + "MODFLOW-USGS/modflow6/develop", + "MODFLOW-USGS/modflow6/master", + "MODFLOW-USGS/modflow6/6.4.1", + ] + + # refs provided as env vars override the defaults + ref_env = environ.get("TEST_GENERATE_CLASSES_REF") + if ref_env: + ref = nonempty(ref_env.strip().split(",")) + + # refs given as CLI options override everything + ref_opt = metafunc.config.getoption("--ref") + if ref_opt: + ref = nonempty([o.strip() for o in ref_opt]) + + # drop duplicates + ref = list(dict.fromkeys(ref)) + + # drop and warn refs with invalid format + # i.e. not "owner/repo/branch" + for r in ref: + spl = r.split("/") + if len(spl) != 3 or not all(spl): + warn(f"Skipping invalid ref: {r}") + ref.remove(r) + + key = "ref" + if key in metafunc.fixturenames: + metafunc.parametrize(key, ref, scope="session") + + @pytest.mark.mf6 -def test_generate_classes_from_dfn(virtualenv, project_root_path): +@pytest.mark.slow +def test_generate_classes_from_dfn(virtualenv, project_root_path, ref): python = virtualenv.python venv = Path(python).parent - print(f"Using temp venv at {venv} with python {python}") + print( + f"Using temp venv at {venv} with python {python} to test class generation from {ref}" + ) # install flopy/dependencies pprint(virtualenv.run(f"pip install {project_root_path}")) @@ -31,9 +78,10 @@ def test_generate_classes_from_dfn(virtualenv, project_root_path): mod_file_times = [Path(mod_file).stat().st_mtime for mod_file in mod_files] pprint(mod_files) - # generate classes from develop branch - owner = "MODFLOW-USGS" - branch = "develop" + # generate classes + spl = ref.split("/") + owner = spl[0] + branch = spl[2] pprint( virtualenv.run( "python -c 'from flopy.mf6.utils import generate_classes; generate_classes(owner=\"" @@ -44,31 +92,25 @@ def test_generate_classes_from_dfn(virtualenv, project_root_path): ) ) + def get_mtime(f): + try: + return Path(f).stat().st_mtime + except: + return 0 # if file not found + # make sure files were regenerated modified_files = [ mod_files[i] for i, (before, after) in enumerate( zip( mod_file_times, - [Path(mod_file).stat().st_mtime for mod_file in mod_files], + [get_mtime(f) for f in mod_files], ) ) - if after > before + if after > 0 and after > before ] assert any(modified_files) print(f"{len(modified_files)} files were modified:") pprint(modified_files) - # try with master branch - branch = "master" - pprint( - virtualenv.run( - "python -c 'from flopy.mf6.utils import generate_classes; generate_classes(owner=\"" - + owner - + '", branch="' - + branch - + "\", backup=False)'" - ) - ) - # todo checkout mf6 and test with dfnpath? test with backups?