/** * @module tests/unit/storage/blob-save-durability * @description Finding 13 (cortex sweep): saveBinaryBlob must never acknowledge a * durable write that stored nothing. With the UNIQUE per-writer temp suffix, a * rename ENOENT can no longer mean "a concurrent idempotent writer already * renamed it" — nobody else has this writer's temp — so it means our temp * vanished before the rename and the bytes did NOT land. The old code returned * success on that ENOENT; the native provider mmaps these blobs, so a * phantom-acked blob is the exact silent-loss class the registered-blob work * chases. The fix retries once with a fresh temp, then fails loud. */ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' import * as fs from 'node:fs' import * as os from 'node:os' import * as path from 'node:path' import { FileSystemStorage } from '../../../src/storage/adapters/fileSystemStorage.js' const enoent = (): Error => Object.assign(new Error('temp removed'), { code: 'ENOENT' }) describe('FileSystemStorage.saveBinaryBlob durable-write honesty (finding 13)', () => { let dir: string let storage: any beforeEach(async () => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'brainy-blob-save-')) storage = new FileSystemStorage(dir) await storage.init() }) afterEach(() => { vi.restoreAllMocks() fs.rmSync(dir, { recursive: true, force: true }) }) it('persists and reads back a blob under normal conditions', async () => { await storage.saveBinaryBlob('graph-lsm/seg-1', Buffer.from([1, 2, 3, 4])) expect(await storage.loadBinaryBlob('graph-lsm/seg-1')).toEqual(Buffer.from([1, 2, 3, 4])) }) it('throws (never acks) when the temp vanishes on every rename attempt', async () => { vi.spyOn(fs.promises, 'rename').mockRejectedValue(enoent()) await expect( storage.saveBinaryBlob('k/silent-loss', Buffer.from([9])) ).rejects.toThrow(/did NOT persist/) // Prove the write truly did not land — and was not acknowledged. (loadBinaryBlob // uses readFile, not rename, so it reflects the real on-disk state.) expect(await storage.loadBinaryBlob('k/silent-loss')).toBeNull() }) it('self-heals: a single transient temp-vanish retries and persists', async () => { const real = fs.promises.rename.bind(fs.promises) let calls = 0 vi.spyOn(fs.promises, 'rename').mockImplementation(async (from: any, to: any) => { calls++ if (calls === 1) throw enoent() return real(from, to) }) await expect( storage.saveBinaryBlob('k/heals', Buffer.from([7, 7])) ).resolves.toBeUndefined() expect(calls).toBe(2) // first attempt vanished, retry landed expect(await storage.loadBinaryBlob('k/heals')).toEqual(Buffer.from([7, 7])) }) it('a non-ENOENT rename fault propagates verbatim (not swallowed)', async () => { vi.spyOn(fs.promises, 'rename').mockRejectedValue( Object.assign(new Error('disk fault'), { code: 'EIO' }) ) await expect( storage.saveBinaryBlob('k/eio', Buffer.from([1])) ).rejects.toMatchObject({ code: 'EIO' }) }) }) describe('FileSystemStorage.loadBinaryBlob fault-propagation (finding 11; cor 3.0.13 lockstep)', () => { let dir: string let storage: any beforeEach(async () => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'brainy-blob-load-')) storage = new FileSystemStorage(dir) await storage.init() }) afterEach(() => { vi.restoreAllMocks() fs.rmSync(dir, { recursive: true, force: true }) }) it('returns null for a genuinely absent blob (ENOENT)', async () => { expect(await storage.loadBinaryBlob('never/written')).toBeNull() }) it('reads back a present blob', async () => { await storage.saveBinaryBlob('present/blob', Buffer.from([1, 2, 3])) expect(await storage.loadBinaryBlob('present/blob')).toEqual(Buffer.from([1, 2, 3])) }) it('propagates a real IO fault instead of masking it as absent', async () => { await storage.saveBinaryBlob('present/blob', Buffer.from([1, 2, 3])) vi.spyOn(fs.promises, 'readFile').mockRejectedValue( Object.assign(new Error('disk fault'), { code: 'EIO' }) ) // A present-but-unreadable blob must NOT read as null (that drove needless // native rebuilds / empty reads); cor 3.0.13's column-store handles the throw. await expect(storage.loadBinaryBlob('present/blob')).rejects.toMatchObject({ code: 'EIO' }) }) })