fix: discover preinstalled hwpod specs
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
||||
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { test } from "bun:test";
|
||||
@@ -17,12 +17,67 @@ test("cloud-api exposes hwpod-node-ops contract on /v1", async () => {
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(payload.hwpod.contractVersion, "hwpod-node-ops-v1");
|
||||
assert.equal(payload.hwpod.apiRole, "node-ops-forwarder");
|
||||
assert.equal(payload.hwpod.specDiscoveryRoute, "/v1/hwpod/specs");
|
||||
assert.ok(payload.hwpod.supportedOps.includes("workspace.ls"));
|
||||
} finally {
|
||||
await close(server);
|
||||
}
|
||||
});
|
||||
|
||||
test("cloud-api discovers preinstalled workspace hwpod-specs without hardcoded device constants", async () => {
|
||||
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-spec-discovery-"));
|
||||
const specDir = path.join(root, ".hwlab");
|
||||
await mkdir(specDir, { recursive: true });
|
||||
await writeFile(path.join(specDir, "hwpod-spec.yaml"), sampleSpecYaml(), "utf8");
|
||||
await writeFile(path.join(specDir, "hwpod-spec.meta.json"), JSON.stringify({ source: { kind: "preinstalled-verified-spec", caseRepo: "pikasTech/hwpod-cases", caseId: "d601-f103-v2-compile" } }), "utf8");
|
||||
const server = createCloudApiServer({ env: { PATH: process.env.PATH, HWLAB_CODE_AGENT_WORKSPACE: root } });
|
||||
await listen(server);
|
||||
try {
|
||||
const response = await fetch(`${serverUrl(server)}/v1/hwpod/specs`);
|
||||
const payload = await response.json();
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(payload.contractVersion, "hwpod-spec-discovery-v1");
|
||||
assert.equal(payload.count, 1);
|
||||
assert.equal(payload.specs[0].name, "d601-f103-v2");
|
||||
assert.equal(payload.specs[0].uid, "D601-F103-V2");
|
||||
assert.equal(payload.specs[0].nodeId, "node-d601-f103-v2");
|
||||
assert.equal(payload.specs[0].source.caseId, "d601-f103-v2-compile");
|
||||
} finally {
|
||||
await close(server);
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("cloud-api probes discovered hwpod-spec availability through node-ops", async () => {
|
||||
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-spec-probe-"));
|
||||
const specDir = path.join(root, ".hwlab");
|
||||
await mkdir(specDir, { recursive: true });
|
||||
await writeFile(path.join(specDir, "hwpod-spec.yaml"), sampleSpecYaml(), "utf8");
|
||||
const seen: any[] = [];
|
||||
const server = createCloudApiServer({
|
||||
env: { PATH: process.env.PATH, HWLAB_CODE_AGENT_WORKSPACE: root },
|
||||
hwpodNodeOpsHandler: async (plan: any) => {
|
||||
seen.push(plan);
|
||||
return { ok: true, status: "completed", results: plan.ops.map((op: any) => ({ opId: op.opId, op: op.op, ok: true, status: "completed", output: { path: op.args.workspacePath } })) };
|
||||
}
|
||||
});
|
||||
await listen(server);
|
||||
try {
|
||||
const response = await fetch(`${serverUrl(server)}/v1/hwpod/specs?probe=1`);
|
||||
const payload = await response.json();
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(payload.count, 1);
|
||||
assert.equal(payload.availableCount, 1);
|
||||
assert.equal(payload.specs[0].availability.status, "available");
|
||||
assert.equal(seen[0].hwpodId, "d601-f103-v2");
|
||||
assert.equal(seen[0].nodeId, "node-d601-f103-v2");
|
||||
assert.equal(seen[0].ops[0].op, "workspace.ls");
|
||||
} finally {
|
||||
await close(server);
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("cloud-api forwards valid hwpod-node-ops plans to injected node handler", async () => {
|
||||
const seen: any[] = [];
|
||||
const server = createCloudApiServer({
|
||||
@@ -171,6 +226,30 @@ function samplePlan() {
|
||||
};
|
||||
}
|
||||
|
||||
function sampleSpecYaml() {
|
||||
return `apiVersion: hwlab.dev/v0alpha1
|
||||
kind: Hwpod
|
||||
metadata:
|
||||
uid: D601-F103-V2
|
||||
name: d601-f103-v2
|
||||
spec:
|
||||
targetDevice:
|
||||
board: D601-F103-V2
|
||||
mcu: STM32F103
|
||||
workspace:
|
||||
path: "F:\\\\Work\\\\D601-HWLAB"
|
||||
toolchain: keil-mdk
|
||||
debugProbe:
|
||||
type: daplink
|
||||
ioProbe:
|
||||
uart:
|
||||
port: COM9
|
||||
nodeBinding:
|
||||
nodeId: node-d601-f103-v2
|
||||
nodeType: pc-host
|
||||
`;
|
||||
}
|
||||
|
||||
async function listen(server: any) {
|
||||
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user