Files
boss/tests/boss-agent-ota-runner.test.mjs
2026-05-17 02:20:08 +08:00

222 lines
7.4 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import { createServer } from "node:http";
import os from "node:os";
import path from "node:path";
import { mkdtemp, readFile, rm, stat } from "node:fs/promises";
import {
applyBossAgentOtaUpdate,
checkBossAgentOtaUpdate,
getBossAgentOtaRunnerConfig,
} from "../local-agent/boss-agent-ota-runner.mjs";
function listen(server, host = "127.0.0.1") {
return new Promise((resolve, reject) => {
server.once("error", reject);
server.listen(0, host, () => {
server.off("error", reject);
resolve(server.address().port);
});
});
}
function sha256(buffer) {
return createHash("sha256").update(buffer).digest("hex");
}
test("boss-agent ota runner derives config from local-agent config", () => {
const config = getBossAgentOtaRunnerConfig({}, {
bossAgentOtaEnabled: true,
bossAgentVersion: "20260516194026",
bossAgentInstallRoot: "/tmp/boss-agent/current",
bossAgentOtaDownloadDir: "/tmp/boss-agent/updates",
bossAgentOtaCheckIntervalMs: 12345,
bossAgentOtaAutoInstall: true,
});
assert.equal(config.enabled, true);
assert.equal(config.currentVersion, "20260516194026");
assert.equal(config.installRoot, "/tmp/boss-agent/current");
assert.equal(config.downloadDir, "/tmp/boss-agent/updates");
assert.equal(config.checkIntervalMs, 12345);
assert.equal(config.autoInstall, true);
});
test("boss-agent ota runner checks, downloads, verifies, and stages a mac runtime package", async () => {
const tmp = await mkdtemp(path.join(os.tmpdir(), "boss-agent-ota-runner-"));
const packageBuffer = Buffer.from("boss-agent mac runtime zip", "utf8");
const packageHash = sha256(packageBuffer);
const requestLog = [];
const server = createServer((request, response) => {
requestLog.push({
url: request.url,
token: request.headers["x-boss-device-token"],
});
if (request.url?.startsWith("/api/v1/boss-agent/ota?")) {
response.writeHead(200, { "content-type": "application/json" });
response.end(JSON.stringify({
ok: true,
currentVersion: "20260501000000",
hasUpdate: true,
latest: {
version: "20260516194026",
fileName: "boss-agent-mac-latest.zip",
sizeBytes: packageBuffer.length,
sha256: packageHash,
downloadUrl: "/api/v1/boss-agent/ota/package",
updatedAt: "2026-05-16T11:40:26.000Z",
},
}));
return;
}
if (request.url?.startsWith("/api/v1/boss-agent/ota/package")) {
response.writeHead(200, {
"content-type": "application/zip",
"content-length": String(packageBuffer.length),
"x-boss-agent-ota-sha256": packageHash,
});
response.end(packageBuffer);
return;
}
response.writeHead(404, { "content-type": "application/json" });
response.end(JSON.stringify({ ok: false }));
});
try {
const port = await listen(server);
const localConfig = {
controlPlaneUrl: `http://127.0.0.1:${port}`,
deviceId: "mac-studio",
token: "device-token",
bossAgentOtaEnabled: true,
bossAgentVersion: "20260501000000",
bossAgentOtaDownloadDir: path.join(tmp, "updates"),
bossAgentInstallRoot: path.join(tmp, "current"),
};
const runtime = {};
const status = await checkBossAgentOtaUpdate(localConfig, runtime);
assert.equal(status.hasUpdate, true);
assert.equal(status.latest.version, "20260516194026");
assert.equal(requestLog.at(0)?.token, "device-token");
assert.match(requestLog.at(0)?.url ?? "", /deviceId=mac-studio/);
assert.match(requestLog.at(0)?.url ?? "", /currentVersion=20260501000000/);
const result = await applyBossAgentOtaUpdate(localConfig, runtime, {
launchInstaller: false,
});
assert.equal(result.status, "staged");
assert.equal(result.version, "20260516194026");
assert.equal(result.sha256, packageHash);
assert.match(result.archivePath, /boss-agent-mac-latest\.zip$/);
assert.equal(await readFile(result.archivePath, "utf8"), "boss-agent mac runtime zip");
const installInfo = await stat(path.join(result.stageDir, "install.command"));
assert.equal(installInfo.isFile(), true);
assert.equal(runtime.lastBossAgentOtaApply.status, "staged");
} finally {
server.close();
await rm(tmp, { recursive: true, force: true });
}
});
test("boss-agent ota runner reports up-to-date when latest equals current version", async () => {
const server = createServer((request, response) => {
if (request.url?.startsWith("/api/v1/boss-agent/ota?")) {
response.writeHead(200, { "content-type": "application/json" });
response.end(JSON.stringify({
ok: true,
currentVersion: "20260516201125",
hasUpdate: false,
latest: {
version: "20260516201125",
fileName: "boss-agent-mac-latest.zip",
sizeBytes: 1,
sha256: "0".repeat(64),
downloadUrl: "/api/v1/boss-agent/ota/package",
updatedAt: "2026-05-16T12:11:30.842Z",
},
}));
return;
}
response.writeHead(404);
response.end();
});
try {
const port = await listen(server);
const status = await checkBossAgentOtaUpdate(
{
controlPlaneUrl: `http://127.0.0.1:${port}`,
deviceId: "macbook-air",
token: "device-token",
bossAgentOtaEnabled: true,
bossAgentVersion: "20260516201125",
},
{},
);
assert.equal(status.hasUpdate, false);
assert.equal(status.message, "BOSS_AGENT_OTA_UP_TO_DATE");
assert.equal(status.latest.version, "20260516201125");
} finally {
server.close();
}
});
test("boss-agent ota runner rejects a package with mismatched checksum", async () => {
const tmp = await mkdtemp(path.join(os.tmpdir(), "boss-agent-ota-bad-checksum-"));
const packageBuffer = Buffer.from("tampered", "utf8");
const server = createServer((request, response) => {
if (request.url?.startsWith("/api/v1/boss-agent/ota?")) {
response.writeHead(200, { "content-type": "application/json" });
response.end(JSON.stringify({
ok: true,
currentVersion: "20260501000000",
hasUpdate: true,
latest: {
version: "20260516194026",
fileName: "boss-agent-mac-latest.zip",
sizeBytes: packageBuffer.length,
sha256: "0".repeat(64),
downloadUrl: "/api/v1/boss-agent/ota/package",
updatedAt: "2026-05-16T11:40:26.000Z",
},
}));
return;
}
if (request.url?.startsWith("/api/v1/boss-agent/ota/package")) {
response.writeHead(200, { "content-type": "application/zip" });
response.end(packageBuffer);
return;
}
response.writeHead(404);
response.end();
});
try {
const port = await listen(server);
const result = await applyBossAgentOtaUpdate(
{
controlPlaneUrl: `http://127.0.0.1:${port}`,
deviceId: "mac-studio",
token: "device-token",
bossAgentOtaEnabled: true,
bossAgentVersion: "20260501000000",
bossAgentOtaDownloadDir: path.join(tmp, "updates"),
bossAgentInstallRoot: path.join(tmp, "current"),
},
{},
{ launchInstaller: false },
);
assert.equal(result.status, "failed");
assert.equal(result.error, "BOSS_AGENT_OTA_CHECKSUM_MISMATCH");
} finally {
server.close();
await rm(tmp, { recursive: true, force: true });
}
});