Files
workinf_Blender_Wasm/web/tests/unit/server-render-job.test.mjs
mes123456 0fe8d2bb56
Some checks are pending
M6 deployable RC / quick (push) Waiting to run
M6 deployable RC / chromium (push) Blocked by required conditions
M6 deployable RC / release (push) Blocked by required conditions
Advance M8-M11 parity workflows
2026-08-17 04:37:07 -04:00

67 lines
4.5 KiB
JavaScript

import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import test from "node:test";
import ts from "typescript";
const root = path.resolve(import.meta.dirname, "../../..");
const sourcePath = path.join(root, "web/protocol/server-render-job.ts");
const source = fs.readFileSync(sourcePath, "utf8").replace('import type { ErrorCode } from "./error";\n', "");
const transpiled = ts.transpileModule(source, {
compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 },
fileName: sourcePath,
reportDiagnostics: true,
});
assert.deepEqual(transpiled.diagnostics, []);
const jobs = await import("data:text/javascript;base64," + Buffer.from(transpiled.outputText).toString("base64"));
const sourceBytes = new TextEncoder().encode("server-render-source-v1").buffer;
const build = { version: "5.2.0", buildSha256: "a".repeat(64) };
const settings = {
renderEngine: "BLENDER_CYCLES",
frameStart: 1,
frameEnd: 1,
resolutionX: 32,
resolutionY: 32,
resolutionPercentage: 100,
samples: 4,
outputMime: "image/png",
transparent: false,
};
test("M11-06 binds source bytes, Blender build and canonical render settings", async () => {
const request = await jobs.createServerRenderJobRequest(sourceBytes, build, settings, { jobId: "render:test", sourceRevision: 7 });
assert.equal(request.sourceBlendByteLength, sourceBytes.byteLength);
assert.match(request.sourceBlendSha256, /^[a-f0-9]{64}$/);
assert.match(request.settingsSha256, /^[a-f0-9]{64}$/);
assert.match(request.requestSha256, /^[a-f0-9]{64}$/);
assert.deepEqual(await jobs.verifyServerRenderJobRequest(request, sourceBytes), request);
const reordered = await jobs.createServerRenderJobRequest(sourceBytes, build, { transparent: settings.transparent, ...settings }, { jobId: "render:test", sourceRevision: 7 });
assert.equal(reordered.settingsSha256, request.settingsSha256);
assert.equal(await jobs.createServerRenderJobKey(request), await jobs.createServerRenderJobKey(reordered));
});
test("M11-06 verifies output hash and rejects every provenance drift", async () => {
const request = await jobs.createServerRenderJobRequest(sourceBytes, build, settings, { jobId: "render:verify", sourceRevision: 2 });
const output = Uint8Array.from([0x89, 0x50, 0x4e, 0x47, 0x00, 0x01]).buffer;
const result = await jobs.createServerRenderJobResult(request, output);
assert.equal(result.status, "SUCCEEDED");
assert.deepEqual(await jobs.verifyServerRenderJobResult(result, request, output), result);
await assert.rejects(jobs.verifyServerRenderJobRequest(request, Uint8Array.from([1, 2, 3]).buffer), { code: "SERVER_RENDER_SOURCE_HASH_MISMATCH" });
await assert.rejects(jobs.verifyServerRenderJobResult(result, request, Uint8Array.from([9, 9]).buffer), { code: "SERVER_RENDER_OUTPUT_HASH_MISMATCH" });
await assert.rejects(jobs.verifyServerRenderJobResult({ ...result, sourceBlendSha256: "b".repeat(64) }, request, output), { code: "SERVER_RENDER_BINDING_MISMATCH" });
await assert.rejects(jobs.verifyServerRenderJobRequest({ ...request, blenderBuild: { ...build, buildSha256: "b".repeat(64) } }), { code: "SERVER_RENDER_REQUEST_HASH_MISMATCH" });
await assert.rejects(jobs.createServerRenderJobRequest(sourceBytes, { ...build, version: "5.3.0" }, settings), { code: "SERVER_RENDER_BUILD_INVALID" });
await assert.rejects(jobs.createServerRenderJobRequest(sourceBytes, build, { ...settings, samples: 0 }), { code: "SERVER_RENDER_SETTINGS_INVALID" });
});
test("M11-06 rejects malformed result metadata and settings budget abuse", async () => {
await assert.rejects(jobs.createServerRenderJobRequest(sourceBytes, build, { ...settings, payload: "x".repeat(300_000) }), { code: "SERVER_RENDER_SETTINGS_INVALID" });
const request = await jobs.createServerRenderJobRequest(sourceBytes, build, settings);
const result = await jobs.createServerRenderJobResult(request, Uint8Array.from([1]).buffer);
await assert.rejects(jobs.verifyServerRenderJobResult({ ...result, outputByteLength: result.outputByteLength + 1 }, request), { code: "SERVER_RENDER_RESULT_HASH_MISMATCH" });
await assert.rejects(jobs.verifyServerRenderJobResult({ ...result, outputMime: "image/openexr" }, request), { code: "SERVER_RENDER_OUTPUT_INVALID" });
await assert.rejects(jobs.verifyServerRenderJobResult({ ...result, errorCode: "SERVER_RENDER_FAILED" }, request), { code: "SERVER_RENDER_OUTPUT_INVALID" });
await assert.rejects(jobs.verifyServerRenderJobRequest({ ...request, unexpected: true }), { code: "SERVER_RENDER_REQUEST_INVALID" });
});