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

One test seeds a clog (51 opened against 15 landed, six pulls on one file) and proves the governor and the hot-file hold prevent it #6537

Merged opened this

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

Merged

scout/forge:scout/6523-one-test-seeds-a-clog-51-opened-against → main 1 commit fork

  • Merged. scout/6523-one-test-seeds-a-clog-51-opened-against was merged into main as b48af75.

Review

Sign in to review this change.
1 file changed +73 −0
test/flow-clog-prevent.test.ts added +73
@@ -0,0 +1,73 @@
1 /**
2 * The seeded clog (#6523, part of #5930): 51 pulls opened against 15 landed in
3 * the last hour, and six open pulls on one file. The inflow governor lowers the
4 * builder slots and says why; the hot-file hold keeps a fresh build off that
5 * file while a build on another file may start. Vitals are plain data and the
6 * pulls' files are remembered, so no clock and no git.
7 */
8 import { afterAll, beforeAll, expect, test } from "bun:test";
9 import { mkdtemp, rm } from "node:fs/promises";
10 import { tmpdir } from "node:os";
11 import { join } from "node:path";
12 import { createApp, type App } from "../src/app.ts";
13 import { openIssue } from "../src/actions/issues.ts";
14 import { createRepo } from "../src/actions/repos.ts";
15 import { createUser, type User } from "../src/core/users.ts";
16 import type { Issue } from "../src/core/issues.ts";
17 import type { Repo } from "../src/core/repos.ts";
18 import { governedSlots } from "../src/crew/governor.ts";
19 import { heldNow } from "../src/crew/held.ts";
20 import { HOT_PULLS, rememberPullFiles } from "../src/crew/hot_files.ts";
21 import type { Vitals } from "../src/flow/vitals.ts";
22
23 let dataDir: string;
24 let app: App;
25 let alice: User;
26 let repo: Repo;
27
28 beforeAll(async () => {
29 dataDir = await mkdtemp(join(tmpdir(), "forge-clog-"));
30 app = createApp({ dataDir, port: 0 });
31 const a = await createUser(app.db, {
32 origin: "seed", trusted: true, username: "alice", email: "[email protected]",
33 password: "a-good-passphrase", adminIfFirst: true,
34 });
35 if (!a.ok) throw new Error(a.error);
36 alice = a.value;
37 const made = await createRepo(app, alice, { name: "engine" });
38 if (!made.ok) throw new Error(String(made.error));
39 repo = made.value;
40 });
41
42 afterAll(async () => {
43 rememberPullFiles(repo.id, []);
44 app.close();
45 await rm(dataDir, { recursive: true, force: true });
46 });
47
48 const open = (title: string): Issue => {
49 const r = openIssue(app, alice, repo, { title, body: "" });
50 if (!r.ok) throw new Error(String(r.error));
51 return r.value;
52 };
53
54 test("a seeded clog lowers the slots and holds a fresh build on the hot file", () => {
55 const clog: Vitals = { open: 8, opened1h: 51, landed1h: 15, opened6h: 120, landed6h: 40, conflicted: 0 };
56 const ceiling = 7;
57 const governed = governedSlots(clog, ceiling);
58 expect(governed.slots).toBeLessThan(ceiling);
59 expect(governed.slots).toBeGreaterThanOrEqual(1);
60 expect(governed.why).toContain("51 opened");
61 expect(governed.why).toContain("15 landed");
62
63 rememberPullFiles(
64 repo.id,
65 Array.from({ length: HOT_PULLS + 1 }, (_, i) => ({ number: i + 1, files: ["src/hot.ts", `src/own${i}.ts`] })),
66 );
67 const hot = open("Add a flag to src/hot.ts");
68 const cold = open("Tidy src/cold.ts");
69
70 const held = heldNow(app, repo);
71 expect(held.by.hot_file.map((i) => i.number)).toEqual([hot.number]);
72 expect(held.startable.map((r) => r.issue.number)).toEqual([cold.number]);
73 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs