mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix(qa): accept testbox smoke lease ids
This commit is contained in:
@@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai
|
||||
- QA/Mantis: add `pnpm openclaw qa mantis slack-desktop-smoke` to run Slack live QA inside a Crabbox VNC desktop, open Slack Web, and capture desktop screenshots beside the Slack QA artifacts.
|
||||
- QA/Mantis: pass the runtime env through desktop-browser Crabbox and artifact-copy child commands, so embedded Mantis callers can provide Crabbox credentials without mutating the parent process. Thanks @vincentkoc.
|
||||
- QA/Mantis: return the copied Slack desktop screenshot path even when remote Slack QA fails, so the CLI still prints the failure screenshot artifact. Thanks @vincentkoc.
|
||||
- QA/Mantis: accept Blacksmith Testbox `tbx_...` lease ids from desktop smoke warmup, so provider overrides do not fail before inspect/run. Thanks @vincentkoc.
|
||||
- QA/Slack: add a Slack live transport QA runner with canary and mention-gating coverage for the private bot-to-bot harness. Thanks @vincentkoc.
|
||||
- Gateway/performance: lazy-load the heavy cron runtime after the rest of Gateway startup, defer restart-sentinel refresh after readiness, and let the Gateway startup benchmark write per-run V8 CPU profiles with `--cpu-prof-dir`.
|
||||
- Gateway/performance: keep raw channel-config schema parsing from discovering bundled plugin runtime metadata, and add `pnpm gateway:watch --benchmark-no-force` for profiling startup without the default port cleanup.
|
||||
|
||||
@@ -129,6 +129,64 @@ describe("mantis desktop browser smoke runtime", () => {
|
||||
expect(runner).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("accepts Blacksmith Testbox lease ids from Crabbox warmup", async () => {
|
||||
const commands: { args: readonly string[]; command: string }[] = [];
|
||||
const runner = vi.fn(async (command: string, args: readonly string[]) => {
|
||||
commands.push({ command, args });
|
||||
if (command === "/tmp/crabbox" && args[0] === "warmup") {
|
||||
return { stdout: "ready: tbx_abc-123_more\n", stderr: "" };
|
||||
}
|
||||
if (command === "/tmp/crabbox" && args[0] === "inspect") {
|
||||
return {
|
||||
stdout: `${JSON.stringify({
|
||||
host: "203.0.113.10",
|
||||
id: "tbx_abc-123_more",
|
||||
provider: "blacksmith-testbox",
|
||||
sshKey: "/tmp/key",
|
||||
sshPort: "2222",
|
||||
sshUser: "crabbox",
|
||||
state: "active",
|
||||
})}\n`,
|
||||
stderr: "",
|
||||
};
|
||||
}
|
||||
if (command === "rsync") {
|
||||
const outputDir = args.at(-1);
|
||||
await fs.mkdir(outputDir as string, { recursive: true });
|
||||
await fs.writeFile(path.join(outputDir as string, "desktop-browser-smoke.png"), "png");
|
||||
await fs.writeFile(path.join(outputDir as string, "remote-metadata.json"), "{}\n");
|
||||
await fs.writeFile(path.join(outputDir as string, "chrome.log"), "chrome\n");
|
||||
}
|
||||
return { stdout: "", stderr: "" };
|
||||
});
|
||||
|
||||
const result = await runMantisDesktopBrowserSmoke({
|
||||
commandRunner: runner,
|
||||
crabboxBin: "/tmp/crabbox",
|
||||
now: () => new Date("2026-05-04T12:30:00.000Z"),
|
||||
outputDir: ".artifacts/qa-e2e/mantis/desktop-browser-testbox",
|
||||
provider: "blacksmith-testbox",
|
||||
repoRoot,
|
||||
});
|
||||
|
||||
expect(result.status).toBe("pass");
|
||||
expect(commands).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
args: expect.arrayContaining(["--id", "tbx_abc-123_more"]),
|
||||
command: "/tmp/crabbox",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
const summary = JSON.parse(await fs.readFile(result.summaryPath, "utf8")) as {
|
||||
crabbox: { id: string; provider: string };
|
||||
};
|
||||
expect(summary.crabbox).toMatchObject({
|
||||
id: "tbx_abc-123_more",
|
||||
provider: "blacksmith-testbox",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps an existing lease and writes failure reports when the remote run fails", async () => {
|
||||
const commands: { args: readonly string[]; command: string }[] = [];
|
||||
const runner = vi.fn(async (command: string, args: readonly string[]) => {
|
||||
|
||||
@@ -170,7 +170,7 @@ async function resolveCrabboxBin(params: {
|
||||
}
|
||||
|
||||
function extractLeaseId(output: string) {
|
||||
return output.match(/\bcbx_[a-f0-9]+\b/u)?.[0];
|
||||
return output.match(/\b(?:cbx_[a-f0-9]+|tbx_[A-Za-z0-9_-]+)\b/u)?.[0];
|
||||
}
|
||||
|
||||
function shellQuote(value: string) {
|
||||
@@ -346,7 +346,7 @@ async function warmupCrabbox(params: {
|
||||
});
|
||||
const leaseId = extractLeaseId(`${result.stdout}\n${result.stderr}`);
|
||||
if (!leaseId) {
|
||||
throw new Error("Crabbox warmup did not print a cbx_ lease id.");
|
||||
throw new Error("Crabbox warmup did not print a lease id.");
|
||||
}
|
||||
return leaseId;
|
||||
}
|
||||
|
||||
@@ -175,4 +175,67 @@ describe("mantis Slack desktop smoke runtime", () => {
|
||||
expect(summary.error).toContain("remote Slack QA failed");
|
||||
expect(summary.artifacts.screenshotPath).toContain("slack-desktop-smoke.png");
|
||||
});
|
||||
|
||||
it("accepts Blacksmith Testbox lease ids from Crabbox warmup", async () => {
|
||||
const commands: { args: readonly string[]; command: string }[] = [];
|
||||
const runner = vi.fn(async (command: string, args: readonly string[]) => {
|
||||
commands.push({ command, args });
|
||||
if (command === "/tmp/crabbox" && args[0] === "warmup") {
|
||||
return { stdout: "ready: tbx_abc-123_more\n", stderr: "" };
|
||||
}
|
||||
if (command === "/tmp/crabbox" && args[0] === "inspect") {
|
||||
return {
|
||||
stdout: `${JSON.stringify({
|
||||
host: "203.0.113.10",
|
||||
id: "tbx_abc-123_more",
|
||||
provider: "blacksmith-testbox",
|
||||
sshKey: "/tmp/key",
|
||||
sshPort: "2222",
|
||||
sshUser: "crabbox",
|
||||
state: "active",
|
||||
})}\n`,
|
||||
stderr: "",
|
||||
};
|
||||
}
|
||||
if (command === "rsync") {
|
||||
const outputDir = args.at(-1);
|
||||
await fs.mkdir(outputDir as string, { recursive: true });
|
||||
if (String(outputDir).endsWith("slack-qa/")) {
|
||||
await fs.writeFile(path.join(outputDir as string, "slack-qa-report.md"), "# Slack\n");
|
||||
} else {
|
||||
await fs.writeFile(path.join(outputDir as string, "slack-desktop-smoke.png"), "png");
|
||||
await fs.writeFile(path.join(outputDir as string, "remote-metadata.json"), "{}\n");
|
||||
await fs.writeFile(path.join(outputDir as string, "chrome.log"), "chrome\n");
|
||||
await fs.writeFile(path.join(outputDir as string, "slack-desktop-command.log"), "qa\n");
|
||||
}
|
||||
}
|
||||
return { stdout: "", stderr: "" };
|
||||
});
|
||||
|
||||
const result = await runMantisSlackDesktopSmoke({
|
||||
commandRunner: runner,
|
||||
crabboxBin: "/tmp/crabbox",
|
||||
now: () => new Date("2026-05-04T13:30:00.000Z"),
|
||||
outputDir: ".artifacts/qa-e2e/mantis/slack-desktop-testbox",
|
||||
provider: "blacksmith-testbox",
|
||||
repoRoot,
|
||||
});
|
||||
|
||||
expect(result.status).toBe("pass");
|
||||
expect(commands).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
args: expect.arrayContaining(["--id", "tbx_abc-123_more"]),
|
||||
command: "/tmp/crabbox",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
const summary = JSON.parse(await fs.readFile(result.summaryPath, "utf8")) as {
|
||||
crabbox: { id: string; provider: string };
|
||||
};
|
||||
expect(summary.crabbox).toMatchObject({
|
||||
id: "tbx_abc-123_more",
|
||||
provider: "blacksmith-testbox",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -199,7 +199,7 @@ function buildCrabboxEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
||||
}
|
||||
|
||||
function extractLeaseId(output: string) {
|
||||
return output.match(/\bcbx_[a-f0-9]+\b/u)?.[0];
|
||||
return output.match(/\b(?:cbx_[a-f0-9]+|tbx_[A-Za-z0-9_-]+)\b/u)?.[0];
|
||||
}
|
||||
|
||||
function shellQuote(value: string) {
|
||||
@@ -479,7 +479,7 @@ async function warmupCrabbox(params: {
|
||||
});
|
||||
const leaseId = extractLeaseId(`${result.stdout}\n${result.stderr}`);
|
||||
if (!leaseId) {
|
||||
throw new Error("Crabbox warmup did not print a cbx_ lease id.");
|
||||
throw new Error("Crabbox warmup did not print a lease id.");
|
||||
}
|
||||
return leaseId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user