From 2c5eccb68bb7f483ec0042bc9236280ef9d6383f Mon Sep 17 00:00:00 2001 From: DropD Date: Fri, 31 Jan 2025 14:54:08 +0100 Subject: [PATCH 1/5] disable slow tests by default, enable on CI --- .github/workflows/ci.yaml | 2 +- pyproject.toml | 5 ++++- src/sirocco/core/workflow.py | 2 +- tests/test_wc_workflow.py | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a3501211..c4ec7f96 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,7 +38,7 @@ jobs: env: PYTEST_ADDOPTS: "--durations=0" run: | - hatch test --cover + hatch test -m "" --cover # override default exclusion of slow tests with -m "" docs: runs-on: ubuntu-latest diff --git a/pyproject.toml b/pyproject.toml index a4041a78..9d60ac7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,9 @@ Changelog = "https://github.com/C2SM/Sirocco/blob/main/CHANGELOG.md" # Configuration for [pytest](https://docs.pytest.org) addopts = "--pdbcls=IPython.terminal.debugger:TerminalPdb" norecursedirs = "tests/cases" +markers = [ + "slow: slow integration tests which are not recommended to run locally for normal development" +] [tool.coverage.run] # Configuration of [coverage.py](https://coverage.readthedocs.io) @@ -83,7 +86,7 @@ extra-dependencies = [ "ipdb" ] default-args = [] -extra-args = ["--doctest-modules"] +extra-args = ["--doctest-modules", '-m not slow'] [[tool.hatch.envs.hatch-test.matrix]] python = ["3.12"] diff --git a/src/sirocco/core/workflow.py b/src/sirocco/core/workflow.py index 13f856ea..c394ad4a 100644 --- a/src/sirocco/core/workflow.py +++ b/src/sirocco/core/workflow.py @@ -116,7 +116,7 @@ def from_config_file(cls: type[Self], config_path: str) -> Self: return cls.from_config_workflow(ConfigWorkflow.from_config_file(config_path)) @classmethod - def from_config_workflow(cls: type[Self], config_workflow: ConfigWorkflow) -> Workflow: + def from_config_workflow(cls: type[Self], config_workflow: ConfigWorkflow) -> Self: return cls( name=config_workflow.name, config_rootdir=config_workflow.rootdir, diff --git a/tests/test_wc_workflow.py b/tests/test_wc_workflow.py index 23dfceee..3649d6d8 100644 --- a/tests/test_wc_workflow.py +++ b/tests/test_wc_workflow.py @@ -69,6 +69,7 @@ def test_vizgraph(config_paths): # configs that are tested for running workgraph +@pytest.mark.slow @pytest.mark.parametrize( "config_path", [ From 1905f954ef9e33a0ce2cc429a50ce39da72982b6 Mon Sep 17 00:00:00 2001 From: DropD Date: Fri, 31 Jan 2025 15:58:06 +0100 Subject: [PATCH 2/5] fix unavoidable warnings and force non-ignored warnigns as errors. --- pyproject.toml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9d60ac7c..c5593881 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,13 @@ norecursedirs = "tests/cases" markers = [ "slow: slow integration tests which are not recommended to run locally for normal development" ] +filterwarnings = [ + "error", + "ignore::UserWarning", + 'ignore:datetime.datetime.utcfromtimestamp\(\) is deprecated:DeprecationWarning', # from aio_pika via duration + "ignore:There is no current event loop:DeprecationWarning", # from plumpy via aiida testing tools + "ignore:Object of type not in session:sqlalchemy.exc.SAWarning", # sqlalchemy via aiida testing tools +] [tool.coverage.run] # Configuration of [coverage.py](https://coverage.readthedocs.io) @@ -85,8 +92,8 @@ installer = "uv" extra-dependencies = [ "ipdb" ] -default-args = [] -extra-args = ["--doctest-modules", '-m not slow'] +default-args = ['-m not slow'] +extra-args = ["--doctest-modules"] [[tool.hatch.envs.hatch-test.matrix]] python = ["3.12"] From c0f65b6750b254a716cbc7cfb49f8ea8dba9ba1b Mon Sep 17 00:00:00 2001 From: DropD Date: Fri, 31 Jan 2025 17:10:54 +0100 Subject: [PATCH 3/5] add cmdline option for regenerating serialized references --- tests/conftest.py | 56 +++++++++++++++++++++++++++++++++++++ tests/test_wc_workflow.py | 58 ++++++--------------------------------- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index ea414760..97184f56 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,11 @@ import pathlib +import typing import pytest +from sirocco import pretty_print +from sirocco.core import _tasks as core_tasks +from sirocco.core import workflow from sirocco.parsing import _yaml_data_models as models pytest_plugins = ["aiida.tools.pytest_fixtures"] @@ -20,3 +24,55 @@ def minimal_config() -> models.ConfigWorkflow: ), parameters={}, ) + + +# configs that are tested for parsing +ALL_CONFIG_CASES = ["small", "parameters", "large"] + + +@pytest.fixture(params=ALL_CONFIG_CASES) +def config_case(request) -> typing.Iterator[str]: + return request.param + + +@pytest.fixture +def pprinter() -> typing.Iterator[pretty_print.PrettyPrinter]: + return pretty_print.PrettyPrinter() + + +def generate_config_paths(test_case: str): + return { + "yml": pathlib.Path(f"tests/cases/{test_case}/config/config.yml"), + "txt": pathlib.Path(f"tests/cases/{test_case}/data/config.txt"), + "svg": pathlib.Path(f"tests/cases/{test_case}/svg/config.svg"), + } + + +@pytest.fixture +def config_paths(config_case) -> typing.Iterator[dict[str, pathlib.Path]]: + return generate_config_paths(config_case) + + +def pytest_addoption(parser): + parser.addoption("--reserialize", action="store_true", default=False) + + +def serialize_worklfow(config_paths: dict[str, pathlib.Path], workflow: workflow.Workflow) -> None: + config_paths["txt"].write_text(pretty_print.PrettyPrinter().format(workflow)) + + +def serialize_nml(config_paths: dict[str, pathlib.Path], workflow: workflow.Workflow) -> None: + nml_refdir = config_paths["txt"].parent / "ICON_namelists" + for task in workflow.tasks: + if isinstance(task, core_tasks.icon_task.IconTask): + task.create_workflow_namelists(folder=nml_refdir) + + +def pytest_configure(config): + if config.getoption("reserialize"): + print("Regenerating serialized references") # noqa: T201 # this is actual UX, not a debug print + for config_case in ALL_CONFIG_CASES: + config_paths = generate_config_paths(config_case) + wf = workflow.Workflow.from_config_file(str(config_paths["yml"])) + serialize_worklfow(config_paths=config_paths, workflow=wf) + serialize_nml(config_paths=config_paths, workflow=wf) diff --git a/tests/test_wc_workflow.py b/tests/test_wc_workflow.py index 3649d6d8..4491af43 100644 --- a/tests/test_wc_workflow.py +++ b/tests/test_wc_workflow.py @@ -5,7 +5,6 @@ from sirocco.core import Workflow from sirocco.core._tasks.icon_task import IconTask from sirocco.parsing._yaml_data_models import ConfigShellTask, ShellCliArgument -from sirocco.pretty_print import PrettyPrinter from sirocco.vizgraph import VizGraph from sirocco.workgraph import AiidaWorkGraph @@ -26,28 +25,6 @@ def test_parsing_cli_parameters(): ] -@pytest.fixture -def pprinter(): - return PrettyPrinter() - - -def generate_config_paths(test_case: str): - return { - "yml": Path(f"tests/cases/{test_case}/config/config.yml"), - "txt": Path(f"tests/cases/{test_case}/data/config.txt"), - "svg": Path(f"tests/cases/{test_case}/svg/config.svg"), - } - - -# configs that are tested for parsing -all_uses_cases = ["small", "parameters", "large"] - - -@pytest.fixture(params=all_uses_cases) -def config_paths(request): - return generate_config_paths(request.param) - - def test_parse_config_file(config_paths, pprinter): reference_str = config_paths["txt"].read_text() test_str = pprinter.format(Workflow.from_config_file(config_paths["yml"])) @@ -59,11 +36,6 @@ def test_parse_config_file(config_paths, pprinter): ), f"Workflow graph doesn't match serialized data. New graph string dumped to {new_path}." -@pytest.mark.skip(reason="don't run it each time, uncomment to regenerate serilaized data") -def test_serialize_workflow(config_paths, pprinter): - config_paths["txt"].write_text(pprinter.format(Workflow.from_config_file(config_paths["yml"]))) - - def test_vizgraph(config_paths): VizGraph.from_config_file(config_paths["yml"]).draw(file_path=config_paths["svg"]) @@ -71,13 +43,13 @@ def test_vizgraph(config_paths): # configs that are tested for running workgraph @pytest.mark.slow @pytest.mark.parametrize( - "config_path", + "config_case", [ - "tests/cases/small/config/config.yml", - "tests/cases/parameters/config/config.yml", + "small", + "parameters", ], ) -def test_run_workgraph(config_path, aiida_computer): +def test_run_workgraph(config_case, config_paths, aiida_computer): # noqa: ARG001 # config_case is overridden """Tests end-to-end the parsing from file up to running the workgraph. Automatically uses the aiida_profile fixture to create a new profile. Note to debug the test with your profile @@ -86,7 +58,7 @@ def test_run_workgraph(config_path, aiida_computer): # some configs reference computer "localhost" which we need to create beforehand aiida_computer("localhost").store() - core_workflow = Workflow.from_config_file(config_path) + core_workflow = Workflow.from_config_file(str(config_paths["yml"])) aiida_workflow = AiidaWorkGraph(core_workflow) out = aiida_workflow.run() assert out.get("execution_count", None).value == 1 @@ -94,10 +66,10 @@ def test_run_workgraph(config_path, aiida_computer): # configs containing task using icon plugin @pytest.mark.parametrize( - "config_paths", - [generate_config_paths("large")], + "config_case", + ["large"], ) -def test_nml_mod(config_paths, tmp_path): +def test_nml_mod(config_case, config_paths, tmp_path): # noqa: ARG001 # config_case is overridden nml_refdir = config_paths["txt"].parent / "ICON_namelists" wf = Workflow.from_config_file(config_paths["yml"]) # Create core mamelists @@ -112,17 +84,3 @@ def test_nml_mod(config_paths, tmp_path): new_path = nml.with_suffix(".new") new_path.write_text(test_nml) assert ref_nml == test_nml, f"Namelist {nml.name} differs between ref and test" - - -@pytest.mark.skip(reason="don't run it each time, uncomment to regenerate serilaized data") -# configs containing task using icon plugin -@pytest.mark.parametrize( - "config_paths", - [generate_config_paths("large")], -) -def test_serialize_nml(config_paths): - nml_refdir = config_paths["txt"].parent / "ICON_namelists" - wf = Workflow.from_config_file(config_paths["yml"]) - for task in wf.tasks: - if isinstance(task, IconTask): - task.create_workflow_namelists(folder=nml_refdir) From 756bf13fde148d335496729c06746b22e21255fe Mon Sep 17 00:00:00 2001 From: DropD Date: Mon, 3 Feb 2025 10:31:43 +0100 Subject: [PATCH 4/5] move -m not slow to extra args --- .github/workflows/ci.yaml | 2 +- pyproject.toml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c4ec7f96..b28d5c75 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,7 +38,7 @@ jobs: env: PYTEST_ADDOPTS: "--durations=0" run: | - hatch test -m "" --cover # override default exclusion of slow tests with -m "" + hatch test -m "" --parallel --cover # override default exclusion of slow tests with -m "" docs: runs-on: ubuntu-latest diff --git a/pyproject.toml b/pyproject.toml index c5593881..39a5d715 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,8 +92,7 @@ installer = "uv" extra-dependencies = [ "ipdb" ] -default-args = ['-m not slow'] -extra-args = ["--doctest-modules"] +extra-args = ["--doctest-modules", '-m not slow'] [[tool.hatch.envs.hatch-test.matrix]] python = ["3.12"] From e794ca2873547713c8970a61dec528ecdaac8117 Mon Sep 17 00:00:00 2001 From: DropD Date: Tue, 4 Feb 2025 13:54:01 +0100 Subject: [PATCH 5/5] re-add empty default-args key for hatch test --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 39a5d715..7f9a4c6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,7 @@ installer = "uv" extra-dependencies = [ "ipdb" ] +default-args = [] extra-args = ["--doctest-modules", '-m not slow'] [[tool.hatch.envs.hatch-test.matrix]]