Phase 2 low-risk backend/perf batch (ai-ag2026 reliability cluster). Each byte-verified vs PR head, Codex SAFE, 33 own + 720 regression tests pass, disjoint routes.py regions. - #5840: skip dashboard status poll while tab hidden (perf; forced polls unaffected) - #5841: arm write deadline on session-events invalidation SSE (stuck-client teardown) - #5842: bound client rate-limit maps by sweeping stale keys (long-uptime memory) Co-authored-by: t <a@b> Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
105 lines
4.1 KiB
Python
105 lines
4.1 KiB
Python
"""Regression test — the dashboard status poll is skipped while the tab is hidden.
|
|
|
|
`_initDashboardLinkProbe` sets `setInterval(refreshDashboardStatus, 60000)`, and
|
|
the interval equals `DASHBOARD_STATUS_TTL_MS`, so every background tick was a
|
|
real `/api/dashboard/status` fetch that never hit the cache — a needless wakeup
|
|
on a tab nobody is looking at. It was the only frontend poll without a
|
|
`document.hidden` guard (the gateway / streaming / hidden-stream polls all skip
|
|
while hidden, #4704/#2476).
|
|
|
|
`refreshDashboardStatus` now short-circuits an unforced call while hidden, and
|
|
`_initDashboardLinkProbe` refreshes once on `visibilitychange` back to visible.
|
|
Forced calls (settings save, init, the catch-up) still run.
|
|
"""
|
|
import pathlib
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
import textwrap
|
|
|
|
import pytest
|
|
|
|
REPO = pathlib.Path(__file__).parent.parent
|
|
UI_JS = (REPO / "static" / "ui.js").read_text(encoding="utf-8")
|
|
NODE = shutil.which("node")
|
|
requires_node = pytest.mark.skipif(NODE is None, reason="node not on PATH")
|
|
|
|
|
|
def test_guard_and_catchup_present():
|
|
# Guard lives inside refreshDashboardStatus (keeps the setInterval anchor).
|
|
assert "setInterval(refreshDashboardStatus,DASHBOARD_STATUS_TTL_MS)" in UI_JS
|
|
assert "if(!force&&typeof document!=='undefined'&&document.hidden){" in UI_JS
|
|
assert "visibilitychange" in UI_JS
|
|
|
|
|
|
_DRIVER = textwrap.dedent(
|
|
"""\
|
|
const fs = require('fs');
|
|
function extractFn(src, name) {
|
|
const markers = [`async function ${name}(`, `function ${name}(`];
|
|
let start = -1;
|
|
for (const m of markers) { start = src.indexOf(m); if (start >= 0) break; }
|
|
if (start < 0) throw new Error(`${name}() not found`);
|
|
let i = src.indexOf('{', start), depth = 0, s = null, esc = false, lc = false, bc = false;
|
|
for (; i < src.length; i++) {
|
|
const ch = src[i], nx = src[i + 1] || '';
|
|
if (lc) { if (ch === '\\n') lc = false; continue; }
|
|
if (bc) { if (ch === '*' && nx === '/') bc = false; continue; }
|
|
if (s) { if (esc) esc = false; else if (ch === '\\\\') esc = true; else if (ch === s) s = null; continue; }
|
|
if (ch === '/' && nx === '/') { lc = true; continue; }
|
|
if (ch === '/' && nx === '*') { bc = true; continue; }
|
|
if (ch === '\\'' || ch === '"' || ch === '`') { s = ch; continue; }
|
|
if (ch === '{') depth += 1;
|
|
if (ch === '}') { depth -= 1; if (depth === 0) return src.slice(start, i + 1); }
|
|
}
|
|
throw new Error(`could not extract ${name}`);
|
|
}
|
|
|
|
const uiSrc = fs.readFileSync(process.argv[2], 'utf8');
|
|
const hidden = process.argv[3] === 'hidden';
|
|
let fetches = 0;
|
|
global.document = { hidden };
|
|
global._dashboardStatusCache = null;
|
|
global._dashboardStatusFetchedAt = 0;
|
|
global.DASHBOARD_STATUS_TTL_MS = 60000;
|
|
global._applyDashboardStatus = () => {};
|
|
global.api = (url) => { if (String(url) === '/api/dashboard/status') fetches += 1; return Promise.resolve({ running: true }); };
|
|
eval(extractFn(uiSrc, 'refreshDashboardStatus'));
|
|
|
|
(async () => {
|
|
// Unforced call (what the interval does).
|
|
await refreshDashboardStatus();
|
|
// Forced call always runs regardless of visibility.
|
|
await refreshDashboardStatus(true);
|
|
console.log(JSON.stringify({ fetches }));
|
|
})();
|
|
"""
|
|
)
|
|
|
|
|
|
def _run(hidden):
|
|
with tempfile.NamedTemporaryFile("w", suffix=".js", delete=False) as f:
|
|
f.write(_DRIVER)
|
|
driver = f.name
|
|
out = subprocess.run(
|
|
[NODE, driver, str(REPO / "static" / "ui.js"), "hidden" if hidden else "visible"],
|
|
capture_output=True, text=True, timeout=30,
|
|
)
|
|
assert out.returncode == 0, out.stderr
|
|
import json
|
|
return json.loads(out.stdout.strip())
|
|
|
|
|
|
@requires_node
|
|
def test_hidden_tab_skips_unforced_poll_but_forced_still_runs():
|
|
r = _run(hidden=True)
|
|
# Only the forced call fetched; the unforced (interval) call was skipped.
|
|
assert r["fetches"] == 1, "hidden tab should skip the unforced poll"
|
|
|
|
|
|
@requires_node
|
|
def test_visible_tab_polls_normally():
|
|
r = _run(hidden=False)
|
|
# Both the unforced and forced calls fetched while visible.
|
|
assert r["fetches"] == 2, "visible tab should poll on both calls"
|