fix(tests): make mtime_invalidation and glm_5_3 robust (#7100) - #7101
webtecnica wants to merge 1 commit into
Conversation
|
| Filename | Overview |
|---|---|
| tests/test_glm_5_3_catalog.py | Pins the live provider catalog to an empty list so the test deterministically exercises the repository fallback. |
| tests/test_ttl_cache.py | Makes cache setup and cleanup self-contained, but the post-mismatch assertion does not prove that invalidation rebuilt the primed cache. |
Reviews (1): Last reviewed commit: "fix(tests): make mtime_invalidation and ..." | Re-trigger Greptile
| # to 0.0 on invalidation. | ||
| assert config._available_models_cache_ts > 0.0, ( | ||
| "Cache timestamp should be updated after invalidation + rebuild" | ||
| ) |
There was a problem hiding this comment.
The priming call already establishes that _available_models_cache_ts is positive, so repeating that assertion after the mtime mismatch does not distinguish a rebuild from reuse of the primed cache. Compare the cache identity or timestamp across the second call so an mtime-invalidation regression cannot pass undetected.
Context Used: AGENTS.md (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
Reviewed the diff at
|
….6 max reasoning (#7083) + test order-independence (#7101) (#7102) * fix(tests): make mtime_invalidation and glm_5_3 tests order-independent (#7100) * fix: expose max reasoning for GPT-5.6 models * fix(recovery): do not reattach cancelling runs ACTIVE_RUNS tracks worker lifecycle, which is deliberately broader than "a turn a browser may attach to". cancel_stream() keeps the row as phase="cancelling" while the worker unwinds so a successor turn cannot start on top of it, but the client has already reached a terminal state for that stream: its run journal ends in a terminal event. The recovery lookups treated every same-session ACTIVE_RUNS row as attachable. An idle session holding a cancelling row therefore received a recovered server_turn_started on every /api/session/stream subscription: the client attached, replayed the terminal event, tore the renderer down, resubscribed, and the server replayed the same frame again. The result is an endless attach/replay loop that rebuilds the transcript repeatedly. Separate the two meanings instead of narrowing one call site: - api/config.py gains active_run_is_attachable() and active_run_cancel_is_stale() as the shared predicates. - active_stream_id_for_session() (browser recovery) returns attachable rows only; _session_has_active_turn() (busy check) keeps counting a fresh cancellation so a successor cannot overlap the unwinding worker. - _live_active_stream_id() applies the same rule to the hidden-tab status poller, on both the STREAMS and ACTIVE_RUNS paths. - routes._cancelled_run_is_stale() now delegates to the shared predicate rather than keeping a parallel copy of the staleness rule. - A cancelling row past a bounded unwind window with no live STREAMS channel is reclaimed from ACTIVE_RUNS and its stream owner released, so a wedged worker cannot suppress background wakeups forever. Age alone does not reclaim a row that still owns a live channel. Staleness anchors on cancelled_at, falling back to started_at, so a long-running turn cancelled moments ago is never treated as an orphan. tests/test_cancelling_run_not_attachable.py covers both directions of each rule. The six behavioral tests fail on the unpatched tree and pass with the fix; two targeted mutations (forcing the attachability predicate true, and disabling the staleness reaper) each turn the suite red. * docs(rfc): document cancellation attach/admission split Records the runtime contract introduced by the recovery fix in the WebUI run-state consistency RFC, so the distinction is discoverable instead of living only in code comments. - Adds ACTIVE_RUNS to the State Layers table as the worker-lifecycle registry, explicitly not the set of runs a browser may attach to. - Adds invariant 9: lifecycle-busy is not client-attachable. Cancellation splits the two meanings, recovery paths must exclude cancelling rows, and admission checks must keep counting them. - Documents the bounded cancellation-unwind window: reclamation needs both age and the absence of a live STREAMS channel, and staleness is anchored on the cancellation timestamp. - Extends the review checklist with the admission-vs-attachment question and the evidence required when changing a reclamation window. * docs(changelog): note #7096 cancelling-run reattach, #7083 GPT-5.6 max reasoning, #7101 test order-independence --------- Co-authored-by: webtecnica <webtecnica@gmail.com> Co-authored-by: Abdulrahman Elkenany <boudy.elkenany123@gmail.com> Co-authored-by: allenliang2022 <allenliang2022@users.noreply.github.com> Co-authored-by: n <a@n>
|
Shipped in experimental release exp-v0.52.235 (closes #7100). |
… + GPT-5.6 max reasoning (nesquena#7083) + test order-independence (nesquena#7101) (nesquena#7102) * fix(tests): make mtime_invalidation and glm_5_3 tests order-independent (nesquena#7100) * fix: expose max reasoning for GPT-5.6 models * fix(recovery): do not reattach cancelling runs ACTIVE_RUNS tracks worker lifecycle, which is deliberately broader than "a turn a browser may attach to". cancel_stream() keeps the row as phase="cancelling" while the worker unwinds so a successor turn cannot start on top of it, but the client has already reached a terminal state for that stream: its run journal ends in a terminal event. The recovery lookups treated every same-session ACTIVE_RUNS row as attachable. An idle session holding a cancelling row therefore received a recovered server_turn_started on every /api/session/stream subscription: the client attached, replayed the terminal event, tore the renderer down, resubscribed, and the server replayed the same frame again. The result is an endless attach/replay loop that rebuilds the transcript repeatedly. Separate the two meanings instead of narrowing one call site: - api/config.py gains active_run_is_attachable() and active_run_cancel_is_stale() as the shared predicates. - active_stream_id_for_session() (browser recovery) returns attachable rows only; _session_has_active_turn() (busy check) keeps counting a fresh cancellation so a successor cannot overlap the unwinding worker. - _live_active_stream_id() applies the same rule to the hidden-tab status poller, on both the STREAMS and ACTIVE_RUNS paths. - routes._cancelled_run_is_stale() now delegates to the shared predicate rather than keeping a parallel copy of the staleness rule. - A cancelling row past a bounded unwind window with no live STREAMS channel is reclaimed from ACTIVE_RUNS and its stream owner released, so a wedged worker cannot suppress background wakeups forever. Age alone does not reclaim a row that still owns a live channel. Staleness anchors on cancelled_at, falling back to started_at, so a long-running turn cancelled moments ago is never treated as an orphan. tests/test_cancelling_run_not_attachable.py covers both directions of each rule. The six behavioral tests fail on the unpatched tree and pass with the fix; two targeted mutations (forcing the attachability predicate true, and disabling the staleness reaper) each turn the suite red. * docs(rfc): document cancellation attach/admission split Records the runtime contract introduced by the recovery fix in the WebUI run-state consistency RFC, so the distinction is discoverable instead of living only in code comments. - Adds ACTIVE_RUNS to the State Layers table as the worker-lifecycle registry, explicitly not the set of runs a browser may attach to. - Adds invariant 9: lifecycle-busy is not client-attachable. Cancellation splits the two meanings, recovery paths must exclude cancelling rows, and admission checks must keep counting them. - Documents the bounded cancellation-unwind window: reclamation needs both age and the absence of a live STREAMS channel, and staleness is anchored on the cancellation timestamp. - Extends the review checklist with the admission-vs-attachment question and the evidence required when changing a reclamation window. * docs(changelog): note nesquena#7096 cancelling-run reattach, nesquena#7083 GPT-5.6 max reasoning, nesquena#7101 test order-independence --------- Co-authored-by: webtecnica <webtecnica@gmail.com> Co-authored-by: Abdulrahman Elkenany <boudy.elkenany123@gmail.com> Co-authored-by: allenliang2022 <allenliang2022@users.noreply.github.com> Co-authored-by: n <a@n>
What Changed
Hardened two fragile tests so the full suite no longer produces spurious failures under
SHARDED=1/ isolated runs:tests/test_ttl_cache.py::test_mtime_invalidationtest_cache_hit_within_ttl/test_ttl_expiry)._LIVE_REBUILD_BUDGET_SECONDS = 0.0, so the cache is guaranteed to be published before the first assertion runs. Previously, a cold rebuild on a slow/loaded box could exceed the 4s budget and return a static fallback without populating_available_models_cache, making the test fail when picked up by a shard without its predecessors._available_models_cache is not None,_available_models_cache_ts > 0.0) so failures are diagnosed at the exact precondition, not downstream.tests/test_glm_5_3_catalog.py::test_glm_5_3_in_models_payload_for_zai_providerget_available_models()sources the zai model list from the installed hermes-cli core catalog (_read_live_provider_model_ids→provider_model_ids), not from the repo's static_PROVIDER_MODELS. On a box whose installed core predatesglm-5.3(e.g. onlyglm-5/5.1/5.2), the test failed with "glm-5.3 missing from zai group models".provider_model_ids→[]) so the repo's own_PROVIDER_MODELSfallback is exercised deterministically — verifying WebUI catalog propagation, independent of the installed agent-core version. This matches the issue's suggested fix (a): "pin/stub the core catalog in the test".Verification
pytest tests/test_ttl_cache.py::test_mtime_invalidation— PASSED in isolation (previously order-dependent).pytest tests/test_glm_5_3_catalog.py::test_glm_5_3_in_models_payload_for_zai_provider— PASSED (previously FAILED on this box: installed core lacks glm-5.3).pytest tests/test_ttl_cache.py tests/test_glm_5_3_catalog.py— 13 passed (full-file run intact, no sibling regressions).Closes #7100