refactor(relay): add --smoke entrypoint

This commit is contained in:
Peter Steinberger
2026-01-07 03:12:30 +00:00
parent 59cc15f3cc
commit aa87d6cee8
4 changed files with 84 additions and 7 deletions

View File

@@ -255,7 +255,7 @@ if [[ "${SKIP_GATEWAY_PACKAGE:-0}" != "1" ]]; then
rm -rf "$RELAY_BUILD_DIR"
echo "🧪 Smoke testing bundled relay QR modules"
CLAWDBOT_SMOKE_QR=1 "$RELAY_OUT" >/dev/null
"$RELAY_OUT" --smoke qr >/dev/null
echo "🎨 Copying gateway A2UI host assets"
rm -rf "$RELAY_DIR/a2ui"

View File

@@ -0,0 +1,37 @@
import { describe, expect, it, vi } from "vitest";
import { parseRelaySmokeTest, runRelaySmokeTest } from "./relay-smoke.js";
vi.mock("../web/qr-image.js", () => ({
renderQrPngBase64: vi.fn(async () => "base64"),
}));
describe("parseRelaySmokeTest", () => {
it("parses --smoke qr", () => {
expect(parseRelaySmokeTest(["--smoke", "qr"], {})).toBe("qr");
});
it("parses --smoke-qr", () => {
expect(parseRelaySmokeTest(["--smoke-qr"], {})).toBe("qr");
});
it("parses env var smoke mode only when no args", () => {
expect(parseRelaySmokeTest([], { CLAWDBOT_SMOKE_QR: "1" })).toBe("qr");
expect(parseRelaySmokeTest(["send"], { CLAWDBOT_SMOKE_QR: "1" })).toBe(
null,
);
});
it("rejects unknown smoke values", () => {
expect(() => parseRelaySmokeTest(["--smoke", "nope"], {})).toThrow(
"Unknown smoke test",
);
});
});
describe("runRelaySmokeTest", () => {
it("runs qr smoke test", async () => {
await runRelaySmokeTest("qr");
const mod = await import("../web/qr-image.js");
expect(mod.renderQrPngBase64).toHaveBeenCalledWith("smoke-test");
});
});

39
src/macos/relay-smoke.ts Normal file
View File

@@ -0,0 +1,39 @@
export type RelaySmokeTest = "qr";
export function parseRelaySmokeTest(
args: string[],
env: NodeJS.ProcessEnv,
): RelaySmokeTest | null {
const smokeIdx = args.indexOf("--smoke");
if (smokeIdx !== -1) {
const value = args[smokeIdx + 1];
if (!value || value.startsWith("-")) {
throw new Error("Missing value for --smoke (expected: qr)");
}
if (value === "qr") return "qr";
throw new Error(`Unknown smoke test: ${value}`);
}
if (args.includes("--smoke-qr")) return "qr";
// Back-compat: only run env-based smoke mode when no CLI args are present,
// to avoid surprising early-exit when users set env vars globally.
if (
args.length === 0 &&
(env.CLAWDBOT_SMOKE_QR === "1" || env.CLAWDBOT_SMOKE === "qr")
) {
return "qr";
}
return null;
}
export async function runRelaySmokeTest(test: RelaySmokeTest): Promise<void> {
switch (test) {
case "qr": {
const { renderQrPngBase64 } = await import("../web/qr-image.js");
await renderQrPngBase64("smoke-test");
return;
}
}
}

View File

@@ -32,15 +32,16 @@ async function main() {
process.exit(0);
}
// Smoke test for QR modules in bun-compiled binaries.
// Verifies that QR code generation works in the bundled relay.
if (process.env.CLAWDBOT_SMOKE_QR === "1" && args.length === 0) {
const { parseRelaySmokeTest, runRelaySmokeTest } = await import(
"./relay-smoke.js"
);
const smokeTest = parseRelaySmokeTest(args, process.env);
if (smokeTest) {
try {
const { renderQrPngBase64 } = await import("../web/qr-image.js");
await renderQrPngBase64("smoke-test");
await runRelaySmokeTest(smokeTest);
process.exit(0);
} catch (err) {
console.error("QR smoke test failed:", err);
console.error(`Relay smoke test failed (${smokeTest}):`, err);
process.exit(1);
}
}