fix(tests): make test_list_by_thread independent of host clock granularity (#5210)

test_list_by_thread creates two runs back-to-back and expects the newer
one to sort first under list_by_thread's newest-first ordering. That
relies on the wall clock advancing between the two create() calls.

On Windows, datetime.now() has a coarse granularity (~15.6 ms), so both
runs can receive an identical created_at. Python's stable sort then
keeps insertion order and the assertion fails; on this host 50
consecutive now_iso() calls return identical strings.

Drive the clock with a controlled 1 ms-per-call fake (same monkeypatch
pattern as test_list_by_thread_is_stable_when_timestamps_tie) so the
strictly-newer assumption no longer depends on the host clock. The tie
case stays covered by the existing dedicated test.

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
theater 2026-09-06 10:10:08 +08:00 committed by GitHub
parent b002d55991
commit ab9c1719ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,9 +1,11 @@
"""Tests for RunManager.""" """Tests for RunManager."""
import asyncio import asyncio
import itertools
import logging import logging
import re import re
import sqlite3 import sqlite3
from datetime import UTC, datetime, timedelta
from typing import Any from typing import Any
import pytest import pytest
@ -616,8 +618,18 @@ async def test_cancel_not_inflight(manager: RunManager):
@pytest.mark.anyio @pytest.mark.anyio
async def test_list_by_thread(manager: RunManager): async def test_list_by_thread(manager: RunManager, monkeypatch: pytest.MonkeyPatch):
"""Same thread should return multiple runs.""" """Same thread should return multiple runs."""
# Advance the fake clock 1ms per call so r2 gets a strictly newer
# created_at than r1 even on hosts with coarse wall-clock granularity
# (Windows timestamps can repeat across consecutive creates).
base = datetime.now(UTC)
calls = itertools.count()
monkeypatch.setattr(
"deerflow.runtime.runs.manager._now_iso",
lambda: (base + timedelta(milliseconds=next(calls))).isoformat(),
)
r1 = await manager.create("thread-1") r1 = await manager.create("thread-1")
r2 = await manager.create("thread-1") r2 = await manager.create("thread-1")
await manager.create("thread-2") await manager.create("thread-2")