From b7e2de310e084d60d2b06e30e18b3e8c34e6097c Mon Sep 17 00:00:00 2001 From: Nelson Parente Date: Wed, 21 Oct 2026 11:51:43 +0200 Subject: [PATCH] test(health): measure the health check timeout with time.monotonic() DaprHealth computes its deadline with time.monotonic(), but the tests measured the elapsed time with time.time(). On Windows the two clocks have different resolutions, so the >= 2.5 check failed now and then (2.4987 s) although the code waited the full timeout. Use the same clock in the tests. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Nelson Parente --- tests/clients/test_healthcheck.py | 9 +++++---- tests/clients/test_healthcheck_async.py | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/clients/test_healthcheck.py b/tests/clients/test_healthcheck.py index 535c45e32..3012713f1 100644 --- a/tests/clients/test_healthcheck.py +++ b/tests/clients/test_healthcheck.py @@ -71,12 +71,13 @@ def test_wait_for_sidecar_success_with_api_token(self, mock_urlopen): def test_wait_for_sidecar_timeout(self, mock_urlopen): mock_urlopen.return_value.__enter__.return_value = MagicMock(status=500) - start = time.time() + start = time.monotonic() with self.assertRaises(TimeoutError): DaprHealth.wait_for_sidecar() - self.assertGreaterEqual(time.time() - start, 2.5) + # Same clock as DaprHealth. On Windows, time.time() can read a few ms less. + self.assertGreaterEqual(time.monotonic() - start, 2.5) self.assertGreater(mock_urlopen.call_count, 1) @@ -103,14 +104,14 @@ def wait(): # Run in a daemon thread so a regression fails this test instead of hanging # the whole session. waiter = threading.Thread(target=wait, daemon=True) - start = time.time() + start = time.monotonic() waiter.start() waiter.join(self.HANG_LIMIT_SECONDS) self.assertFalse(waiter.is_alive(), 'wait_for_sidecar() blocked past DAPR_HEALTH_TIMEOUT') self.assertIsInstance(outcome.get('error'), TimeoutError) self.assertIn('Dapr health check timed out', str(outcome['error'])) - self.assertLess(time.time() - start, self.HANG_LIMIT_SECONDS) + self.assertLess(time.monotonic() - start, self.HANG_LIMIT_SECONDS) logged = [str(call.args[0]) for call in mock_print.call_args_list if call.args] self.assertTrue(any(line.endswith('failed: timed out') for line in logged), logged) self.assertFalse(any(line.startswith('Unexpected error') for line in logged), logged) diff --git a/tests/clients/test_healthcheck_async.py b/tests/clients/test_healthcheck_async.py index 4f18889e3..373551cf4 100644 --- a/tests/clients/test_healthcheck_async.py +++ b/tests/clients/test_healthcheck_async.py @@ -87,12 +87,13 @@ async def test_wait_for_sidecar_timeout(self, mock_get): mock_response.__aexit__ = AsyncMock(return_value=None) mock_get.return_value = mock_response - start = time.time() + start = time.monotonic() with self.assertRaises(TimeoutError): await DaprHealth.wait_for_sidecar() - self.assertGreaterEqual(time.time() - start, 2.5) + # Same clock as DaprHealth. On Windows, time.time() can read a few ms less. + self.assertGreaterEqual(time.monotonic() - start, 2.5) self.assertGreater(mock_get.call_count, 1) @patch.object(settings, 'DAPR_HTTP_ENDPOINT', 'http://domain.com:3500') @@ -174,13 +175,13 @@ async def test_multiple_health_checks_concurrent(self, mock_get): mock_get.return_value = mock_response # Run multiple health checks concurrently - start_time = time.time() + start_time = time.monotonic() results = await asyncio.gather( DaprHealth.wait_for_sidecar(), DaprHealth.wait_for_sidecar(), DaprHealth.wait_for_sidecar(), ) - elapsed = time.time() - start_time + elapsed = time.monotonic() - start_time # All should complete successfully self.assertEqual(len(results), 3)