fix(ci): stub resolve_runtime_provider in cron wake-gate tests + shield update-check timeout test from thread race

Two additional CI failures surfaced when the first PR ran through GHA —
both were pre-existing but blocked merge.

1) tests/cron/test_scheduler.py::TestRunJobWakeGate (3 tests)
   run_job calls resolve_runtime_provider BEFORE constructing AIAgent, so
   patching run_agent.AIAgent alone isn't enough — the resolver raises
   'No inference provider configured' in hermetic CI (no API keys) and
   the test never reaches the mocked AIAgent.  Added autouse fixture
   that stubs resolve_runtime_provider with a fake openrouter runtime.

2) tests/hermes_cli/test_update_check.py::test_get_update_result_timeout
   Observed on CI: assert 4950 is None.  A background update-check
   thread (from an earlier test or hermes_cli.main's own
   prefetch_update_check call) raced a real git-fetch result
   (4950 commits behind origin/main) into banner._update_result during
   this test's wait(0.1).  Wrap the test in patch.object(banner,
   'check_for_updates', return_value=None) so any in-flight thread
   writes None rather than a real value.

Validation:
  Under CI-parity env (env -i, no creds): 6/6 pass
  Broader suite (tests/hermes_cli + cron + gateway + run_agent/streaming
  + toolsets + discord_tool): 6033 passed, pre-existing failures in
  telegram_approval_buttons (3) and internal_event_bypass_pairing (1)
  are unrelated.
This commit is contained in:
Teknium 2026-04-19 18:55:20 -07:00 committed by Teknium
parent c9b833feb3
commit ad4680cf74
2 changed files with 44 additions and 10 deletions

View file

@ -114,20 +114,30 @@ def test_prefetch_non_blocking():
def test_get_update_result_timeout():
"""get_update_result() returns None when check hasn't completed within timeout."""
"""get_update_result() returns None when check hasn't completed within timeout.
Race protection: a background update-check thread from an earlier
test, or from hermes_cli.main's own prefetch_update_check(), could
write to module-level ``_update_result`` during this test's
``wait(0.1)``. Observed on CI: a real git-fetch returned 4950
commits-behind mid-test, failing ``assert 4950 is None``. Patching
``check_for_updates`` for the duration of the test ensures any
in-flight thread writes ``None`` rather than a real fetch result.
"""
import hermes_cli.banner as banner
# Reset module state — don't set the event
banner._update_result = None
banner._update_check_done = threading.Event()
with patch.object(banner, "check_for_updates", return_value=None):
# Fresh Event so we hit the timeout branch deterministically.
banner._update_result = None
banner._update_check_done = threading.Event()
start = time.monotonic()
result = banner.get_update_result(timeout=0.1)
elapsed = time.monotonic() - start
start = time.monotonic()
result = banner.get_update_result(timeout=0.1)
elapsed = time.monotonic() - start
# Should have waited ~0.1s and returned None
assert result is None
assert elapsed < 0.5
# Should have waited ~0.1s and returned None
assert result is None
assert elapsed < 0.5
def test_invalidate_update_cache_clears_all_profiles(tmp_path):