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

test/app-domains.test.ts: "an app gets its own domain" is green on a loaded runner and rejoins the gate #1167

Merged opened this

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

Merged

mason/forge:mason/1045-test-app-domains-test-ts-an-app-gets-its → main 1 commit fork 2 threads · 2 unresolved

  • Merged. mason/1045-test-app-domains-test-ts-an-app-gets-its was merged into main as eadbd2f.

Review

Sign in to review this change.
1 file changed +32 −14
test/app-domains.test.ts +32 −14
@@ -29,6 +29,7 @@ import { addDomain, getDomain, TOKEN_LENGTH } from "../src/core/domains.ts";
2929 import { listEvents } from "../src/core/events.ts";
3030 import type { Repo } from "../src/core/repos.ts";
3131 import { listRuns, type Run } from "../src/core/runs.ts";
32 import { readRunLogTail } from "../src/runs/log.ts";

Import is out of order: ../src/runs/log.ts sits between core/runs and core/tokens. Move it after the core/* imports.

3233 import { createToken } from "../src/core/tokens.ts";
3334 import { createUser, type User } from "../src/core/users.ts";
3435 import { serve, type Servers } from "../src/http/server.ts";
@@ -267,21 +268,35 @@ describe("an app gets its own domain", () => {
267268 return `${(response.headers.get("set-cookie") ?? "").split(";")[0]!}; forge_mode=dev`;
268269 };
269270
270 async function until<T>(read: () => T | undefined, ms = 60_000): Promise<T> {
271 /** A deploy run as the hook reports it: its state, summary and log tail. */
272 const said = (run: Run): string =>
273 [
274 `deploy ${run.id} is ${run.state}: ${run.summary || "(no summary)"}`,
275 ...readRunLogTail(dataDir, run.id, 20).lines,
276 ].join("\n");
277 /**
278 * The deploy's own end: the first matching run that is `ok` or `failed`.
279 * Out of time, it names where the latest matching run stood instead.
280 */
281 async function settled(
282 where: (run: Run) => boolean,
283 ms = 60_000,
284 ): Promise<Run> {
271285 const deadline = Date.now() + ms;
286 let latest: Run | undefined;
272287 while (Date.now() < deadline) {
273 const value = read();
274 if (value !== undefined) return value;
288 const runs = listRuns(app.db, repo.id, { kind: "deploy", limit: 50 });
289 const done = runs.find(
290 (r) => where(r) && (r.state === "ok" || r.state === "failed"),
291 );
292 if (done !== undefined) return done;
293 latest = runs.find(where);
275294 await Bun.sleep(100);
276295 }
277 throw new Error("did not happen in time");
278 }
279 const settled = (where: (run: Run) => boolean) =>
280 until(() =>
281 listRuns(app.db, repo.id, { kind: "deploy", limit: 50 }).find(
282 (r) => where(r) && (r.state === "ok" || r.state === "failed"),
283 ),
296 throw new Error(
297 `no deploy settled in ${ms} ms; ${latest === undefined ? "none was queued" : said(latest)}`,
284298 );
299 }
285300 const kinds = (prefix: string): string[] =>
286301 listEvents(app.db, { repoId: repo.id, limit: 100 })
287302 .map((e) => e.kind)
@@ -346,15 +361,18 @@ describe("an app gets its own domain", () => {
346361 if (!row.ok) throw new Error(row.error);
347362 other = row.value;
348363 const run = await settled((r) => r.env === "production");
364 // A failed deploy says why in the check's log, not only "failed".
365 if (run.state !== "ok") throw new Error(said(run));

The throw already guarantees ok, so the expect on the next line is redundant; drop it or drop the throw.

349366 expect(run.state).toBe("ok");
350367 expect((await viaHost(`notes.${DOMAIN}`)).status).toBe(200);
351368 }, 120_000);
352369
353370 afterAll(async () => {
354 await runtime.stop();
355 servers.stop();
356 app.close();
357 await rm(dataDir, { recursive: true, force: true });
371 // A setup that failed part-way leaves later handles unset: stop what started.
372 await runtime?.stop();
373 servers?.stop();
374 app?.close();
375 if (dataDir) await rm(dataDir, { recursive: true, force: true });
358376 });
359377
360378 test("what a domain may be: a hostname someone can own, and not the forge's", () => {

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs