From 765ab8d9bd22993f912cb7588763fbd7cdbe2b35 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 18 Jan 2024 13:12:08 +0200 Subject: [PATCH] Fix fragile tests (#325) The previous push to `master` failed to deploy because of a flaky Windows test. --- pycyphal/transport/can/media/candump/_candump.py | 5 ++++- pycyphal/transport/can/media/pythoncan/_pythoncan.py | 10 ++++++++-- pycyphal/transport/can/media/socketcan/_socketcan.py | 5 ++++- pycyphal/transport/can/media/socketcand/_socketcand.py | 10 ++++++++-- tests/demo/_demo_app.py | 2 +- tests/transport/can/media/_pythoncan.py | 1 + 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/pycyphal/transport/can/media/candump/_candump.py b/pycyphal/transport/can/media/candump/_candump.py index c68de56d5..66e1d85eb 100644 --- a/pycyphal/transport/can/media/candump/_candump.py +++ b/pycyphal/transport/can/media/candump/_candump.py @@ -146,7 +146,10 @@ def close(self) -> None: self._f.close() self._thread, thd = None, self._thread assert thd is not None - thd.join(timeout=1) + try: + thd.join(timeout=1) + except RuntimeError: + pass @property def _is_closed(self) -> bool: diff --git a/pycyphal/transport/can/media/pythoncan/_pythoncan.py b/pycyphal/transport/can/media/pythoncan/_pythoncan.py index 119859d10..04f2af2c0 100644 --- a/pycyphal/transport/can/media/pythoncan/_pythoncan.py +++ b/pycyphal/transport/can/media/pythoncan/_pythoncan.py @@ -323,9 +323,15 @@ def close(self) -> None: self._closed = True try: self._tx_queue.put(None) - self._tx_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + try: + self._tx_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + except RuntimeError: + pass if self._maybe_thread is not None: - self._maybe_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + try: + self._maybe_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + except RuntimeError: + pass self._maybe_thread = None finally: try: diff --git a/pycyphal/transport/can/media/socketcan/_socketcan.py b/pycyphal/transport/can/media/socketcan/_socketcan.py index 6dad9a062..17d68562d 100644 --- a/pycyphal/transport/can/media/socketcan/_socketcan.py +++ b/pycyphal/transport/can/media/socketcan/_socketcan.py @@ -165,7 +165,10 @@ def close(self) -> None: if self._ctl_main.fileno() >= 0: # Ignore if already closed. self._ctl_main.send(b"stop") # The actual data is irrelevant, we just need it to unblock the select(). if self._maybe_thread: - self._maybe_thread.join(timeout=_SELECT_TIMEOUT) + try: + self._maybe_thread.join(timeout=_SELECT_TIMEOUT) + except RuntimeError: + pass self._maybe_thread = None finally: self._sock.close() # These are expected to be idempotent. diff --git a/pycyphal/transport/can/media/socketcand/_socketcand.py b/pycyphal/transport/can/media/socketcand/_socketcand.py index d011d48a5..0a382eb83 100644 --- a/pycyphal/transport/can/media/socketcand/_socketcand.py +++ b/pycyphal/transport/can/media/socketcand/_socketcand.py @@ -203,9 +203,15 @@ def close(self) -> None: self._closed = True try: self._tx_queue.put(None) - self._tx_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + try: + self._tx_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + except RuntimeError: + pass if self._maybe_thread is not None: - self._maybe_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + try: + self._maybe_thread.join(timeout=self._MAXIMAL_TIMEOUT_SEC * 10) + except RuntimeError: + pass self._maybe_thread = None finally: try: diff --git a/tests/demo/_demo_app.py b/tests/demo/_demo_app.py index ea7cd8029..a3ed15b4d 100644 --- a/tests/demo/_demo_app.py +++ b/tests/demo/_demo_app.py @@ -310,7 +310,7 @@ async def _unittest_slow_demo_app( assert hb.health.value == hb.health.NOMINAL assert hb.mode.value == hb.mode.OPERATIONAL assert num_heartbeats <= hb.uptime <= 300 - assert prev_hb_transfer[0].uptime <= hb.uptime <= prev_hb_transfer[0].uptime + 1 + assert prev_hb_transfer[0].uptime <= hb.uptime <= prev_hb_transfer[0].uptime + 2 # +2 due to aliasing assert transfer.transfer_id == prev_hb_transfer[1].transfer_id + 1 prev_hb_transfer = hb_transfer num_heartbeats += 1 diff --git a/tests/transport/can/media/_pythoncan.py b/tests/transport/can/media/_pythoncan.py index e4a31395d..4e503cd80 100644 --- a/tests/transport/can/media/_pythoncan.py +++ b/tests/transport/can/media/_pythoncan.py @@ -164,6 +164,7 @@ def _unittest_can_pythoncan_iface_name() -> None: # multiple colons are allowed in interface names, only the first one is split media = PythonCANMedia("virtual:0:0", 1_000_000) assert media.interface_name == "virtual:0:0" + media.close() def _unittest_can_pythoncan_errors() -> None: