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 repoRoot = path.resolve(import.meta.dirname, "../../.."); const sourcePath = path.join(repoRoot, "web/protocol/nanovdb-page-feedback.ts"); const transpiled = ts.transpileModule(fs.readFileSync(sourcePath, "utf8"), { compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 }, fileName: sourcePath, reportDiagnostics: true, }); assert.deepEqual(transpiled.diagnostics, []); const moduleUrl = "data:text/javascript;base64," + Buffer.from(transpiled.outputText).toString("base64"); const feedback = await import(moduleUrl); test("M8-01 freezes the bounded GPU feedback word layout", () => { const buffer = feedback.createNanoVDBPageFeedbackBuffer(); const words = new Uint32Array(buffer); assert.equal(buffer.byteLength, (feedback.NANOVDB_PAGE_FEEDBACK_HEADER_WORDS + feedback.NANOVDB_PAGE_FEEDBACK_DEFAULT_CAPACITY) * 4); assert.deepEqual([...words.slice(0, 4)], [1, 1024, 0, 0]); assert.ok([...words.slice(4)].every((word) => word === 0xffffffff)); assert.deepEqual(feedback.NANOVDB_PAGE_FEEDBACK_WORD, { schemaVersion: 0, capacity: 1, count: 2, overflow: 3, pageIds: 4 }); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_WGSL, /count: atomic/); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_WGSL, /overflow: atomic/); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_WGSL, /page_ids: array>/); }); test("M8-02 records unique page IDs with a physical-capacity bound", () => { assert.match(feedback.NANOVDB_PAGE_FEEDBACK_RECORD_WGSL, /arrayLength\(&nanovdb_page_feedback\.page_ids\)/); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_RECORD_WGSL, /min\(nanovdb_page_feedback\.capacity, physical_capacity\)/); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_RECORD_WGSL, /slot < capacity/); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_RECORD_WGSL, /atomicCompareExchangeWeak/); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_RECORD_WGSL, /claim\.old_value == page_id/); assert.match(feedback.NANOVDB_PAGE_FEEDBACK_RECORD_WGSL, /atomicStore\(&nanovdb_page_feedback\.overflow, 1u\)/); }); test("M8-03 sorts, deduplicates and binds CPU feedback to a render revision", () => { const buffer = feedback.createNanoVDBPageFeedbackBuffer(4); const words = new Uint32Array(buffer); words[feedback.NANOVDB_PAGE_FEEDBACK_WORD.count] = 4; words.set([7, 2, 7, 5], feedback.NANOVDB_PAGE_FEEDBACK_WORD.pageIds); assert.deepEqual(feedback.parseNanoVDBPageFeedbackBatch(buffer, 8, 42), { schemaVersion: 1, renderRevision: 42, attemptedCount: 4, gpuStoredCount: 4, uniqueCount: 3, pageIds: [2, 5, 7], status: "READY", errorCode: null, }); assert.throws( () => feedback.parseNanoVDBPageFeedbackBatch(buffer, 8, -1), (error) => error.code === "INVALID_ARGUMENT", ); assert.throws( () => feedback.parseNanoVDBPageFeedbackBatch(buffer, 8, 1.5), (error) => error.code === "INVALID_ARGUMENT", ); }); test("M8-04 rejects stale frame feedback before page I/O", async () => { const buffer = feedback.createNanoVDBPageFeedbackBuffer(4); const words = new Uint32Array(buffer); words[feedback.NANOVDB_PAGE_FEEDBACK_WORD.count] = 3; words.set([7, 2, 5], feedback.NANOVDB_PAGE_FEEDBACK_WORD.pageIds); const batch = feedback.parseNanoVDBPageFeedbackBatch(buffer, 8, 42); const requests = []; const requestPage = async (pageId, renderRevision) => { requests.push({ pageId, renderRevision }); }; assert.deepEqual(await feedback.dispatchNanoVDBPageFeedbackBatch(batch, 43, requestPage), { schemaVersion: 1, renderRevision: 42, currentRenderRevision: 43, status: "STALE", requestedPageIds: [], requestedCount: 0, errorCode: "REVISION_CONFLICT", }); assert.deepEqual(await feedback.dispatchNanoVDBPageFeedbackBatch(batch, 41, requestPage), { schemaVersion: 1, renderRevision: 42, currentRenderRevision: 41, status: "STALE", requestedPageIds: [], requestedCount: 0, errorCode: "REVISION_CONFLICT", }); assert.deepEqual(requests, []); assert.deepEqual(await feedback.dispatchNanoVDBPageFeedbackBatch(batch, 42, requestPage), { schemaVersion: 1, renderRevision: 42, currentRenderRevision: 42, status: "ACCEPTED", requestedPageIds: [2, 5, 7], requestedCount: 3, errorCode: null, }); assert.deepEqual(requests, [ { pageId: 2, renderRevision: 42 }, { pageId: 5, renderRevision: 42 }, { pageId: 7, renderRevision: 42 }, ]); await assert.rejects( feedback.dispatchNanoVDBPageFeedbackBatch(batch, -1, requestPage), (error) => error.code === "INVALID_ARGUMENT", ); }); test("M8-01 parses ready and overflow feedback with a stable overflow code", () => { const readyBuffer = feedback.createNanoVDBPageFeedbackBuffer(4); const readyWords = new Uint32Array(readyBuffer); readyWords[feedback.NANOVDB_PAGE_FEEDBACK_WORD.count] = 3; readyWords.set([7, 2, 5], feedback.NANOVDB_PAGE_FEEDBACK_WORD.pageIds); assert.deepEqual(feedback.parseNanoVDBPageFeedbackBuffer(readyBuffer, 8), { schemaVersion: 1, capacity: 4, attemptedCount: 3, storedCount: 3, pageIds: [7, 2, 5], status: "READY", errorCode: null, }); const overflowBuffer = feedback.createNanoVDBPageFeedbackBuffer(2); const overflowWords = new Uint32Array(overflowBuffer); overflowWords[feedback.NANOVDB_PAGE_FEEDBACK_WORD.count] = 4; overflowWords[feedback.NANOVDB_PAGE_FEEDBACK_WORD.overflow] = 1; overflowWords.set([3, 4], feedback.NANOVDB_PAGE_FEEDBACK_WORD.pageIds); assert.deepEqual(feedback.parseNanoVDBPageFeedbackBuffer(overflowBuffer, 8), { schemaVersion: 1, capacity: 2, attemptedCount: 4, storedCount: 2, pageIds: [3, 4], status: "OVERFLOW", errorCode: "NANOVDB_PAGE_FEEDBACK_OVERFLOW", }); }); test("M8-01 rejects layout drift, invalid pages and inconsistent overflow", () => { assert.throws(() => feedback.createNanoVDBPageFeedbackBuffer(0), (error) => error.code === "INVALID_ARGUMENT"); assert.throws(() => feedback.createNanoVDBPageFeedbackBuffer(8193), (error) => error.code === "INVALID_ARGUMENT"); const wrongSchema = feedback.createNanoVDBPageFeedbackBuffer(2); new Uint32Array(wrongSchema)[0] = 2; assert.throws(() => feedback.parseNanoVDBPageFeedbackBuffer(wrongSchema, 8), (error) => error.code === "PROTOCOL_MISMATCH"); const wrongCapacity = feedback.createNanoVDBPageFeedbackBuffer(2); new Uint32Array(wrongCapacity)[1] = 8193; assert.throws(() => feedback.parseNanoVDBPageFeedbackBuffer(wrongCapacity, 8), (error) => error.code === "PROTOCOL_MISMATCH"); const wrongSize = feedback.createNanoVDBPageFeedbackBuffer(2).slice(0, 20); assert.throws(() => feedback.parseNanoVDBPageFeedbackBuffer(wrongSize, 8), (error) => error.code === "PROTOCOL_MISMATCH"); const inconsistent = feedback.createNanoVDBPageFeedbackBuffer(2); const inconsistentWords = new Uint32Array(inconsistent); inconsistentWords[2] = 3; inconsistentWords.set([1, 2], 4); assert.throws(() => feedback.parseNanoVDBPageFeedbackBuffer(inconsistent, 8), (error) => error.code === "PROTOCOL_MISMATCH"); const invalidPage = feedback.createNanoVDBPageFeedbackBuffer(2); const invalidPageWords = new Uint32Array(invalidPage); invalidPageWords[2] = 1; invalidPageWords[4] = 8; assert.throws(() => feedback.parseNanoVDBPageFeedbackBuffer(invalidPage, 8), (error) => error.code === "PROTOCOL_MISMATCH"); }); test("M8-01 reset clears atomic words and stale page IDs", () => { const buffer = feedback.createNanoVDBPageFeedbackBuffer(3); const words = new Uint32Array(buffer); words[2] = 5; words[3] = 1; words.set([1, 2, 3], 4); feedback.resetNanoVDBPageFeedbackBuffer(buffer); assert.deepEqual([...words], [1, 3, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff]); });