// SPDX-License-Identifier: LGPL-3.0-or-later import assert from 'node:assert'; import { randomBytes } from 'node:crypto'; import { suite, test } from 'node:test'; import { Worker } from 'worker_threads'; import { fs, mount, resolveMountConfig, SingleBuffer, vfs } from '@zenfs/core'; import { setupLogs } from '../logs.js'; setupLogs(); await suite('SingleBuffer', () => { test('filesystem restoration from original buffer (with same metadata)', async () => { const buffer = new ArrayBuffer(0x100000); const writable = await resolveMountConfig({ backend: SingleBuffer, buffer }); mount('/mnt', writable); fs.writeFileSync('/mnt/example.ts', 'console.log("hello world")', 'utf-8'); const stats = fs.statSync('/mnt/example.ts'); const snapshot = await resolveMountConfig({ backend: SingleBuffer, buffer }); mount('/snapshot', snapshot); const snapshotStats = fs.statSync('/snapshot/example.ts'); assert.deepEqual(snapshotStats, stats); }); test('cross-thread SharedArrayBuffer', async () => { const sharedBuffer = new SharedArrayBuffer(0x100000); const writable = await resolveMountConfig({ backend: SingleBuffer, buffer: sharedBuffer }); fs.mkdirSync('/shared'); mount('/shared', writable); const worker = new Worker(import.meta.dirname + '/single-buffer.worker.js', { workerData: sharedBuffer }); // Pause while we wait for the worker to emit the 'continue' message, which // means it has mounted the filesystem and created /worker-file.ts const { promise, resolve, reject } = Promise.withResolvers(); setTimeout(reject, 1000); worker.on('message', message => { if (message === 'continue') resolve(); else reject(message ?? new Error('Failed')); }); await promise; await worker.terminate(); worker.unref(); assert(fs.existsSync('/shared/worker-file.ts')); }); test('reliability across varied file sizes', async () => { const mountPoint = '/sbfs-reliability'; const verifyMountPoint = '/sbfs-verify'; const buffer = new ArrayBuffer(0x400000); const writable = await resolveMountConfig({ backend: SingleBuffer, buffer, label: 'reliability' }); mount(mountPoint, writable); const filePath = `${mountPoint}/payload.bin`; const growthSizes = [0, 1, 17, 512, 8192, 65535, 262144, 524288]; const shrinkSizes = [262144, 4096, 128, 0]; const verifySnapshot = (expected: Buffer, size: number) => { mount(verifyMountPoint, writable); try { const reopened = fs.readFileSync(`${verifyMountPoint}/payload.bin`); assert.strictEqual(reopened.byteLength, size, `snapshot size mismatch for ${size} bytes`); assert.deepStrictEqual(reopened, expected, `snapshot content mismatch for ${size} bytes`); } finally { vfs.umount(verifyMountPoint); } }; try { for (const size of growthSizes) { const payload = size ? randomBytes(size) : Buffer.alloc(0); fs.writeFileSync(filePath, payload); const direct = fs.readFileSync(filePath); assert.strictEqual(direct.byteLength, size, `direct size mismatch for ${size} bytes`); assert.deepStrictEqual(direct, payload, `direct content mismatch for ${size} bytes`); verifySnapshot(direct, size); } for (const size of shrinkSizes) { const payload = size ? randomBytes(size) : Buffer.alloc(0); fs.writeFileSync(filePath, payload); const direct = fs.readFileSync(filePath); assert.strictEqual(direct.byteLength, size, `direct size mismatch after shrink to ${size} bytes`); assert.deepStrictEqual(direct, payload, `direct content mismatch after shrink to ${size} bytes`); verifySnapshot(direct, size); } } finally { if (fs.existsSync(filePath)) fs.unlinkSync(filePath); vfs.umount(mountPoint); } }); });