Skip to content

Commit 232bd53

Browse files
authored
Always mark unmarked tests as 'parallel[1]' (#26)
* Always mark unmarked tests as 'parallel[1]' This means we can avoid the clunky -m "not parallel or parallel[1]" * Always mark even if no markers are found
1 parent c82dc5f commit 232bd53

File tree

3 files changed

+21
-20
lines changed

3 files changed

+21
-20
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ jobs:
6464
: # 'forking' mode
6565
pytest -v tests
6666
: # 'non-forking' mode
67-
${{ matrix.mpiexec }} -n 1 pytest -v -m "not parallel or parallel[1]" tests
67+
${{ matrix.mpiexec }} -n 1 pytest -v -m parallel[1] tests
6868
${{ matrix.mpiexec }} -n 2 pytest -v -m parallel[2] tests
6969
${{ matrix.mpiexec }} -n 3 pytest -v -m parallel[3] tests

README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ to each test to allow one to select all tests with a particular number of proces
5151
For example, to select all parallel tests on 3 processors, one should run:
5252

5353
```bash
54-
$ mpiexec -n 3 pytest -m "parallel[3]"
54+
$ mpiexec -n 3 pytest -m parallel[3]
5555
```
5656

5757
Serial tests - those either unmarked or marked `@pytest.mark.parallel(1)` - can
5858
be selected by running:
5959

6060
```bash
61-
$ pytest -m "not parallel or parallel[1]"
61+
$ pytest -m parallel[1]
6262
```
6363

6464
### Forking mode
@@ -84,10 +84,6 @@ This is convenient for development for a number of reasons:
8484

8585
There are however a number of downsides:
8686

87-
* Only one mainstream MPI distribution ([MPICH](https://www.mpich.org/)) supports
88-
nested calls to `MPI_Init`. If your 'parent' `pytest` process initialises MPI
89-
(for instance by executing `from mpi4py import MPI`) then this will cause non-MPICH
90-
MPI distributions to crash.
9187
* Forking a subprocess can be expensive since a completely fresh Python interpreter
9288
is launched each time.
9389
* Sandboxing each test means that polluted global state at the end of a test cannot
@@ -101,7 +97,7 @@ with `mpiexec`, no additional configuration is necessary. For example, to run
10197
all of the parallel tests on 2 ranks one needs to execute:
10298

10399
```bash
104-
$ mpiexec -n 2 pytest -m "parallel[2]"
100+
$ mpiexec -n 2 pytest -m parallel[2]
105101
```
106102

107103
## `parallel_assert`

pytest_mpi/plugin.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,25 +88,30 @@ def pytest_generate_tests(metafunc):
8888

8989
@pytest.hookimpl()
9090
def pytest_collection_modifyitems(config, items):
91+
"""Add 'parallel[N]' markers to each test."""
9192
global _plugin_in_use
9293

9394
_plugin_in_use = any(item.get_closest_marker("parallel") for item in items)
9495

95-
if not _plugin_in_use:
96-
return
97-
9896
for item in items:
9997
if item.get_closest_marker("parallel"):
100-
# Add extra markers to each test to allow for querying specific levels of
101-
# parallelism (e.g. "-m parallel[3]")
10298
nprocs = _extract_nprocs_for_single_test(item)
103-
new_marker = f"parallel[{nprocs}]"
104-
if new_marker not in pytest.mark._markers:
105-
config.addinivalue_line(
106-
"markers",
107-
f"{new_marker}: internal marker"
108-
)
109-
item.add_marker(getattr(pytest.mark, new_marker))
99+
marker_name = f"parallel[{nprocs}]"
100+
else:
101+
# mark serial tests as 'parallel[1]'
102+
marker_name = "parallel[1]"
103+
104+
_maybe_register_marker(config, marker_name)
105+
item.add_marker(getattr(pytest.mark, marker_name))
106+
107+
108+
def _maybe_register_marker(config, marker_name: str) -> None:
109+
"""Register ``marker_name`` as a new marker if it does not already exist."""
110+
if marker_name not in pytest.mark._markers:
111+
config.addinivalue_line(
112+
"markers",
113+
f"{marker_name}: internal marker"
114+
)
110115

111116

112117
@pytest.hookimpl()

0 commit comments

Comments
 (0)