Skip to content

Commit 125fa9d

Browse files
committed
Remove fixtures and get pytest to check for cpu availability at runtime
1 parent dd0e519 commit 125fa9d

File tree

2 files changed

+46
-40
lines changed

2 files changed

+46
-40
lines changed

tests/core/conftest.py

-28
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,6 @@
99
from cellfinder.core.tools.prep import DEFAULT_INSTALL_PATH
1010

1111

12-
@pytest.fixture()
13-
def no_free_cpus() -> int:
14-
"""
15-
Set number of free CPUs,
16-
so all available CPUs are used by the tests.
17-
18-
Note that this is passed to min_cpus_to_keep_free,
19-
so a value of 0 implies no CPUs will be kept free,
20-
IE all will be used.
21-
"""
22-
return 0
23-
24-
25-
@pytest.fixture()
26-
def run_on_one_cpu_only() -> int:
27-
"""
28-
Set number of free CPUs so tests can use exactly one CPU.
29-
30-
Note that this is passed to min_cpus_to_keep_free,
31-
so a value of #cpus-1 implies all but one CPU will be kept free.
32-
"""
33-
cpus = os.cpu_count()
34-
if cpus is not None:
35-
return cpus - 1
36-
else:
37-
raise ValueError("No CPUs available.")
38-
39-
4012
@pytest.fixture(scope="session")
4113
def download_default_model():
4214
"""

tests/core/test_integration/test_detection.py

+46-12
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,43 @@ def background_array():
4545
# FIXME: This isn't a very good example
4646
@pytest.mark.slow
4747
@pytest.mark.parametrize(
48-
"free_cpus",
48+
"cpus_to_leave_available",
4949
[
50-
pytest.param("no_free_cpus", id="No free CPUs"),
51-
pytest.param("run_on_one_cpu_only", id="One CPU"),
50+
pytest.param(0, id="Leave no CPUS free"),
51+
pytest.param(-1, id="Only use one CPU"),
5252
],
5353
)
54-
def test_detection_full(signal_array, background_array, free_cpus, request):
55-
n_free_cpus = request.getfixturevalue(free_cpus)
54+
def test_detection_full(
55+
signal_array, background_array, cpus_to_leave_available: int
56+
):
57+
"""
58+
cpus_to_leave_available is interpreted as follows:
59+
60+
- For values >=0, this is the number of CPUs to leave available
61+
to the system when running this test.
62+
- For values <0, this is HOW MANY CPUS to request be used to
63+
run the test.
64+
65+
In each case, we check that we will be running on at least one CPU,
66+
and not requesting more CPUs than the system can provide.
67+
"""
68+
# Determine the number of CPUs to leave available
69+
system_cpus = os.cpu_count()
70+
# How many CPUs do we want to leave free?
71+
if cpus_to_leave_available >= 0:
72+
n_free_cpus = cpus_to_leave_available
73+
else:
74+
# Number of CPUs to keep free is <0, interpret as
75+
# number of CPUs _to use_. Thus;
76+
# n_free_cpus = system_cpus - |cpus_to_leave_available|
77+
n_free_cpus = system_cpus - abs(cpus_to_leave_available)
78+
# Check that there are enough CPUs
79+
if not 0 <= n_free_cpus < system_cpus:
80+
RuntimeError(
81+
f"Not enough CPUS available (you want to leave {n_free_cpus} "
82+
f"available, but there are only {system_cpus} on the system)."
83+
)
84+
5685
cells_test = main(
5786
signal_array,
5887
background_array,
@@ -80,10 +109,13 @@ def test_detection_full(signal_array, background_array, free_cpus, request):
80109

81110

82111
def test_detection_small_planes(
83-
signal_array, background_array, no_free_cpus, mocker
112+
signal_array,
113+
background_array,
114+
mocker,
115+
cpus_to_leave_free: int = 0,
84116
):
85117
# Check that processing works when number of planes < number of processes
86-
nproc = get_num_processes(no_free_cpus)
118+
nproc = get_num_processes(cpus_to_leave_free)
87119
n_planes = 2
88120

89121
# Don't want to bother classifying in this test, so mock classifcation
@@ -100,11 +132,13 @@ def test_detection_small_planes(
100132
background_array[0:n_planes],
101133
voxel_sizes,
102134
ball_z_size=5,
103-
n_free_cpus=no_free_cpus,
135+
n_free_cpus=cpus_to_leave_free,
104136
)
105137

106138

107-
def test_callbacks(signal_array, background_array, no_free_cpus):
139+
def test_callbacks(
140+
signal_array, background_array, cpus_to_leave_free: int = 0
141+
):
108142
# 20 is minimum number of planes needed to find > 0 cells
109143
signal_array = signal_array[0:20]
110144
background_array = background_array[0:20]
@@ -129,7 +163,7 @@ def detect_finished_callback(points):
129163
detect_callback=detect_callback,
130164
classify_callback=classify_callback,
131165
detect_finished_callback=detect_finished_callback,
132-
n_free_cpus=no_free_cpus,
166+
n_free_cpus=cpus_to_leave_free,
133167
)
134168

135169
np.testing.assert_equal(planes_done, np.arange(len(signal_array)))
@@ -147,13 +181,13 @@ def test_floating_point_error(signal_array, background_array):
147181
main(signal_array, background_array, voxel_sizes)
148182

149183

150-
def test_synthetic_data(synthetic_bright_spots, no_free_cpus):
184+
def test_synthetic_data(synthetic_bright_spots, cpus_to_leave_free: int = 0):
151185
signal_array, background_array = synthetic_bright_spots
152186
detected = main(
153187
signal_array,
154188
background_array,
155189
voxel_sizes,
156-
n_free_cpus=no_free_cpus,
190+
n_free_cpus=cpus_to_leave_free,
157191
)
158192
assert len(detected) == 8
159193

0 commit comments

Comments
 (0)