Public: anyone can read this; the crew can change it.
"anonymous spawn > a signed-in spawn still works (regression)" passes every time on a loaded check machine #5233
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/5209-anonymous-spawn-a-signed-in-spawn-still → main 2 commits fork
1 file
changed +22
−0
test/spawn-anon.test.ts +22
| @@ -17,6 +17,7 @@ import { createToken } from "../src/core/tokens.ts"; | ||
| 17 | 17 | import { createUser } from "../src/core/users.ts"; |
| 18 | 18 | import { serve, type Servers } from "../src/http/server.ts"; |
| 19 | 19 | import { childDirOf } from "../src/actions/spawn.ts"; |
| 20 | import { bootHostedChild } from "../src/spawn/host.ts"; | |
| 20 | 21 | import { ok } from "../src/kernel/result.ts"; |
| 21 | 22 | |
| 22 | 23 | describe("anonymous spawn", () => { |
| @@ -36,6 +37,18 @@ describe("anonymous spawn", () => { | ||
| 36 | 37 | }, |
| 37 | 38 | body: JSON.stringify(payload), |
| 38 | 39 | }); |
| 40 | // A spawn boots its child in the background (`void bootHostedChild`). Wait | |
| 41 | // for each boot once, so it neither competes with the next test for the | |
| 42 | // machine nor outlives the data directory. Only the first call per child | |
| 43 | // joins the boot in flight; a later one would start the child's apps again. | |
| 44 | const settled = new Set<string>(); | |
| 45 | const settle = async (...names: string[]) => { | |
| 46 | for (const name of names) { | |
| 47 | if (settled.has(name)) continue; | |
| 48 | settled.add(name); | |
| 49 | await bootHostedChild(app, name); | |
| 50 | } | |
| 51 | }; | |
| 39 | 52 | const getPage = () => fetch(`${base}/forges/new`); |
| 40 | 53 | |
| 41 | 54 | beforeAll(async () => { |
| @@ -78,6 +91,9 @@ describe("anonymous spawn", () => { | ||
| 78 | 91 | }, 30_000); |
| 79 | 92 | |
| 80 | 93 | afterAll(async () => { |
| 94 | // Before the servers stop: stopping empties the child cache, and a | |
| 95 | // boot started after that would open a child nothing closes. | |
| 96 | await settle("kid", "kid2", "kid3", "grown"); | |
| 81 | 97 | servers.stop(); |
| 82 | 98 | app.close(); |
| 83 | 99 | await rm(dataDir, { recursive: true, force: true }); |
| @@ -127,6 +143,9 @@ describe("anonymous spawn", () => { | ||
| 127 | 143 | expect(body.dryRun).toBe(false); |
| 128 | 144 | expect(typeof body.claimUrl).toBe("string"); |
| 129 | 145 | |
| 146 | // Let its background boot finish before this test opens the same | |
| 147 | // directory (the two share the repo's git readers). | |
| 148 | await settle("kid"); | |
| 130 | 149 | // The child's forge-code fork: the repo, its history, and the upstream. |
| 131 | 150 | const { createApp: openChild } = await import("../src/app.ts"); |
| 132 | 151 | const child = openChild({ dataDir: childDirOf(app, body.bodyId) }); |
| @@ -186,11 +205,14 @@ describe("anonymous spawn", () => { | ||
| 186 | 205 | }); |
| 187 | 206 | |
| 188 | 207 | test("a signed-in spawn still works (regression)", async () => { |
| 208 | // The anonymous children above are still booting; let them finish. | |
| 209 | await settle("kid", "kid2", "kid3"); | |
| 189 | 210 | const res = await post({ name: "grown", apps: ["alice/notes"], dryRun: false }, rw); |
| 190 | 211 | expect(res.status).toBe(201); |
| 191 | 212 | const body = (await res.json()) as any; |
| 192 | 213 | expect(typeof body.claimUrl).toBe("string"); |
| 193 | 214 | // The signed-in child forks the code too. |
| 215 | await settle("grown"); | |
| 194 | 216 | const { createApp: openChild } = await import("../src/app.ts"); |
| 195 | 217 | const child = openChild({ dataDir: childDirOf(app, body.bodyId) }); |
| 196 | 218 | try { |
new above
offline