Initial commit

This commit is contained in:
Samraaj Bath
2026-06-29 15:11:48 -07:00
commit 66dfdcc58d
404 changed files with 45970 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
{
"name": "@cloner/test-utils",
"version": "0.1.0",
"private": true,
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"tsx": "4.22.4",
"typescript": "5.7.3",
"@types/node": "22.10.5"
}
}
+87
View File
@@ -0,0 +1,87 @@
import { createServer, type Server } from "node:http";
import { readFileSync, existsSync, statSync, readdirSync } from "node:fs";
import { join, extname, normalize, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { homedir } from "node:os";
export { startEphemeralPostgres, canRunEphemeralPostgres, type EphemeralPg } from "./postgres.js";
import { startEphemeralPostgres, canRunEphemeralPostgres, type EphemeralPg } from "./postgres.js";
/** A Postgres available to tests: TEST_DATABASE_URL if set (e.g. a CI service),
* else a throwaway local instance when we can run one. Sync check for skip. */
export function hasTestPostgres(): boolean {
return !!process.env.TEST_DATABASE_URL || canRunEphemeralPostgres();
}
/** Acquire a test Postgres (env URL or ephemeral). Returns null if none available. */
export async function acquireTestPostgres(): Promise<EphemeralPg | null> {
if (process.env.TEST_DATABASE_URL) return { url: process.env.TEST_DATABASE_URL, stop: async () => {} };
if (canRunEphemeralPostgres()) return startEphemeralPostgres();
return null;
}
const HERE = dirname(fileURLToPath(import.meta.url));
/** repo root = packages/test-utils/src → ../../.. */
export const REPO_ROOT = join(HERE, "..", "..", "..");
export const FIXTURES_DIR = join(REPO_ROOT, "compiler", "fixtures");
const TYPES: Record<string, string> = {
".html": "text/html; charset=utf-8",
".css": "text/css",
".js": "text/javascript",
".mjs": "text/javascript",
".json": "application/json",
".webmanifest": "application/manifest+json",
".xml": "application/xml",
".png": "image/png",
".ico": "image/x-icon",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".svg": "image/svg+xml",
".webp": "image/webp",
".gif": "image/gif",
".woff2": "font/woff2",
".woff": "font/woff",
};
/** Serve a directory of fixtures over loopback (zero external network). */
export function serveDir(rootDir: string): Promise<{ url: string; close: () => Promise<void> }> {
const server: Server = createServer((req, res) => {
try {
let p = decodeURIComponent((req.url || "/").split("?")[0]!);
if (p === "/") p = "/index.html";
const file = join(rootDir, normalize(p).replace(/^(\.\.[/\\])+/, ""));
if (!existsSync(file) || statSync(file).isDirectory()) {
res.writeHead(404);
res.end("not found");
return;
}
res.writeHead(200, { "content-type": TYPES[extname(file).toLowerCase()] ?? "application/octet-stream" });
res.end(readFileSync(file));
} catch {
res.writeHead(500);
res.end("error");
}
});
return new Promise((resolve) => {
server.listen(0, "127.0.0.1", () => {
const addr = server.address();
const port = typeof addr === "object" && addr ? addr.port : 0;
resolve({
url: `http://127.0.0.1:${port}`,
close: () => new Promise<void>((r) => server.close(() => r())),
});
});
});
}
/** Whether a Playwright Chromium browser appears installed (browser tests skip if not). */
export function hasChromium(): boolean {
try {
const base = process.env.PLAYWRIGHT_BROWSERS_PATH || join(homedir(), ".cache", "ms-playwright");
if (!existsSync(base)) return false;
return readdirSync(base).some((d) => d.startsWith("chromium"));
} catch {
return false;
}
}
+97
View File
@@ -0,0 +1,97 @@
import { spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, existsSync, readdirSync, chmodSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { createServer } from "node:net";
export type EphemeralPg = { url: string; stop: () => Promise<void> };
/** Locate the newest installed PostgreSQL bin dir (e.g. /usr/lib/postgresql/16/bin). */
function findPgBin(): string | null {
if (process.env.PG_BIN && existsSync(join(process.env.PG_BIN, "initdb"))) return process.env.PG_BIN;
const root = "/usr/lib/postgresql";
if (!existsSync(root)) return null;
const versions = readdirSync(root)
.filter((d) => /^\d+$/.test(d))
.sort((a, b) => Number(b) - Number(a));
for (const v of versions) {
const bin = join(root, v, "bin");
if (existsSync(join(bin, "initdb"))) return bin;
}
return null;
}
/** Whether we can stand up a throwaway Postgres here: root (to su to a non-root
* user, since postgres refuses to run as root) + the binaries present. */
export function canRunEphemeralPostgres(): boolean {
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
return isRoot && findPgBin() !== null;
}
function freePort(): Promise<number> {
return new Promise((resolve, reject) => {
const srv = createServer();
srv.listen(0, "127.0.0.1", () => {
const addr = srv.address();
const port = typeof addr === "object" && addr ? addr.port : 0;
srv.close(() => resolve(port));
});
srv.on("error", reject);
});
}
function sh(cmd: string): { ok: boolean; out: string } {
const r = spawnSync("bash", ["-lc", cmd], { encoding: "utf8" });
return { ok: r.status === 0, out: (r.stdout || "") + (r.stderr || "") };
}
/**
* Start a throwaway PostgreSQL instance for tests (no Docker required). initdb's a
* temp data dir, runs the server as a non-root user (`pgtest`) on a random loopback
* port with trust auth, and returns a connection URL + a stop()/cleanup. Use only
* after `canRunEphemeralPostgres()` returns true.
*/
export async function startEphemeralPostgres(): Promise<EphemeralPg> {
const pgbin = findPgBin();
if (!pgbin) throw new Error("no postgres binaries found");
const user = "pgtest";
// Ensure the non-root runner exists.
if (!sh(`id ${user}`).ok) {
const r = sh(`useradd -m -s /bin/bash ${user}`);
if (!sh(`id ${user}`).ok) throw new Error("could not create pgtest user: " + r.out);
}
const data = mkdtempSync(join(tmpdir(), "pgdata-"));
const sock = mkdtempSync(join(tmpdir(), "pgsock-"));
// The runner user must own the data + socket dirs.
chmodSync(data, 0o777);
chmodSync(sock, 0o777);
sh(`chown -R ${user} ${data} ${sock}`);
const init = sh(`su ${user} -c "${pgbin}/initdb -D ${data} -A trust -U postgres --no-sync"`);
if (!init.ok) {
rmSync(data, { recursive: true, force: true });
rmSync(sock, { recursive: true, force: true });
throw new Error("initdb failed: " + init.out.slice(-500));
}
const port = await freePort();
const start = sh(
`su ${user} -c "${pgbin}/pg_ctl -D ${data} -o '-p ${port} -k ${sock} -c listen_addresses=127.0.0.1' -w -l ${data}/server.log start"`,
);
if (!start.ok) {
const log = sh(`cat ${data}/server.log`).out;
rmSync(data, { recursive: true, force: true });
rmSync(sock, { recursive: true, force: true });
throw new Error("pg_ctl start failed: " + start.out + "\n" + log.slice(-500));
}
const url = `postgresql://postgres@127.0.0.1:${port}/postgres`;
const stop = async (): Promise<void> => {
sh(`su ${user} -c "${pgbin}/pg_ctl -D ${data} -w -m immediate stop"`);
rmSync(data, { recursive: true, force: true });
rmSync(sock, { recursive: true, force: true });
};
return { url, stop };
}
+7
View File
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node"]
},
"include": ["src/**/*.ts"]
}