Files
pikasTech-HWLAB/tools/hwpod-node.test.ts
T
2026-06-06 01:49:59 +08:00

125 lines
5.0 KiB
TypeScript

import assert from "node:assert/strict";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { test } from "bun:test";
import { createHwpodNodeServer, executeHwpodNodeOpsPlan } from "./src/hwpod-node-lib.ts";
test("hwpod-node executes minimal workspace node ops", async () => {
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-node-"));
try {
await writeFile(path.join(root, "main.c"), "int main(void) { return 0; }\n", "utf8");
const result = await executeHwpodNodeOpsPlan({
contractVersion: "hwpod-node-ops-v1",
planId: "hwpod_plan_test",
hwpodId: "hwpod-local",
nodeId: "pc-host-1",
ops: [
{ opId: "op_01", op: "node.health", args: { workspacePath: root } },
{ opId: "op_02", op: "workspace.ls", args: { workspacePath: root, path: "." } },
{ opId: "op_03", op: "workspace.cat", args: { workspacePath: root, path: "main.c" } }
]
}, { now: () => "2026-06-05T00:00:00.000Z" });
assert.equal(result.ok, true);
assert.equal(result.status, "completed");
assert.equal(result.results[1].output.entries[0].name, "main.c");
assert.match(result.results[2].output.content, /int main/u);
} finally {
await rm(root, { recursive: true, force: true });
}
});
test("hwpod-node HTTP endpoint accepts hwpod-node-ops plans", async () => {
const server = createHwpodNodeServer({ now: () => "2026-06-05T00:00:00.000Z" });
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
try {
const response = await fetch(`http://127.0.0.1:${server.address().port}/v1/hwpod-node-ops`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
contractVersion: "hwpod-node-ops-v1",
planId: "hwpod_plan_http",
hwpodId: "hwpod-local",
nodeId: "pc-host-1",
ops: [{ opId: "op_01", op: "node.version", args: {} }]
})
});
const payload = await response.json();
assert.equal(response.status, 200);
assert.equal(payload.ok, true);
assert.equal(payload.specAuthority, "none");
assert.equal(payload.results[0].op, "node.version");
} finally {
await new Promise((resolve, reject) => server.close((error: Error | undefined) => (error ? reject(error) : resolve(undefined))));
}
});
test("hwpod-node executes debug ops only through explicit node-side command bindings", async () => {
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-node-debug-"));
try {
const result = await executeHwpodNodeOpsPlan({
contractVersion: "hwpod-node-ops-v1",
planId: "hwpod_plan_debug_bound",
hwpodId: "hwpod-local",
nodeId: "pc-host-1",
ops: [{ opId: "op_build", op: "debug.build", args: { workspacePath: root, command: "printf build-ok > build.ok" } }]
}, { now: () => "2026-06-05T00:00:00.000Z" });
assert.equal(result.ok, true);
assert.equal(result.results[0].ok, true);
assert.equal(result.results[0].output.bindingSource, "hwpod-node-ops.command");
assert.match(await readFile(path.join(root, "build.ok"), "utf8"), /build-ok/u);
} finally {
await rm(root, { recursive: true, force: true });
}
});
test("hwpod-node applies workspace patches through the stable node op", async () => {
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-node-patch-"));
try {
await writeFile(path.join(root, "main.c"), "int value = 1;\n", "utf8");
const result = await executeHwpodNodeOpsPlan({
contractVersion: "hwpod-node-ops-v1",
planId: "hwpod_plan_patch",
hwpodId: "hwpod-local",
nodeId: "pc-host-1",
ops: [{
opId: "op_patch",
op: "workspace.apply-patch",
args: {
workspacePath: root,
patch: [
"*** Begin Patch",
"*** Update File: main.c",
"@@",
"-int value = 1;",
"+int value = 2;",
"*** End Patch",
""
].join("\n")
}
}]
}, { now: () => "2026-06-05T00:00:00.000Z" });
assert.equal(result.ok, true);
assert.equal(result.results[0].ok, true);
assert.match(await readFile(path.join(root, "main.c"), "utf8"), /value = 2/u);
} finally {
await rm(root, { recursive: true, force: true });
}
});
test("hwpod-node preserves Windows absolute workspace paths for PC-host nodes", async () => {
const result = await executeHwpodNodeOpsPlan({
contractVersion: "hwpod-node-ops-v1",
planId: "hwpod_plan_windows_path",
hwpodId: "d601-f103-v2",
nodeId: "node-d601-f103-v2",
ops: [{ opId: "op_01", op: "workspace.ls", args: { workspacePath: "F:\\Work\\D601-HWLAB", path: "." } }]
}, { now: () => "2026-06-05T00:00:00.000Z" });
assert.equal(result.ok, false);
assert.equal(result.results[0].blocker.code, "ENOENT");
assert.match(result.results[0].blocker.summary, /scandir 'F:\\Work\\D601-HWLAB'/u);
assert.doesNotMatch(result.results[0].blocker.summary, /\/root\//u);
});