testBuildDuringStart

tcmts.cli.test.e2e.prod.testBuildDuringStart · #cyv5z227 · term

A build of the app tcm start serves, while it serves it (two at once, each replacing it), doesn't break serving: it reads the build before or the one after, whole; and pruning leaves the build it serves

import { plainEnv, tcmBin, tcmInBackground, withChildren } from "#codebase/tcmts/cli/test/e2e/harness";
import { get, loadTab, setUp, waitFor } from "#codebase/tcmts/cli/test/e2e/prod";
import assert from "node:assert/strict";
import { spawn } from "node:child_process";

export const testBuildDuringStart = () =>
  withChildren(async (keep) => {
    const { dir, tcm, scratch } = setUp();
    scratch(`// tcm: namespace app
export async function greeting(name: string): Promise<string> { return "hello " + name + " from " + process.pid; }
export async function main() { document.querySelector("#app")!.textContent = await greeting("ada"); }
`);
    tcm("add");
    tcm("build", "app.main");
    const child = keep(
      spawn(process.execPath, [tcmBin(), "start", "app.main", "--port", "0"], {
        cwd: dir,
        env: plainEnv(),
      }),
    );
    let out = "";
    child.stdout!.setEncoding("utf8").on("data", (d: string) => (out += d));
    child.stderr!.setEncoding("utf8").on("data", (d: string) => (out += d));
    await waitFor(() => /url\s+http:\/\/\S+/.test(out));
    const url = /url\s+(http:\/\/\S+)/.exec(out)![1]!;

    let building = true;
    const pages: number[] = [];
    const reading = (async () => {
      while (building) pages.push((await get(url)).status);
    })();
    const made = await Promise.all(
      [1, 2].map(() => tcmInBackground(keep, dir, "build", "app.main", "--force")),
    );
    building = false;
    await reading;
    for (const m of made) assert.equal(m.status, 0, m.out);
    assert.ok(pages.length > 0);
    assert.deepEqual([...new Set(pages)], [200], `pages: ${pages.join(" ")}\n${out}`);
    const tab = await loadTab(url);
    assert.equal((await get(new URL(tab.asset, url))).status, 200);

    tcm("apps", "prune", "--keep", "0");
    assert.equal((await get(url)).status, 200, "the build it serves stays");
    assert.equal((await get(new URL(tab.asset, url))).status, 200, "and its assets");
  })

uses