fix: restore loadBinaryBlob fault-propagation (native column-store lockstep)
The Pass-1 hardening that makes loadBinaryBlob distinguish genuine absence (ENOENT -> null) from a real fault (EIO/EACCES/... -> throw) was held out of 8.2.6 because the native accelerator's two column-store read sites still relied on null-on-error. That accelerator release has now hardened those sites to handle the throw (a faulted segment read marks the field unavailable and throws a named error), so the fault-propagating form is restored and ships lockstep. A present-but-unreadable index blob no longer masquerades as absent (which drove needless rebuilds / empty reads). Adds the loadBinaryBlob leg to the blob durability suite (absent -> null; present -> bytes; real fault -> throws).
This commit is contained in:
parent
76843b782e
commit
b6c7039769
3 changed files with 65 additions and 19 deletions
|
|
@ -74,3 +74,38 @@ describe('FileSystemStorage.saveBinaryBlob durable-write honesty (finding 13)',
|
|||
).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' })
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue