Files
NODEDC_TASKMANAGER_CODEXAPI/scripts/build-ops-agents-reboot-resilience-artifact.test.mjs

90 lines
3.5 KiB
JavaScript

import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import { spawnSync } from "node:child_process";
import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
const scriptDir = dirname(fileURLToPath(import.meta.url));
const builder = join(scriptDir, "build-ops-agents-reboot-resilience-artifact.mjs");
const basename = "nodedc-ops-agents-reboot-resilience-20260809-001";
test("builds a deterministic, minimal Ops Agents application overlay", async () => {
const firstRoot = await mkdtemp(join(tmpdir(), "ops-agents-artifact-first-"));
const secondRoot = await mkdtemp(join(tmpdir(), "ops-agents-artifact-second-"));
try {
const first = runBuilder(firstRoot);
const second = runBuilder(secondRoot);
const firstArtifact = join(firstRoot, `${basename}.tgz`);
const secondArtifact = join(secondRoot, `${basename}.tgz`);
assert.equal(first.artifactSha256, second.artifactSha256);
assert.equal(first.artifactSha256, sha256(await readFile(firstArtifact)));
assert.deepEqual(first.files, [
"docker-compose.synology.yml",
"src/db/wait-for-database.test.ts",
"src/db/wait-for-database.ts",
"src/scripts/migrate.ts",
]);
assert.equal(first.runnerChanged, false);
assert.equal(first.databaseVolumeSelected, false);
const members = new Set(runTar(["-tzf", firstArtifact]).trim().split("\n"));
assert.deepEqual(members, new Set([
"manifest.env",
"files.txt",
"payload/",
"payload/docker-compose.synology.yml",
"payload/src/",
"payload/src/db/",
"payload/src/db/wait-for-database.test.ts",
"payload/src/db/wait-for-database.ts",
"payload/src/scripts/",
"payload/src/scripts/migrate.ts",
]));
assert.equal([...members].some((member) => member.includes("._")), false);
assert.equal(
runTar(["-xOzf", firstArtifact, "manifest.env"]),
"id=ops-agents-reboot-resilience-20260809-001\ncomponent=ops-agents\ntype=app-overlay\n",
);
assert.equal(
runTar(["-xOzf", firstArtifact, "files.txt"]),
`${first.files.join("\n")}\n`,
);
const predecessors = await readFile(join(firstRoot, `${basename}.predecessor.sha256`), "utf8");
assert.match(predecessors, /^e78d37368c3d255f257086773ba908e44aae2e475661b80ee17f98c3d55d178f .*docker-compose\.synology\.yml$/m);
assert.match(predecessors, /^8396a42deded31f1fe2381f772838a33b05bfd389075ebd34a5f546593f08769 .*src\/scripts\/migrate\.ts$/m);
const newPaths = await readFile(join(firstRoot, `${basename}.new-paths`), "utf8");
assert.match(newPaths, /src\/db\/wait-for-database\.ts/);
assert.match(newPaths, /src\/db\/wait-for-database\.test\.ts/);
} finally {
await rm(firstRoot, { recursive: true, force: true });
await rm(secondRoot, { recursive: true, force: true });
}
});
function runBuilder(outputRoot) {
const result = spawnSync(process.execPath, [builder], {
encoding: "utf8",
env: { ...process.env, NODEDC_DEPLOY_ARTIFACT_DIR: outputRoot },
});
assert.equal(result.status, 0, result.stderr || result.stdout);
return JSON.parse(result.stdout);
}
function runTar(args) {
const result = spawnSync("tar", args, { encoding: "utf8" });
assert.equal(result.status, 0, result.stderr || result.stdout);
return result.stdout;
}
function sha256(bytes) {
return createHash("sha256").update(bytes).digest("hex");
}