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

test/studio.test.ts: a pull's preview case waits for the deploy it reads, and the file rejoins the gate #1165

Merged opened this

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

Merged

scout/forge:scout/1044-test-studio-test-ts-a-pull-s-preview-cas → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/1044-test-studio-test-ts-a-pull-s-preview-cas was merged into main as a97eaf6.

Review

Sign in to review this change.
1 file changed +42 −8
test/studio.test.ts +42 −8
@@ -51,6 +51,7 @@ import {
5151 createRun,
5252 finishRun,
5353 getRun,
54 isTerminal,
5455 listRuns,
5556 markServing,
5657 noteRunProgress,
@@ -2540,6 +2541,41 @@ describe("every open pull's preview on the studio page", () => {
25402541 redirect: "manual",
25412542 });
25422543
2544 const WAIT_MS = 60_000;

WAIT_MS is 60 s while the case timeouts are 120 s. That leaves room for both waits plus the assertions, so it is fine. Say so in a short comment so nobody lowers the timeout below 2x.

2545
2546 /** The deploys this repo has not finished, as "env:state" words. */
2547 const unfinished = () =>
2548 listRuns(app.db, repo.id, { kind: "deploy", limit: 50 })
2549 .filter((r) => !isTerminal(r.state))
2550 .map((r) => `${r.env}:${r.state}`);
2551
2552 /** Wait until the runtime has no deploy open or queued, so the next case
2553 * does not queue behind this one's (concurrency is 1). */
2554 async function deploysIdle(): Promise<void> {
2555 const deadline = Date.now() + WAIT_MS;
2556 while (unfinished().length > 0) {
2557 if (Date.now() > deadline)
2558 throw new Error(`deploys still open: ${unfinished().join(", ")}`);
2559 await Bun.sleep(50);
2560 }
2561 }
2562
2563 /** Wait for `env` to serve; fail naming the state it reached. */
2564 async function previewServes(record: AppRecord, env: EnvName): Promise<void> {
2565 const deadline = Date.now() + WAIT_MS;
2566 while (runtime.envStatus(record, env)?.state !== "running") {
2567 if (Date.now() > deadline) {
2568 const status = runtime.envStatus(record, env);
2569 throw new Error(
2570 `${env} did not serve within ${WAIT_MS} ms: state ${status?.state ?? "absent"}` +
2571 (status?.error ? ` (${status.error})` : "") +
2572 `; open deploys: ${unfinished().join(", ") || "none"}`,
2573 );
2574 }
2575 await Bun.sleep(50);
2576 }
2577 }
2578
25432579 beforeAll(async () => {
25442580 dataDir = await mkdtemp(join(tmpdir(), "forge-studio-previews-"));
25452581 app = createApp({ dataDir, port: 0 });
@@ -2637,7 +2673,10 @@ describe("every open pull's preview on the studio page", () => {
26372673 const after = await (await get("/alice/widget")).text();
26382674 expect(after).not.toContain("<h2>Previews</h2>");
26392675 expect(after).not.toContain(`pull-${pull.number}/open`);
2640 }, 30_000);
2676 // The merge queues production's deploy and the pull's was cut short;
2677 // leave the single deploy slot free for the next case.
2678 await deploysIdle();
2679 }, 120_000);
26412680
26422681 test("a change's page names its preview's data as its own copy and gives the moment it was taken; production's card does not", async () => {
26432682 const alice = getUserByName(app.db, "alice")!;
@@ -2659,12 +2698,7 @@ describe("every open pull's preview on the studio page", () => {
26592698 const record = getAppByRepo(app.db, repo.id)!;
26602699 const env = `pull-${pull.number}` as const;
26612700
2662 const deadline = Date.now() + 30_000;
2663 while (
2664 Date.now() < deadline &&
2665 runtime.envStatus(record, env)?.state !== "running"
2666 )
2667 await Bun.sleep(100);
2701 await previewServes(record, env);
26682702 expect(runtime.envStatus(record, env)?.state).toBe("running");
26692703
26702704 const note = "its own copy of production's data, taken";
@@ -2680,7 +2714,7 @@ describe("every open pull's preview on the studio page", () => {
26802714 ).text();
26812715 expect(changePage).toContain("<h2>Preview</h2>");
26822716 expect(changePage).toContain(note);
2683 }, 30_000);
2717 }, 120_000);
26842718 });
26852719
26862720 /**

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs