62 lines
3.2 KiB
JavaScript
62 lines
3.2 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { createServer } from "node:http";
|
|
import { readFile } from "node:fs/promises";
|
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
import { spawn } from "node:child_process";
|
|
import { tmpdir } from "node:os";
|
|
import { dirname, join, normalize, sep } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
const appRoot = join(root, "app");
|
|
const webRoot = root;
|
|
|
|
function serve() {
|
|
return createServer(async (request, response) => {
|
|
const requested = decodeURIComponent((request.url ?? "/").split("?")[0]);
|
|
const relative = requested === "/" ? "/app/browser-opfs-probe.html" : requested;
|
|
const file = normalize(join(webRoot, relative));
|
|
if (!file.startsWith(webRoot + sep)) { response.writeHead(403); response.end(); return; }
|
|
try {
|
|
const body = await readFile(file);
|
|
response.writeHead(200, { "content-type": file.endsWith(".html") ? "text/html" : "text/javascript", "cache-control": "no-store" });
|
|
response.end(body);
|
|
} catch {
|
|
response.writeHead(404); response.end();
|
|
}
|
|
});
|
|
}
|
|
|
|
function runChrome(url, profile) {
|
|
return new Promise((resolve) => {
|
|
const command = process.env.CHROME_BIN ?? "google-chrome";
|
|
const args = ["--headless=new", "--no-sandbox", "--disable-gpu", "--disable-dev-shm-usage", "--disable-background-networking", "--user-data-dir=" + profile, "--virtual-time-budget=5000", "--dump-dom", url];
|
|
const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
let stdout = ""; let stderr = "";
|
|
child.stdout.on("data", (chunk) => { stdout += chunk; });
|
|
child.stderr.on("data", (chunk) => { stderr += chunk; });
|
|
const timer = setTimeout(() => child.kill("SIGKILL"), 15000);
|
|
child.on("close", (code, signal) => { clearTimeout(timer); resolve({ code, signal, stdout, stderr }); });
|
|
child.on("error", (error) => { clearTimeout(timer); resolve({ code: null, signal: null, stdout, stderr, error: error.message }); });
|
|
});
|
|
}
|
|
|
|
const server = serve();
|
|
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
|
const port = server.address().port;
|
|
const profile = await mkdtemp(join(tmpdir(), "linuxcnc-opfs-s6-05-"));
|
|
const first = await runChrome(`http://127.0.0.1:${port}/app/browser-opfs-probe.html`, profile);
|
|
server.close();
|
|
await rm(profile, { recursive: true, force: true });
|
|
|
|
const match = first.stdout.match(/<output id="result">([^<]*)<\/output>/);
|
|
if (first.code !== 0 || !match || match[1] === "pending") {
|
|
console.log(JSON.stringify({ schema: "browser-opfs-s6-05-sample.v1", status: "blocked", browser: "chromium", code: first.error ? "browser_unavailable" : "opfs_worker_timeout", stage: null }));
|
|
} else {
|
|
const result = JSON.parse(match[1]);
|
|
assert.equal(result.schema, "opfs-runtime.v1", JSON.stringify({ result, stderr: first.stderr }));
|
|
assert.equal(result.status, "blocked", JSON.stringify({ result, stderr: first.stderr.slice(-500) }));
|
|
assert.ok(["opfs_probe_timeout", "opfs_worker_timeout", "opfs_sync_access_handle_missing", "opfs_probe_failed"].includes(result.code));
|
|
console.log(JSON.stringify({ schema: "browser-opfs-s6-05-sample.v1", status: "blocked", browser: "chromium", code: result.code, stage: result.stage ?? null }));
|
|
}
|