Public: anyone can read this; the crew can change it.
Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:19547qkh3k is past its budget: trevato/forge: "a walk that blows up half-way (outside any step) still removes its forge" failed on 3 pulls in the last… #12458
Check · Review · Land · Live done — Landed and live in production.
torque/forge:torque/12457-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 2 commits fork
1 file
changed +17
−0
test/release-journey.test.ts +17
| @@ -30,9 +30,15 @@ let dir = ""; | ||
| 30 | 30 | let parent: App; |
| 31 | 31 | let parentServers: Servers; |
| 32 | 32 | let adminToken = ""; |
| 33 | const stopped = new Set<unknown>(); | |
| 33 | 34 | const kids = new Map<string, { app: App; servers: Servers; crew: CrewHandle; dataDir: string }>(); |
| 34 | 35 | /** A step that answers 503, as `METHOD path` on the child. */ |
| 35 | 36 | let broken: string | undefined; |
| 37 | /** | |
| 38 | * When set, a child's stand-in process is stopped just before the parent is asked to remove it: | |
| 39 | * a real removal ends the process first, and a live stand-in would write its files back. | |
| 40 | */ | |
| 41 | let stopBeforeRemove = false; | |
| 36 | 42 | |
| 37 | 43 | beforeAll(async () => { |
| 38 | 44 | dir = await mkdtemp(join(tmpdir(), "forge-journey-")); |
| @@ -50,6 +56,7 @@ beforeAll(async () => { | ||
| 50 | 56 | |
| 51 | 57 | afterAll(async () => { |
| 52 | 58 | for (const k of kids.values()) { |
| 59 | if (stopped.has(k)) continue; | |
| 53 | 60 | await k.crew.stop(); |
| 54 | 61 | k.servers.stop(); |
| 55 | 62 | k.app.close(); |
| @@ -93,6 +100,14 @@ function routed(log: string[]): typeof fetch { | ||
| 93 | 100 | const url = new URL(input instanceof Request ? input.url : String(input)); |
| 94 | 101 | const name = /^([a-z0-9-]+)--forge\.test$/.exec(url.hostname)?.[1]; |
| 95 | 102 | if (name === undefined) { |
| 103 | const gone = stopBeforeRemove && init?.method === "POST" ? /^\/forges\/([a-z0-9-]+)\/remove$/.exec(url.pathname)?.[1] : undefined; | |
| 104 | const live = gone === undefined ? undefined : kids.get(gone); | |
| 105 | if (live !== undefined && !stopped.has(live)) { | |
| 106 | stopped.add(live); | |
| 107 | await live.crew.stop(); | |
| 108 | live.servers.stop(); | |
| 109 | live.app.close(); | |
| 110 | } | |
| 96 | 111 | // The parent believes it lives at forge.test: a browser there would send that origin. |
| 97 | 112 | const headers = new Headers(init?.headers); |
| 98 | 113 | if (headers.has("origin")) headers.set("origin", "https://forge.test"); |
| @@ -167,6 +182,7 @@ test("an address that is not http(s) is refused before anything is sent", async | ||
| 167 | 182 | }); |
| 168 | 183 | |
| 169 | 184 | test("a walk that blows up half-way (outside any step) still removes its forge", async () => { |
| 185 | stopBeforeRemove = true; | |
| 170 | 186 | let calls = 0; |
| 171 | 187 | const log: string[] = []; |
| 172 | 188 | const inner = routed(log); |
| @@ -176,6 +192,7 @@ test("a walk that blows up half-way (outside any step) still removes its forge", | ||
| 176 | 192 | return (calls += 1); |
| 177 | 193 | }; |
| 178 | 194 | const result = await walkJourney({ base: parentServers.url, fetch: inner, adminToken, now, sleep: () => Bun.sleep(100), pollMs: 100 }); // real-timer: the stand-in crew child runs in real time |
| 195 | stopBeforeRemove = false; | |
| 179 | 196 | // The walk does not reject: it says what stopped it, and cleans up all the same. |
| 180 | 197 | expect(result.ok).toBe(false); |
| 181 | 198 | expect(result.failure).toBe("the walk stopped unexpectedly"); |
new above
offline