import assert from "node:assert/strict"; import crypto from "node:crypto"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import test from "node:test"; import { submitIdempotentServerJobResult } from "../../../tools/web/server-job-idempotency.mjs"; const h = (value) => crypto.createHash("sha256").update(value).digest("hex"); const identity = { requestId: "retry-1", projectId: "project-1", baseRevision: 4, sourceSha256: h("source"), settingsSha256: h("settings"), buildSha256: h("build") }; test("M13-04J reuses the exact verified result for the same request", async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), "m13-04j-reuse-")); const options = { receiptDirectory: path.join(root, "receipts"), outputDirectory: path.join(root, "outputs") }; try { const first = await submitIdempotentServerJobResult(identity, new Uint8Array([1, 2]), options); const second = await submitIdempotentServerJobResult(identity, new Uint8Array([1, 2]), options); assert.equal(first.reused, false); assert.equal(second.reused, true); assert.equal(first.outputSha256, second.outputSha256); assert.equal((await fs.readdir(options.receiptDirectory)).length, 1); } finally { await fs.rm(root, { recursive: true, force: true }); } }); test("M13-04J rejects conflicting output/identity and isolates different requests", async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), "m13-04j-conflict-")); const options = { receiptDirectory: path.join(root, "receipts"), outputDirectory: path.join(root, "outputs") }; try { await submitIdempotentServerJobResult(identity, new Uint8Array([3]), options); await assert.rejects(submitIdempotentServerJobResult(identity, new Uint8Array([4]), options), /SERVER_JOB_IDEMPOTENCY_CONFLICT/); await assert.rejects(submitIdempotentServerJobResult({ ...identity, settingsSha256: h("changed") }, new Uint8Array([3]), options), /SERVER_JOB_IDEMPOTENCY_CONFLICT/); const other = await submitIdempotentServerJobResult({ ...identity, requestId: "retry-2" }, new Uint8Array([4]), options); assert.equal(other.reused, false); assert.equal((await fs.readdir(options.receiptDirectory)).length, 2); } finally { await fs.rm(root, { recursive: true, force: true }); } }); test("M13-04J serializes concurrent duplicate requests", async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), "m13-04j-concurrent-")); const options = { receiptDirectory: path.join(root, "receipts"), outputDirectory: path.join(root, "outputs") }; try { const results = await Promise.all([ submitIdempotentServerJobResult({ ...identity, requestId: "retry-3" }, new Uint8Array([8]), options), submitIdempotentServerJobResult({ ...identity, requestId: "retry-3" }, new Uint8Array([8]), options), ]); assert.deepEqual(results.map((result) => result.reused).sort(), [false, true]); } finally { await fs.rm(root, { recursive: true, force: true }); } });