Skip to content

Commit

Permalink
refactor: move test suite out of caput (#274)
Browse files Browse the repository at this point in the history
And fix the pytest.fixture things I was complaining about.
  • Loading branch information
ketiltrout authored Aug 6, 2024
1 parent 1b543a0 commit d487c67
Show file tree
Hide file tree
Showing 23 changed files with 99 additions and 97 deletions.
17 changes: 7 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,18 @@ jobs:

- name: Install pip dependencies
run: |
pip install -e .
pip install -e .[mpi]
pip install -e .[compression]
pip install -e .[test]
pip install -e .[compression,mpi,test]
- name: Run serial tests
run: pytest --doctest-modules caput/
run: pytest --doctest-modules .

- name: Run parallel tests
run: |
mpirun --oversubscribe -np 4 pytest caput/tests/test_memh5_parallel.py
mpirun --oversubscribe -np 4 pytest caput/tests/test_mpiarray.py
mpirun -np 1 pytest caput/tests/test_selection_parallel.py
mpirun --oversubscribe -np 2 pytest caput/tests/test_selection_parallel.py
mpirun --oversubscribe -np 4 pytest caput/tests/test_selection_parallel.py
mpirun --oversubscribe -np 4 pytest tests/test_memh5_parallel.py
mpirun --oversubscribe -np 4 pytest tests/test_mpiarray.py
mpirun -np 1 pytest tests/test_selection_parallel.py
mpirun --oversubscribe -np 2 pytest tests/test_selection_parallel.py
mpirun --oversubscribe -np 4 pytest tests/test_selection_parallel.py
build-docs:

Expand Down
17 changes: 0 additions & 17 deletions caput/tests/test_pipeline.py

This file was deleted.

2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import caput

# Mock up modules missing on readthedocs.
from mock import Mock as MagicMock
from unittest.mock import Mock as MagicMock


class Mock(MagicMock):
Expand Down
File renamed without changes.
File renamed without changes.
105 changes: 48 additions & 57 deletions caput/tests/conftest.py → tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import numpy as np
import pytest

from ..pipeline import PipelineStopIteration, TaskBase, IterBase
from ..scripts.runner import cli
from .. import config, fileformats, mpiutil
from caput.pipeline import PipelineStopIteration, TaskBase, IterBase
from caput.scripts.runner import cli
from caput import config, fileformats, mpiutil


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -106,16 +106,19 @@ def write_output(self, filename, output, file_format=None, **kwargs):
raise NotImplementedError()


eggs_pipeline_conf = """
@pytest.fixture
def run_pipeline():
"""Provides the `run_pipeline` function which will run the pipeline."""
eggs_pipeline_conf = """
---
pipeline:
tasks:
- type: caput.tests.conftest.PrintEggs
- type: tests.conftest.PrintEggs
params: eggs_params
- type: caput.tests.conftest.GetEggs
- type: tests.conftest.GetEggs
params: eggs_params
out: egg
- type: caput.tests.conftest.CookEggs
- type: tests.conftest.CookEggs
params: cook_params
in: egg
eggs_params:
Expand All @@ -124,71 +127,53 @@ def write_output(self, filename, output, file_format=None, **kwargs):
style: 'fried'
"""

multi_eggs_pipeline_conf = """
---
pipeline:
tasks:
- type: caput.tests.conftest.GetEggs
params: eggs_params
out: [color, egg]
- type: caput.tests.conftest.CookEggs
params: cook_params
in: egg
- type: caput.tests.conftest.CookEggs
params: cook_params
in: color
eggs_params:
eggs: [['green', 'duck'], ['blue', 'ostrich']]
cook_params:
style: 'fried'
"""

def _run_pipeline(parameters=None, configstr=eggs_pipeline_conf):
"""Run `caput.scripts.runner run` with given parameters and config.
def run_pipeline(parameters=None, configstr=eggs_pipeline_conf):
"""Run `caput.scripts.runner run` with given parameters and config.
Parameters
----------
parameters : List[str]
Parameters to pass to the cli, for example `["--profile"]` (see `--help`).
configstr : str
YAML string to use as a config. This function will write it to a file that is then passed to the cli.
Parameters
----------
parameters : List[str]
Parameters to pass to the cli, for example `["--profile"]` (see `--help`).
configstr : str
YAML string to use as a config. This function will write it to a file that is then passed to the cli.
Returns
-------
result : `click.testing.Result`
Holds the captured result. Try accessing e.g. `result.exit_code`, `result.output`.
"""
with tempfile.NamedTemporaryFile("w+") as configfile:
configfile.write(configstr)
configfile.flush()
from click.testing import CliRunner

Returns
-------
result : `click.testing.Result`
Holds the captured result. Try accessing e.g. `result.exit_code`, `result.output`.
"""
with tempfile.NamedTemporaryFile("w+") as configfile:
configfile.write(configstr)
configfile.flush()
from click.testing import CliRunner
runner = CliRunner()
if parameters is None:
return runner.invoke(cli, ["run", configfile.name])
else:
return runner.invoke(cli, ["run", *parameters, configfile.name])

runner = CliRunner()
if parameters is None:
return runner.invoke(cli, ["run", configfile.name])
else:
return runner.invoke(cli, ["run", *parameters, configfile.name])
return _run_pipeline


@pytest.fixture
def h5_file():
def h5_file(rm_all_files):
"""Provides a file name and removes all files/dirs with the same prefix later."""
fname = "tmp_test_memh5.h5"
yield fname
rm_all_files(fname)


@pytest.fixture
def zarr_file():
def zarr_file(rm_all_files):
"""Provides a directory name and removes all files/dirs with the same prefix later."""
fname = "tmp_test_memh5.zarr"
yield fname
rm_all_files(fname)


@pytest.fixture
def h5_file_distributed():
def h5_file_distributed(rm_all_files):
"""Provides a file name and removes all files/dirs with the same prefix later."""
fname = "tmp_test_memh5_distributed.h5"
yield fname
Expand All @@ -197,16 +182,22 @@ def h5_file_distributed():


@pytest.fixture
def zarr_file_distributed():
def zarr_file_distributed(rm_all_files):
"""Provides a directory name and removes all files/dirs with the same prefix later."""
fname = "tmp_test_memh5.zarr"
yield fname
if mpiutil.rank == 0:
rm_all_files(fname)


def rm_all_files(file_name):
"""Remove all files and directories starting with `file_name`."""
file_names = glob.glob(file_name + "*")
for fname in file_names:
fileformats.remove_file_or_dir(fname)
@pytest.fixture
def rm_all_files():
"""Provides the `rm_all_files` function."""

def _rm_all_files(file_name):
"""Remove all files and directories starting with `file_name`."""
file_names = glob.glob(file_name + "*")
for fname in file_names:
fileformats.remove_file_or_dir(fname)

return _rm_all_files
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions caput/tests/test_lint.py → tests/test_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ def simple_config():
"pipeline": {
"tasks": [
{
"type": "caput.tests.test_lint.DoNothing",
"type": "tests.test_lint.DoNothing",
"out": "out1",
},
{
"type": "caput.tests.test_lint.DoNothing",
"type": "tests.test_lint.DoNothing",
"out": "out2",
"in": "out1",
},
{
"type": "caput.tests.test_lint.DoNothing2",
"type": "tests.test_lint.DoNothing2",
"in": "out2",
"out": "out3",
"requires": "out1",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
35 changes: 35 additions & 0 deletions tests/test_pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Test running the caput.pipeline."""


def test_pipeline(run_pipeline):
"""Test running a very simple pipeline."""
result = run_pipeline()
print(result.output)
assert result.exit_code == 0


def test_pipeline_multiple_outputs(run_pipeline):
"""Test running a very simple pipeline with a multi-output task."""

multi_eggs_pipeline_conf = """
---
pipeline:
tasks:
- type: tests.conftest.GetEggs
params: eggs_params
out: [color, egg]
- type: tests.conftest.CookEggs
params: cook_params
in: egg
- type: tests.conftest.CookEggs
params: cook_params
in: color
eggs_params:
eggs: [['green', 'duck'], ['blue', 'ostrich']]
cook_params:
style: 'fried'
"""

result = run_pipeline(configstr=multi_eggs_pipeline_conf)
print(result.output)
assert result.exit_code == 0
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
"""Test running the caput.pipeline."""

from caput.tests import conftest


def test_pipeline():
def test_pipeline(run_pipeline):
"""Test profiling a very simple pipeline."""
result = conftest.run_pipeline(["--psutil"])
result = run_pipeline(["--psutil"])
print(result.output)
assert result.exit_code == 0
5 changes: 2 additions & 3 deletions caput/tests/test_selection.py → tests/test_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from caput.memh5 import MemGroup
from caput import fileformats
from caput.tests.conftest import rm_all_files

fsel = slice(1, 8, 2)
isel = slice(1, 4)
Expand All @@ -16,7 +15,7 @@


@pytest.fixture
def h5_file_select(datasets, h5_file):
def h5_file_select(datasets, h5_file, rm_all_files):
"""Provides an HDF5 file with some content for testing."""
container = MemGroup()
container.create_dataset("dset1", data=datasets[0].view())
Expand All @@ -27,7 +26,7 @@ def h5_file_select(datasets, h5_file):


@pytest.fixture
def zarr_file_select(datasets, zarr_file):
def zarr_file_select(datasets, zarr_file, rm_all_files):
"""Provides a Zarr file with some content for testing."""
container = MemGroup()
container.create_dataset("dset1", data=datasets[0].view())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@

from caput import mpiutil, mpiarray, fileformats
from caput.memh5 import MemGroup
from caput.tests.conftest import rm_all_files


comm = MPI.COMM_WORLD


@pytest.fixture
def container_on_disk(datasets, file_name, file_format):
def container_on_disk(datasets, file_name, file_format, rm_all_files):
"""Prepare a file for the select_parallel tests."""
if comm.rank == 0:
m1 = mpiarray.MPIArray.wrap(datasets[0], axis=0, comm=MPI.COMM_SELF)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit d487c67

Please sign in to comment.