Skip to content

Commit 27bcc50

Browse files
Use alternative signalling mechanism to fix tests
For unknown reasons on some CI runners, using Process.terminate() was no longer working. This resulted in test processes not being cleaned up and interfering with later tests which re-use the same PV names. The new mechanism more cleanly terminates the subprocesses by letting them exit of their own volition, rather than being forcibly killed. Also adding some extra configuration to fix warnings from pytest-asyncio plugin, which will at some point become errors.
1 parent 8125cbd commit 27bcc50

File tree

3 files changed

+15
-13
lines changed

3 files changed

+15
-13
lines changed

setup.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ extend-ignore =
6060
addopts =
6161
--tb=native -vv --doctest-modules --ignore=iocStats --ignore=epicscorelibs --ignore=docs
6262
--cov=softioc --cov-report term --cov-report xml:cov.xml
63+
# Enables all discovered async tests and fixtures to be automatically marked as async, even if
64+
# they don't have a specific marker https://github.com/pytest-dev/pytest-asyncio#auto-mode
65+
asyncio_mode = auto
6366

6467
[coverage:run]
6568
# This is covered in the versiongit test suite so exclude it here

tests/test_record_values.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from typing import List
33
import numpy
44
import pytest
5-
import asyncio
65

76
from enum import Enum
87
from math import isnan, inf, nan
@@ -350,13 +349,13 @@ def run_ioc(record_configurations: list, conn, set_enum, get_enum):
350349
if val is not None:
351350
conn.send(record.get())
352351

353-
conn.close()
354-
355352
# Keep process alive while main thread works.
356353
# This is most applicable to CAGET tests.
357-
asyncio.run_coroutine_threadsafe(
358-
asyncio.sleep(TIMEOUT), dispatcher.loop
359-
).result()
354+
while (True):
355+
if conn.poll(TIMEOUT):
356+
val = conn.recv()
357+
if val == "EXIT":
358+
break
360359

361360

362361
def run_test_function(
@@ -475,7 +474,10 @@ def run_test_function(
475474
# Purge cache to suppress spurious "IOC disconnected" exceptions
476475
_channel_cache.purge()
477476

478-
ioc_process.terminate()
477+
478+
parent_conn.send("EXIT")
479+
480+
# ioc_process.terminate()
479481
ioc_process.join(timeout=TIMEOUT)
480482
if ioc_process.exitcode is None:
481483
pytest.fail("Process did not terminate")

tests/test_records.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,8 @@ def validate_ioc_test_func(self, record_func, queue, validate_pass: bool):
167167

168168
queue.put("IOC ready")
169169

170-
# Keep process alive while main thread works.
171-
# This is most applicable to CAGET tests.
172-
asyncio.run_coroutine_threadsafe(
173-
asyncio.sleep(TIMEOUT), dispatcher.loop
174-
).result()
170+
# Keep process alive while main thread runs CAGET
171+
queue.get(timeout=5)
175172

176173
def validate_test_runner(
177174
self,
@@ -224,7 +221,7 @@ def validate_test_runner(
224221
assert ret_val == expected_value
225222

226223
finally:
227-
process.terminate()
224+
queue.put("EXIT")
228225
process.join(timeout=3)
229226

230227

0 commit comments

Comments
 (0)