From 7eeec25eb85554fb46c27fc37ad00dcc1bdb3fb8 Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 23 Feb 2026 13:05:31 +0000 Subject: [PATCH 1/2] fix(test): resolve flaky test_midnight_heartbeats boundary condition The test was intermittently failing with `assert 9 == 8` because: 1. `midnight` retained residual microseconds from `datetime.now()`, making the exact midnight boundary non-deterministic across runs 2. Event 9 (starting at 23:59 with 1-min duration) has endtime exactly at midnight, and the server's `endtime >= start_query` condition sometimes includes it in the "after midnight" query results Fix: zero out seconds/microseconds on the start timestamp for deterministic boundaries, and add a 1ms offset to the query start to avoid the ambiguous boundary where events ending exactly at midnight could be included. Closes ActivityWatch/activitywatch#1211 (follow-up) --- tests/test_client.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index ffd56135..ba6e69ff 100755 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -253,7 +253,11 @@ def test_midnight(aw_client, bucket): def test_midnight_heartbeats(aw_client, bucket): now = datetime.now(tz=timezone.utc) - timedelta(days=1) - midnight = now.replace(hour=23, minute=50) + # Zero out seconds/microseconds for deterministic midnight boundary. + # Without this, residual microseconds cause non-deterministic boundary + # matching when querying events around midnight (the endtime >= start_query + # condition can include/exclude boundary events depending on microseconds). + midnight = now.replace(hour=23, minute=50, second=0, microsecond=0) events = _create_periodic_events(20, start=midnight, delta=timedelta(minutes=1)) label_ring = ["1", "1", "2", "3", "4"] @@ -264,8 +268,12 @@ def test_midnight_heartbeats(aw_client, bucket): recv_events_merged = aw_client.get_events(bucket, limit=-1) assert len(recv_events_merged) == 4 / 5 * len(events) + # Query from midnight (00:00), which is exactly midnight + 10 minutes from + # the 23:50 start. Use a small offset to avoid boundary ambiguity where + # events ending exactly at midnight could be included by the >= condition. + query_start = midnight + timedelta(minutes=10, milliseconds=1) recv_events_after_midnight = aw_client.get_events( - bucket, start=midnight + timedelta(minutes=10) + bucket, start=query_start ) pprint(recv_events_after_midnight) assert len(recv_events_after_midnight) == int(len(recv_events_merged) / 2) From 61f046d6d166cee6bf0dca08e602ff3a3e55db45 Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 23 Feb 2026 13:13:05 +0000 Subject: [PATCH 2/2] style: fix Black formatting in test_midnight_heartbeats --- tests/test_client.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index ba6e69ff..a650abab 100755 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -272,9 +272,7 @@ def test_midnight_heartbeats(aw_client, bucket): # the 23:50 start. Use a small offset to avoid boundary ambiguity where # events ending exactly at midnight could be included by the >= condition. query_start = midnight + timedelta(minutes=10, milliseconds=1) - recv_events_after_midnight = aw_client.get_events( - bucket, start=query_start - ) + recv_events_after_midnight = aw_client.get_events(bucket, start=query_start) pprint(recv_events_after_midnight) assert len(recv_events_after_midnight) == int(len(recv_events_merged) / 2)