Skip to content

Commit ed3c4df

Browse files
committed
Clean up how the tests are run "run in process" Part 2: use @pytest.mark.parametrize and clean up the naming.
1 parent 3ecdafe commit ed3c4df

File tree

1 file changed

+45
-31
lines changed

1 file changed

+45
-31
lines changed

tests/test_gil_scoped.py

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -105,24 +105,37 @@ def test_multi_acquire_release_cross_module():
105105
assert len(internals_ids) == 2 if bits % 8 else 1
106106

107107

108-
def _python_to_cpp_to_python():
109-
test_callback_py_obj()
110-
test_callback_std_func()
111-
test_callback_virtual_func()
112-
test_callback_pure_virtual_func()
113-
test_cross_module_gil_released()
114-
test_cross_module_gil_acquired()
115-
test_cross_module_gil_inner_custom_released()
116-
test_cross_module_gil_inner_custom_acquired()
117-
test_cross_module_gil_inner_pybind11_released()
118-
test_cross_module_gil_inner_pybind11_acquired()
119-
test_cross_module_gil_nested_custom_released()
120-
test_cross_module_gil_nested_custom_acquired()
121-
test_cross_module_gil_nested_pybind11_released()
122-
test_cross_module_gil_nested_pybind11_acquired()
123-
test_release_acquire()
124-
test_nested_acquire()
125-
test_multi_acquire_release_cross_module()
108+
# Intentionally putting human review in the loop here, to guard against accidents.
109+
VARS_BEFORE_ALL_BASIC_TESTS = dict(vars()) # Make a copy of the dict (critical).
110+
ALL_BASIC_TESTS = (
111+
test_callback_py_obj,
112+
test_callback_std_func,
113+
test_callback_virtual_func,
114+
test_callback_pure_virtual_func,
115+
test_cross_module_gil_released,
116+
test_cross_module_gil_acquired,
117+
test_cross_module_gil_inner_custom_released,
118+
test_cross_module_gil_inner_custom_acquired,
119+
test_cross_module_gil_inner_pybind11_released,
120+
test_cross_module_gil_inner_pybind11_acquired,
121+
test_cross_module_gil_nested_custom_released,
122+
test_cross_module_gil_nested_custom_acquired,
123+
test_cross_module_gil_nested_pybind11_released,
124+
test_cross_module_gil_nested_pybind11_acquired,
125+
test_release_acquire,
126+
test_nested_acquire,
127+
test_multi_acquire_release_cross_module,
128+
)
129+
130+
131+
def test_all_basic_tests_completeness():
132+
num_found = 0
133+
for key, value in VARS_BEFORE_ALL_BASIC_TESTS.items():
134+
if not key.startswith("test_"):
135+
continue
136+
assert value in ALL_BASIC_TESTS
137+
num_found += 1
138+
assert len(ALL_BASIC_TESTS) == num_found
126139

127140

128141
def _run_in_process(target, *args, **kwargs):
@@ -139,11 +152,10 @@ def _run_in_process(target, *args, **kwargs):
139152
process.terminate()
140153

141154

142-
def _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
143-
"""Calls different C++ functions that come back to Python, from Python threads."""
155+
def _run_in_threads(target, num_threads, parallel):
144156
threads = []
145157
for _ in range(num_threads):
146-
thread = threading.Thread(target=_python_to_cpp_to_python)
158+
thread = threading.Thread(target=target)
147159
thread.daemon = True
148160
thread.start()
149161
if parallel:
@@ -155,44 +167,46 @@ def _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
155167

156168

157169
# TODO: FIXME, sometimes returns -11 (segfault) instead of 0 on macOS Python 3.9
158-
def test_python_to_cpp_to_python_from_thread():
170+
@pytest.mark.parametrize("test_fn", ALL_BASIC_TESTS)
171+
def test_run_in_process_one_thread(test_fn):
159172
"""Makes sure there is no GIL deadlock when running in a thread.
160173
161174
It runs in a separate process to be able to stop and assert if it deadlocks.
162175
"""
163-
assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0
176+
assert _run_in_process(_run_in_threads, test_fn, num_threads=1, parallel=False) == 0
164177

165178

166179
# TODO: FIXME on macOS Python 3.9
167-
def test_python_to_cpp_to_python_from_thread_multiple_parallel():
180+
@pytest.mark.parametrize("test_fn", ALL_BASIC_TESTS)
181+
def test_run_in_process_multiple_threads_parallel(test_fn):
168182
"""Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.
169183
170184
It runs in a separate process to be able to stop and assert if it deadlocks.
171185
"""
172-
exitcode = _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True)
186+
exitcode = _run_in_process(_run_in_threads, test_fn, num_threads=8, parallel=True)
173187
if exitcode is None and env.PYPY and env.WIN: # Seems to be flaky.
174188
pytest.skip("Ignoring unexpected exitcode None (PYPY WIN)")
175189
assert exitcode == 0
176190

177191

178192
# TODO: FIXME on macOS Python 3.9
179-
def test_python_to_cpp_to_python_from_thread_multiple_sequential():
193+
@pytest.mark.parametrize("test_fn", ALL_BASIC_TESTS)
194+
def test_run_in_process_multiple_threads_sequential(test_fn):
180195
"""Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.
181196
182197
It runs in a separate process to be able to stop and assert if it deadlocks.
183198
"""
184-
assert (
185-
_run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0
186-
)
199+
assert _run_in_process(_run_in_threads, test_fn, num_threads=8, parallel=False) == 0
187200

188201

189202
# TODO: FIXME on macOS Python 3.9
190-
def test_python_to_cpp_to_python_from_process():
203+
@pytest.mark.parametrize("test_fn", ALL_BASIC_TESTS)
204+
def test_run_in_process_direct(test_fn):
191205
"""Makes sure there is no GIL deadlock when using processes.
192206
193207
This test is for completion, but it was never an issue.
194208
"""
195-
exitcode = _run_in_process(_python_to_cpp_to_python)
209+
exitcode = _run_in_process(test_fn)
196210
if exitcode is None and env.PYPY and env.WIN: # Seems to be flaky.
197211
pytest.skip("Ignoring unexpected exitcode None (PYPY WIN)")
198212
assert exitcode == 0

0 commit comments

Comments
 (0)