Public: anyone can read this; the crew can change it.

A main check stopped by its cell's limit holds no pull's check #3121

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/3119-a-main-check-stopped-by-its-cell-s-limit → main 1 commit fork

  • Merged. scout/3119-a-main-check-stopped-by-its-cell-s-limit was merged into main as 908d3c5.

Review

Sign in to review this change.
2 files changed +28 −2
src/checks/red_main.ts +10 −2
@@ -29,6 +29,8 @@ export interface RedMain {
2929 /** The failing tests' names the check recorded, else its summary. */
3030 readonly failing: readonly string[];
3131 readonly summary: string;
32 /** The check was stopped by its cell's limit or its budget, not by a test: no pull shares it. */
33 readonly limit: boolean;
3234 readonly since: string;
3335 }
3436
@@ -78,6 +80,9 @@ const lastMain = (from: string): string => `
7880 AND r.state IN ('ok', 'failed')
7981 ORDER BY r.id DESC LIMIT 1)`;
8082
83 /** A summary of a cell stop (`apps/contain.ts`) or a budget kill (`kernel/budgets.ts`). */
84 const LIMIT = /^(?:check failed: )?(?:stopped: |budget:)/;
85
8186 function toRed(row: Row): RedMain | undefined {
8287 if (row.state !== "failed") return undefined;
8388 let failing: string[] = [];
@@ -95,6 +100,7 @@ function toRed(row: Row): RedMain | undefined {
95100 commitOid: row.commit_oid,
96101 failing,
97102 summary: row.summary,
103 limit: LIMIT.test(row.summary),
98104 since: row.finished_at ?? row.created_at,
99105 };
100106 }
@@ -108,6 +114,7 @@ export function heldByRed(
108114 ): boolean {
109115 return (
110116 red !== undefined &&
117 !red.limit &&
111118 run.kind === "check" &&
112119 run.issueId !== null &&
113120 run.reason !== ASKED &&
@@ -144,7 +151,8 @@ const HELD = `
144151
145152 /**
146153 * Each red main with pull checks waiting on it, and how many wait: one
147 * query. A check waiting past the hold is still counted until it runs.
154 * query. A check waiting past the hold is still counted until it runs. A main
155 * stopped by a limit holds nothing, so it has no card.
148156 */
149157 export function heldChecks(db: Database): { red: RedMain; held: number }[] {
150158 const rows = db
@@ -157,7 +165,7 @@ export function heldChecks(db: Database): { red: RedMain; held: number }[] {
157165 const out: { red: RedMain; held: number }[] = [];
158166 for (const row of rows) {
159167 const red = toRed(row);
160 if (red !== undefined) out.push({ red, held: row.n });
168 if (red !== undefined && !red.limit) out.push({ red, held: row.n });
161169 }
162170 return out;
163171 }
test/red-main.test.ts +18
@@ -65,6 +65,24 @@ describe("red main", () => {
6565 expect(unheld(queued(), red, HOLD).map((x) => x.id)).not.toContain(held.id);
6666 });
6767
68 test("a main stopped by its cell's limit or budget holds nothing, and a failed test still does", () => {
69 const stop = (summary: string) => {
70 const run = createRun(db, { repoId: "r1", kind: "check", env: "main", commitOid: OID("b"), reason: "push" });
71 claimRun(db, run.id);
72 finishRun(db, run.id, { state: "failed", summary });
73 };
74 const waiting = pullCheck("a");
75 stop("check failed: stopped: used 4105 MiB of memory, over its 4096 MiB limit");
76 expect(redMain(db, "r1")).toMatchObject({ limit: true, commitOid: OID("b") });
77 expect(unheld(queued(), red, HOLD).map((x) => x.id)).toContain(waiting.id);
78 expect(heldChecks(db)).toEqual([]);
79 stop("budget: check took 31 min, limit 30");
80 expect(unheld(queued(), red, HOLD).map((x) => x.id)).toContain(waiting.id);
81 main("c", "failed", ["x"]);
82 expect(redMain(db, "r1")!.limit).toBe(false);
83 expect(unheld(queued(), red, HOLD).map((x) => x.id)).not.toContain(waiting.id);
84 });
85
6886 test("a person's ask runs while main is red", () => {
6987 main("b", "failed", ["x"]);
7088 const asked = pullCheck("a", "asked");

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs