fix(rustdb-storage): detect stale hint files using data file size metadata and add restart persistence regression tests
This commit is contained in:
82
test/test.stale-sockets.ts
Normal file
82
test/test.stale-sockets.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as smartdb from '../ts/index.js';
|
||||
import * as fs from 'fs';
|
||||
import * as net from 'net';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test: Stale socket cleanup on startup
|
||||
// Covers: LocalSmartDb.cleanStaleSockets(), isSocketAlive()
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function makeTmpDir(): string {
|
||||
return fs.mkdtempSync(path.join(os.tmpdir(), 'smartdb-socket-test-'));
|
||||
}
|
||||
|
||||
function cleanTmpDir(dir: string): void {
|
||||
if (fs.existsSync(dir)) {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Stale socket cleanup: active sockets are preserved
|
||||
// ============================================================================
|
||||
|
||||
tap.test('stale-sockets: does not remove active sockets', async () => {
|
||||
const tmpDir = makeTmpDir();
|
||||
const activeSocketPath = path.join(os.tmpdir(), `smartdb-active-${Date.now()}.sock`);
|
||||
|
||||
// Create an active socket (server still listening)
|
||||
const activeServer = net.createServer();
|
||||
await new Promise<void>((resolve) => activeServer.listen(activeSocketPath, resolve));
|
||||
|
||||
expect(fs.existsSync(activeSocketPath)).toBeTrue();
|
||||
|
||||
// Start LocalSmartDb — should NOT remove the active socket
|
||||
const localDb = new smartdb.LocalSmartDb({ folderPath: tmpDir });
|
||||
await localDb.start();
|
||||
|
||||
expect(fs.existsSync(activeSocketPath)).toBeTrue();
|
||||
|
||||
// Cleanup
|
||||
await localDb.stop();
|
||||
await new Promise<void>((resolve) => activeServer.close(() => resolve()));
|
||||
try { fs.unlinkSync(activeSocketPath); } catch {}
|
||||
cleanTmpDir(tmpDir);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Stale socket cleanup: startup works with no stale sockets
|
||||
// ============================================================================
|
||||
|
||||
tap.test('stale-sockets: startup works cleanly with no stale sockets', async () => {
|
||||
const tmpDir = makeTmpDir();
|
||||
const localDb = new smartdb.LocalSmartDb({ folderPath: tmpDir });
|
||||
const info = await localDb.start();
|
||||
expect(localDb.running).toBeTrue();
|
||||
expect(info.socketPath).toBeTruthy();
|
||||
await localDb.stop();
|
||||
cleanTmpDir(tmpDir);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Stale socket cleanup: the socket file for the current instance is cleaned on stop
|
||||
// ============================================================================
|
||||
|
||||
tap.test('stale-sockets: own socket file is removed on stop', async () => {
|
||||
const tmpDir = makeTmpDir();
|
||||
const localDb = new smartdb.LocalSmartDb({ folderPath: tmpDir });
|
||||
const info = await localDb.start();
|
||||
|
||||
expect(fs.existsSync(info.socketPath)).toBeTrue();
|
||||
|
||||
await localDb.stop();
|
||||
|
||||
// Socket file should be gone after graceful stop
|
||||
expect(fs.existsSync(info.socketPath)).toBeFalse();
|
||||
cleanTmpDir(tmpDir);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
Reference in New Issue
Block a user