diff --git a/tests/tools/test_file_sync.py b/tests/tools/test_file_sync.py index 0c387bd38898..ce49b4364794 100644 --- a/tests/tools/test_file_sync.py +++ b/tests/tools/test_file_sync.py @@ -236,7 +236,7 @@ class TestRateLimiting: from tools.environments import file_sync clock = {"t": 1000.0} - monkeypatch.setattr(file_sync.time, "monotonic", lambda: clock["t"]) + monkeypatch.setattr(file_sync, "_monotonic", lambda: clock["t"]) upload = MagicMock(side_effect=RuntimeError("transport down")) mgr = FileSyncManager( diff --git a/tools/environments/file_sync.py b/tools/environments/file_sync.py index 181e9643799a..2357228ef9c5 100644 --- a/tools/environments/file_sync.py +++ b/tools/environments/file_sync.py @@ -35,6 +35,9 @@ logger = logging.getLogger(__name__) # ``time.sleep`` globally because ``time`` is the module object; under xdist # that lets unrelated background threads inflate retry-test call counts. _sleep = time.sleep +# Same rationale for the rate-limit clock: tests patch ``_monotonic`` +# instead of ``time.monotonic`` on the shared module object. +_monotonic = time.monotonic _SYNC_INTERVAL_SECONDS = 5.0 _FORCE_SYNC_ENV = "HERMES_FORCE_FILE_SYNC" @@ -169,7 +172,7 @@ class FileSyncManager: On failure, state rolls back so the next cycle retries everything. """ if not force and not os.environ.get(_FORCE_SYNC_ENV): - now = time.monotonic() + now = _monotonic() if now - self._last_sync_time < self._sync_interval: return @@ -193,7 +196,7 @@ class FileSyncManager: to_delete = [p for p in self._synced_files if p not in current_remote_paths] if not to_upload and not to_delete: - self._last_sync_time = time.monotonic() + self._last_sync_time = _monotonic() return # Snapshot for rollback (only when there's work to do) @@ -227,7 +230,7 @@ class FileSyncManager: self._pushed_hashes.pop(p, None) self._synced_files = new_files - self._last_sync_time = time.monotonic() + self._last_sync_time = _monotonic() except Exception as exc: self._synced_files = prev_files