Add Prettier and ESLint tooling (Refs #77)
This commit is contained in:
@@ -7,67 +7,103 @@ import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
import { enableIncrementalVacuum } from '../../src/lib/server/db/retention-clocks.js';
|
||||
|
||||
let fixture: Fixture;
|
||||
beforeEach(async () => { vi.resetModules(); fixture = await newFixture([]); });
|
||||
afterEach(async () => { vi.restoreAllMocks(); vi.unstubAllEnvs(); await fixture.cleanup(); });
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
fixture = await newFixture([]);
|
||||
});
|
||||
afterEach(async () => {
|
||||
vi.restoreAllMocks();
|
||||
vi.unstubAllEnvs();
|
||||
await fixture.cleanup();
|
||||
});
|
||||
|
||||
it('keeps a 256 MiB database rebuild below a 160 MiB increase in resident memory', async () => {
|
||||
const helper = fileURLToPath(new URL('../helpers/vacuum-memory.ts', import.meta.url));
|
||||
const { stdout } = await promisify(execFile)(process.execPath, ['--import', 'tsx', helper, fixture.dbPath], { timeout: 60000 });
|
||||
const { stdout } = await promisify(execFile)(
|
||||
process.execPath,
|
||||
['--import', 'tsx', helper, fixture.dbPath],
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
const result = JSON.parse(stdout.trim().split('\n').at(-1)!);
|
||||
expect(result).toMatchObject({ vacuum: 2, integrity: 'ok', rows: { n: 256 } });
|
||||
expect(result.peakKiB - result.beforeKiB).toBeLessThan(160 * 1024);
|
||||
}, 65000);
|
||||
|
||||
it.each(['before', 'after'])('recovers a rebuild interrupted %s copying without losing host preparation boundaries', mode => {
|
||||
let handle = new Database(fixture.dbPath);
|
||||
try {
|
||||
handle.exec(`CREATE TABLE ec_host_operations(id TEXT,host_id TEXT);
|
||||
it.each(['before', 'after'])(
|
||||
'recovers a rebuild interrupted %s copying without losing host preparation boundaries',
|
||||
(mode) => {
|
||||
let handle = new Database(fixture.dbPath);
|
||||
try {
|
||||
handle.exec(`CREATE TABLE ec_host_operations(id TEXT,host_id TEXT);
|
||||
CREATE TABLE ec_host_enable_requests(host_id TEXT,operation_floor INTEGER);
|
||||
INSERT INTO ec_host_operations(rowid,id,host_id) VALUES(10,'before','host'),(30,'after','host');
|
||||
INSERT INTO ec_host_enable_requests VALUES('host',20)`);
|
||||
handle.pragma('temp_store = MEMORY'); handle.pragma('cache_size = -131072');
|
||||
const exec = handle.exec.bind(handle);
|
||||
const mock = vi.spyOn(handle, 'exec').mockImplementation(sql => {
|
||||
if (sql === 'VACUUM') {
|
||||
expect(handle.pragma('temp_store', { simple: true })).toBe(1);
|
||||
expect(handle.pragma('cache_size', { simple: true })).toBe(-16384);
|
||||
if (mode === 'after') exec(sql);
|
||||
throw new Error('simulated interruption');
|
||||
}
|
||||
return exec(sql);
|
||||
});
|
||||
expect(() => enableIncrementalVacuum(handle)).toThrow('simulated interruption');
|
||||
mock.mockRestore();
|
||||
expect(handle.pragma('temp_store', { simple: true })).toBe(2);
|
||||
expect(handle.pragma('cache_size', { simple: true })).toBe(-131072);
|
||||
handle.close(); handle = new Database(fixture.dbPath);
|
||||
enableIncrementalVacuum(handle);
|
||||
expect(handle.pragma('auto_vacuum', { simple: true })).toBe(2);
|
||||
expect(handle.prepare(`SELECT o.id FROM ec_host_operations o JOIN ec_host_enable_requests e ON e.host_id=o.host_id
|
||||
WHERE o.rowid>e.operation_floor`).all()).toEqual([{ id: 'after' }]);
|
||||
expect(handle.prepare("SELECT 1 FROM sqlite_master WHERE name='database_vacuum_boundaries'").get()).toBeUndefined();
|
||||
expect(handle.pragma('quick_check', { simple: true })).toBe('ok');
|
||||
} finally { handle.close(); }
|
||||
});
|
||||
handle.pragma('temp_store = MEMORY');
|
||||
handle.pragma('cache_size = -131072');
|
||||
const exec = handle.exec.bind(handle);
|
||||
const mock = vi.spyOn(handle, 'exec').mockImplementation((sql) => {
|
||||
if (sql === 'VACUUM') {
|
||||
expect(handle.pragma('temp_store', { simple: true })).toBe(1);
|
||||
expect(handle.pragma('cache_size', { simple: true })).toBe(-16384);
|
||||
if (mode === 'after') exec(sql);
|
||||
throw new Error('simulated interruption');
|
||||
}
|
||||
return exec(sql);
|
||||
});
|
||||
expect(() => enableIncrementalVacuum(handle)).toThrow('simulated interruption');
|
||||
mock.mockRestore();
|
||||
expect(handle.pragma('temp_store', { simple: true })).toBe(2);
|
||||
expect(handle.pragma('cache_size', { simple: true })).toBe(-131072);
|
||||
handle.close();
|
||||
handle = new Database(fixture.dbPath);
|
||||
enableIncrementalVacuum(handle);
|
||||
expect(handle.pragma('auto_vacuum', { simple: true })).toBe(2);
|
||||
expect(
|
||||
handle
|
||||
.prepare(
|
||||
`SELECT o.id FROM ec_host_operations o JOIN ec_host_enable_requests e ON e.host_id=o.host_id
|
||||
WHERE o.rowid>e.operation_floor`
|
||||
)
|
||||
.all()
|
||||
).toEqual([{ id: 'after' }]);
|
||||
expect(
|
||||
handle
|
||||
.prepare("SELECT 1 FROM sqlite_master WHERE name='database_vacuum_boundaries'")
|
||||
.get()
|
||||
).toBeUndefined();
|
||||
expect(handle.pragma('quick_check', { simple: true })).toBe('ok');
|
||||
} finally {
|
||||
handle.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
it('uses migration settings before startup writes and restores runtime tuning only after the rebuild', async () => {
|
||||
const legacy = new Database(fixture.dbPath);
|
||||
legacy.exec('CREATE TABLE legacy(id INTEGER PRIMARY KEY, content BLOB); INSERT INTO legacy(content) VALUES(zeroblob(1024))');
|
||||
legacy.exec(
|
||||
'CREATE TABLE legacy(id INTEGER PRIMARY KEY, content BLOB); INSERT INTO legacy(content) VALUES(zeroblob(1024))'
|
||||
);
|
||||
legacy.close();
|
||||
vi.stubEnv('EC_SQLITE_MMAP_MB', '256');
|
||||
const exec = Database.prototype.exec;
|
||||
let rebuilt = false, migrated = false;
|
||||
const mock = vi.spyOn(Database.prototype, 'exec').mockImplementation(function(this: Database.Database, sql) {
|
||||
let rebuilt = false,
|
||||
migrated = false;
|
||||
const mock = vi.spyOn(Database.prototype, 'exec').mockImplementation(function (
|
||||
this: Database.Database,
|
||||
sql
|
||||
) {
|
||||
if (sql === 'VACUUM' || sql.includes('CREATE TABLE IF NOT EXISTS file_blobs')) {
|
||||
expect(this.pragma('temp_store', { simple: true })).toBe(1);
|
||||
expect(this.pragma('cache_size', { simple: true })).toBe(-16384);
|
||||
expect(this.pragma('mmap_size', { simple: true })).toBe(0);
|
||||
if (sql === 'VACUUM') rebuilt = true; else migrated = true;
|
||||
if (sql === 'VACUUM') rebuilt = true;
|
||||
else migrated = true;
|
||||
}
|
||||
return exec.call(this, sql);
|
||||
});
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const handle = db(); mock.mockRestore();
|
||||
const handle = db();
|
||||
mock.mockRestore();
|
||||
expect(rebuilt && migrated).toBe(true);
|
||||
expect(handle.pragma('temp_store', { simple: true })).toBe(1);
|
||||
expect(handle.pragma('cache_size', { simple: true })).toBe(-131072);
|
||||
|
||||
Reference in New Issue
Block a user