Skip to content

Commit b20d15a

Browse files
🐛 Fix cache-test nightly wall-clock timeout (#15936)
Fixes #15933 Raises timeout from 600s to 900s; returns empty SSE for skipped routes to avoid EventSource MIME errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ef7c92a commit b20d15a

2 files changed

Lines changed: 29 additions & 10 deletions

File tree

scripts/run-all-tests.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,10 @@ if [ -z "$FAST_MODE" ]; then
315315
# #8984 ui-compliance-test: renders every registered card type; total
316316
# card count keeps growing as we add cards.
317317
# #8985 cache-test: renders all cards via the same compliance harness.
318+
# #15933 cache-test: nightly now exercises 347 cards across 15 batches;
319+
# 600s was enough to generate the report but not enough to let the
320+
# suite exit cleanly, so the harness killed it after success metrics
321+
# had already been logged. Raise the wall-clock cap to 900s.
318322
# #8986 benchmark-test: 12 tests × up to 60s each ≈ 720s worst case.
319323
# #8987 ai-ml-test: 15 tests × up to 300s each in pathological cases.
320324
# #9098 nav-test: 6 serial scenarios (warmup/cold/warm/from-main/
@@ -334,7 +338,7 @@ if [ -z "$FAST_MODE" ]; then
334338
declare -A PLAYWRIGHT_SUITE_TIMEOUT_OVERRIDES=(
335339
["console-error-scan"]=600
336340
["ui-compliance-test"]=600
337-
["cache-test"]=600
341+
["cache-test"]=900
338342
["benchmark-test"]=600
339343
# deploy-test: npm run build (~2m) + vite preview start (up to 3m) + 11 tests
340344
# running serially with 6-minute per-test timeout. Default 300s cap kills

web/e2e/compliance/card-cache-compliance.spec.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { test, expect, type Page } from '@playwright/test'
1+
import { test, expect, type Page, type Route } from '@playwright/test'
22
import * as fs from 'fs'
33
import * as path from 'path'
44
import { fileURLToPath } from 'url'
@@ -135,10 +135,13 @@ const EVALUATE_RETRY_DELAY_MS = 500
135135
*/
136136
const BATCH_NAV_TIMEOUT_MS = process.env.CI ? 90_000 : 45_000
137137
/**
138-
* Overall test timeout (ms). 300s base × 2 CI multiplier = 600s, matching
139-
* the suite wall-clock cap in run-all-tests.sh (#9101).
138+
* Overall test timeout (ms). The cache suite now covers 347 cards across 15
139+
* batches, so the previous 600s CI cap was too tight: the report finished
140+
* writing, then run-all-tests.sh killed the suite at the wall-clock limit.
141+
* 450s base × 2 CI multiplier = 900s to leave headroom for nightly runner
142+
* jitter without relaxing the cache assertions themselves (#15933).
140143
*/
141-
const CACHE_TEST_TIMEOUT_MS = 300_000
144+
const CACHE_TEST_TIMEOUT_MS = 450_000
142145
const CI_TIMEOUT_MULTIPLIER = 2
143146
/**
144147
* Maximum acceptable median warm time-to-content (ms).
@@ -162,6 +165,7 @@ const STORAGE_CLEANUP_TIMEOUT_MS = 5_000
162165
const STORAGE_CLEANUP_POLL_INTERVAL_MS = 100
163166
const STORAGE_CLEANUP_POLL_ATTEMPTS = 20
164167
const COLD_BATCH_RESET_WINDOW_NAME = '__kc-cache-test-cold-reset__'
168+
const EMPTY_SSE_BODY = ': keep-alive\n\n'
165169
const COLD_BATCH_KEEP_LOCAL_STORAGE_KEYS = [
166170
'token',
167171
'kc-demo-mode',
@@ -696,13 +700,24 @@ function writeReport(report: CacheComplianceReport, outDir: string) {
696700
// Main test
697701
// ---------------------------------------------------------------------------
698702

703+
function fulfillSkippedRoute(route: Route) {
704+
const acceptHeader = route.request().headers().accept || ''
705+
const isStreamRequest = route.request().url().includes('/stream') || acceptHeader.includes('text/event-stream')
706+
707+
return route.fulfill({
708+
status: 200,
709+
contentType: isStreamRequest ? 'text/event-stream' : 'application/json',
710+
body: isStreamRequest ? EMPTY_SSE_BODY : '{}',
711+
})
712+
}
713+
699714
test.describe.configure({ mode: 'serial' })
700715

701716
test('card cache compliance — storage and retrieval', async ({ page }, testInfo) => {
702-
// 300s base × 2 CI multiplier = 600s, matching the suite wall-clock cap in
703-
// run-all-tests.sh. No testInfo.setTimeout was set before (#9101), so the
704-
// test ran against the global config timeout (1200s) which meant timeout
705-
// errors only surfaced as wall-clock kills.
717+
// 450s base × 2 CI multiplier = 900s, aligned with run-all-tests.sh. The
718+
// suite now renders 347 cards across 15 batches, so the old 600s ceiling
719+
// could kill the run after report generation even when cache assertions
720+
// already passed (#15933).
706721
testInfo.setTimeout(process.env.CI ? CACHE_TEST_TIMEOUT_MS * CI_TIMEOUT_MULTIPLIER : CACHE_TEST_TIMEOUT_MS)
707722

708723
const allBatchResults: Array<{ batchIndex: number; cards: CardCacheResult[] }> = []
@@ -730,7 +745,7 @@ test('card cache compliance — storage and retrieval', async ({ page }, testInf
730745
'**/api/self-upgrade/**', '**/api/admin/**', '**/api/acmm/**',
731746
]
732747
for (const pattern of skipRoutePatterns) {
733-
await page.route(pattern, (route) => route.fulfill({ status: 200, contentType: 'application/json', body: '{}' }))
748+
await page.route(pattern, fulfillSkippedRoute)
734749
}
735750

736751
await setLiveColdMode(page)

0 commit comments

Comments
 (0)