feat(hwpod): 补齐拓扑与节点接入控制台
This commit is contained in:
@@ -33,6 +33,8 @@ test("cloud-api exposes hwpod-node-ops contract on /v1", async () => {
|
||||
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.equal(payload.hwpod.topologyRoute, "/v1/hwpod/topology");
|
||||
assert.equal(payload.hwpod.topologyContractVersion, "hwpod-topology-v1");
|
||||
assert.ok(payload.hwpod.supportedOps.includes("node.diagnostics"));
|
||||
assert.ok(payload.hwpod.supportedOps.includes("workspace.ls"));
|
||||
assert.ok(payload.hwpod.supportedOps.includes("workspace.insert-after"));
|
||||
@@ -66,6 +68,11 @@ test("cloud-api exposes hwlab-node Python update metadata", async () => {
|
||||
assert.equal(payload.latestVersion, "0.1.1");
|
||||
assert.equal(payload.downloadUrl, "https://hwlab.pikapython.com/downloads/hwlab-node.py");
|
||||
assert.equal(payload.sha256, "abc123");
|
||||
assert.equal(payload.artifact.fileName, "hwlab-node.py");
|
||||
assert.equal(payload.artifact.sha256, "abc123");
|
||||
assert.ok(payload.artifact.sizeBytes > 0);
|
||||
assert.equal(payload.readinessStages.at(-1).id, "hwpod-ready");
|
||||
assert.ok(payload.installConditions.some((item: any) => item.id === "outbound-websocket"));
|
||||
|
||||
const currentResponse = await fetch(`${serverUrl(server)}/v1/hwlab-node/update?current=0.1.1&channel=stable&platform=windows`);
|
||||
const currentPayload = await currentResponse.json();
|
||||
@@ -85,15 +92,18 @@ test("cloud-api serves bundled hwlab-node Python updater artifact by default", a
|
||||
const payload = await response.json();
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(payload.updateAvailable, true);
|
||||
assert.equal(payload.latestVersion, "0.1.1");
|
||||
assert.equal(payload.latestVersion, "0.1.2");
|
||||
assert.equal(payload.downloadUrl, "https://hwlab.pikapython.com/v1/hwlab-node/download/hwlab-node.py");
|
||||
assert.match(payload.sha256, /^[a-f0-9]{64}$/u);
|
||||
assert.equal(payload.artifact.version, "0.1.2");
|
||||
assert.equal(payload.artifact.fileName, "hwlab-node.py");
|
||||
assert.ok(payload.artifact.sizeBytes > 0);
|
||||
|
||||
const download = await fetch(`${serverUrl(server)}/v1/hwlab-node/download/hwlab-node.py`);
|
||||
const text = await download.text();
|
||||
assert.equal(download.status, 200);
|
||||
assert.equal(download.headers.get("x-hwlab-node-version"), "0.1.1");
|
||||
assert.ok(text.includes('APP_VERSION = "0.1.1"'));
|
||||
assert.equal(download.headers.get("x-hwlab-node-version"), "0.1.2");
|
||||
assert.ok(text.includes('APP_VERSION = "0.1.2"'));
|
||||
} finally {
|
||||
await close(server);
|
||||
}
|
||||
@@ -187,6 +197,40 @@ test("cloud-api probes discovered hwpod-spec availability through node-ops", asy
|
||||
}
|
||||
});
|
||||
|
||||
test("cloud-api serves the typed HWPOD topology read model from its existing owner", async () => {
|
||||
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-topology-"));
|
||||
const specDir = path.join(root, ".hwlab");
|
||||
await mkdir(specDir, { recursive: true });
|
||||
await writeFile(path.join(specDir, "hwpod-spec.yaml"), sampleSpecYaml(), "utf8");
|
||||
const server = createHwpodTestCloudApiServer({
|
||||
env: { PATH: process.env.PATH, HWLAB_CODE_AGENT_WORKSPACE: root },
|
||||
hwpodNodeWsRegistry: {
|
||||
hasNode: () => false,
|
||||
dispatch: async () => ({ ok: false, status: "blocked", results: [] }),
|
||||
describe: () => ({
|
||||
mode: "hwpod-node-outbound-native-ws",
|
||||
connectedCount: 1,
|
||||
pendingCount: 0,
|
||||
nodes: [{ nodeId: "node-d601-f103-v2", name: "D601 Python Node", status: "online", platform: "win32", version: "0.1.2-python-gui", capabilities: ["workspace.ls"], inFlightCount: 0, maxInFlight: 1 }]
|
||||
})
|
||||
}
|
||||
});
|
||||
await listen(server);
|
||||
try {
|
||||
const response = await fetch(`${serverUrl(server)}/v1/hwpod/topology?resource=node`);
|
||||
const payload = await response.json();
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(payload.contractVersion, "hwpod-topology-v1");
|
||||
assert.equal(payload.owner, "cloud-api-hwpod-domain");
|
||||
assert.equal(payload.items[0].nodeId, "node-d601-f103-v2");
|
||||
assert.equal(payload.items[0].deviceCount, 1);
|
||||
assert.equal(payload.items[0].capabilityMismatch, true);
|
||||
} 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 = createHwpodTestCloudApiServer({
|
||||
|
||||
Reference in New Issue
Block a user