Public: anyone can read this; the crew can change it.
Full suite red: test/snappy.test.ts #12263
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/12190-full-suite-red-test-snappy-test-ts → main 5 commits fork 2 threads · 2 unresolved
3 files
changed +34
−28
scripts/gate.ts +7 −1
| @@ -49,7 +49,13 @@ export const EXCLUDED: readonly Exclusion[] = []; | ||
| 49 | 49 | * whole gate and on the fast tier for a file the pull changed. Keep it |
| 50 | 50 | * short: an entry is a debt with an owner, not a home. |
| 51 | 51 | */ |
| 52 | export const SLOW: readonly Exclusion[] = []; | |
| 52 | export const SLOW: readonly Exclusion[] = [ | |
| 53 | { | |
| 54 | file: "test/snappy.test.ts", | |
| 55 | reason: "the cold home takes 20 timed requests at ~65 ms, each after a write, until its per-app reads are grouped", | |
| 56 | issue: 12310, | |
| 57 | }, | |
| 58 | ]; | |
| 53 | 59 | |
| 54 | 60 | /** Everything wrong with one list of named files, `list` its name in the lines. */ |
| 55 | 61 | function auditList(list: "EXCLUDED" | "SLOW", present: readonly string[], entries: readonly Exclusion[]): string[] { |
test/red-on-main.test.ts +3 −3
| @@ -8,7 +8,7 @@ import { describe, expect, test } from "bun:test"; | ||
| 8 | 8 | import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; |
| 9 | 9 | import { tmpdir } from "node:os"; |
| 10 | 10 | import { join } from "node:path"; |
| 11 | import { EXCLUDED } from "../scripts/gate.ts"; | |
| 11 | import { EXCLUDED, SLOW } from "../scripts/gate.ts"; | |
| 12 | 12 | import { askBase, baseVerdict, clearedIn, type OnBase } from "../src/checks/base_red.ts"; |
| 13 | 13 | |
| 14 | 14 | const BASE = "0123456789abcdef0123456789abcdef01234567"; |
| @@ -101,8 +101,8 @@ describe("the fast tier asks main", () => { | ||
| 101 | 101 | const dir = mkdtempSync(join(tmpdir(), "red-on-main-")); |
| 102 | 102 | try { |
| 103 | 103 | mkdirSync(join(dir, "test")); |
| 104 | // The gate refuses a tree its EXCLUDED list names files missing from; they never run. | |
| 105 | for (const { file } of EXCLUDED) writeFileSync(join(dir, file), pass); | |
| 104 | // The gate refuses a tree missing files EXCLUDED and SLOW name; they never run. | |
| 105 | for (const { file } of [...EXCLUDED, ...SLOW]) writeFileSync(join(dir, file), pass); | |
| 106 | 106 | writeFileSync(join(dir, RED), onMain); |
| 107 | 107 | writeFileSync(join(dir, "test/plain.test.ts"), pass); |
| 108 | 108 | writeFileSync(join(dir, "README.md"), "# scratch\n"); |
test/snappy.test.ts +24 −24
| @@ -28,7 +28,8 @@ const SQL = { mapOwner: 80, mapMember: 60, homeOwner: 220, homeMember: 180 }; | ||
| 28 | 28 | /** |
| 29 | 29 | * After a write every cache misses: what the grouped reads alone must hold. The home's was 260 |
| 30 | 30 | * until 2026-11-13: the lanes home reads its picture, its figures and the hosted forges on a cold |
| 31 | * view (306 here), and the held line reads one Later gate per app (12 here). | |
| 31 | * view, and the held line reads one Later gate per app (12 here). It measures 316 here; grouping the | |
| 32 | * per-app reads is #12310, which also brings this file out of SLOW. | |
| 32 | 33 | */ |
| 33 | 34 | const COLD_SQL = { mapOwner: 450, homeOwner: 330 }; |
| 34 | 35 | |
| @@ -44,29 +45,28 @@ afterAll(async () => { | ||
| 44 | 45 | }); |
| 45 | 46 | |
| 46 | 47 | describe("budgets", () => { |
| 47 | test("/map and / answer under their p95 and statement budgets", async () => { | |
| 48 | const owner = { cookie: f.ownerCookie }; | |
| 49 | const peer = { cookie: f.peerCookie }; | |
| 50 | let k = 0; | |
| 51 | const touch = () => | |
| 52 | f.app.db | |
| 53 | .query("UPDATE repo SET description = ?1 WHERE id = ?2") | |
| 54 | .run(`touched ${k++}`, f.repos[0]!.id); | |
| 55 | const rows = [ | |
| 56 | [await timeRoute(f, "map owner", "/map", owner, 20), SQL.mapOwner], | |
| 57 | [await timeRoute(f, "map member", "/map", peer, 20), SQL.mapMember], | |
| 58 | [await timeRoute(f, "home owner", "/", owner, 20), SQL.homeOwner], | |
| 59 | [await timeRoute(f, "home member", "/", peer, 20), SQL.homeMember], | |
| 60 | [await timeRoute(f, "home stranger", "/", {}, 20), 19], | |
| 61 | [await timeRoute(f, "map owner cold", "/map", owner, 20, touch), COLD_SQL.mapOwner], | |
| 62 | [await timeRoute(f, "home owner cold", "/", owner, 20, touch), COLD_SQL.homeOwner], | |
| 63 | ] as const; | |
| 64 | for (const [timing, sql] of rows) { | |
| 65 | expect({ name: timing.name, status: timing.status }).toEqual({ name: timing.name, status: 200 }); | |
| 66 | expect({ name: timing.name, ok: timing.p95 < P95_MS }).toEqual({ name: timing.name, ok: true }); | |
| 67 | expect({ name: timing.name, ok: timing.sql <= sql, sql: timing.sql }).toMatchObject({ name: timing.name, ok: true }); | |
| 68 | } | |
| 69 | }, 60_000); | |
| 48 | // One test per route, so each stays inside the 2 s test budget at 20 samples. | |
| 49 | let k = 0; | |
| 50 | const touch = () => | |
| 51 | f.app.db | |
| 52 | .query("UPDATE repo SET description = ?1 WHERE id = ?2") | |
| 53 | .run(`touched ${k++}`, f.repos[0]!.id); | |
| 54 | const within = (name: string, path: string, who: () => { cookie?: string }, sql: number, cold = false) => | |
| 55 | test(`${name} answers under its p95 and statement budget`, async () => { | |
| 56 | const timing = await timeRoute(f, name, path, who(), 20, cold ? touch : undefined); | |
| 57 | expect({ name, status: timing.status }).toEqual({ name, status: 200 }); | |
outdated
5 samples makes p95 equal the max, so one slow request fails the 250 ms assertion. Keep 20 and split the routes across tests, or use SLOW in scripts/gate.ts with an issue. |
||
| 58 | expect({ name, ok: timing.p95 < P95_MS }).toEqual({ name, ok: true }); | |
| 59 | expect({ name, ok: timing.sql <= sql, sql: timing.sql }).toMatchObject({ name, ok: true }); | |
| 60 | }, 30_000); | |
| 61 | const owner = () => ({ cookie: f.ownerCookie }); | |
| 62 | const peer = () => ({ cookie: f.peerCookie }); | |
| 63 | within("map owner", "/map", owner, SQL.mapOwner); | |
| 64 | within("map member", "/map", peer, SQL.mapMember); | |
| 65 | within("home owner", "/", owner, SQL.homeOwner); | |
| 66 | within("home member", "/", peer, SQL.homeMember); | |
| 67 | within("home stranger", "/", () => ({}), 19); | |
| 68 | within("map owner cold", "/map", owner, COLD_SQL.mapOwner, true); | |
| 69 | within("home owner cold", "/", owner, COLD_SQL.homeOwner, true); | |
| 70 | 70 | |
| 71 | 71 | test("the statement figure is the page's own: no telemetry flush, one outlier ignored", () => { |
| 72 | 72 | const db = new Database(":memory:"); |
new above
offline
Loosened 330 to 350 on a guess. Group the per-app reads, or keep 330 and link a filed issue for the grouping in the comment.