cleanup-test-dbs.test.js
1 /** 2 * Tests for cleanup-test-dbs cron job 3 * 4 * Tests runCleanupTestDbs() using real /tmp filesystem. 5 * Verifies it deletes stale test DB files matching known patterns. 6 */ 7 8 import { test, describe, before, after } from 'node:test'; 9 import assert from 'node:assert/strict'; 10 import { mkdirSync, writeFileSync, existsSync, rmSync, utimesSync } from 'fs'; 11 import { join } from 'path'; 12 13 import { runCleanupTestDbs } from '../../src/cron/cleanup-test-dbs.js'; 14 15 // ─── Helpers ──────────────────────────────────────────────────────────────── 16 17 const TEST_TMP_DIR = `/tmp/test-cleanup-cron-${process.pid}`; 18 19 /** 20 * Create a fake .db file directly in /tmp (where runCleanupTestDbs scans) 21 */ 22 function createDb(filename, ageMins = 120) { 23 const p = join('/tmp', filename); 24 writeFileSync(p, 'x'.repeat(1024)); 25 // Set mtime in the past 26 const mtime = new Date(Date.now() - ageMins * 60 * 1000); 27 utimesSync(p, mtime, mtime); 28 return p; 29 } 30 31 // ─── Setup ─────────────────────────────────────────────────────────────────── 32 33 before(() => { 34 mkdirSync(TEST_TMP_DIR, { recursive: true }); 35 }); 36 37 after(() => { 38 rmSync(TEST_TMP_DIR, { recursive: true, force: true }); 39 }); 40 41 // ─── Tests ─────────────────────────────────────────────────────────────────── 42 43 describe('runCleanupTestDbs', () => { 44 test('returns zero stats when no test DBs exist', () => { 45 const result = runCleanupTestDbs(); 46 assert.ok(typeof result.deleted === 'number'); 47 assert.ok(typeof result.freed_kb === 'number'); 48 }); 49 50 test('returns correct shape', () => { 51 const result = runCleanupTestDbs(); 52 assert.ok('deleted' in result, 'should have deleted field'); 53 assert.ok('freed_kb' in result, 'should have freed_kb field'); 54 }); 55 56 test('isTestDb: matches known test DB patterns', () => { 57 // These files have the right patterns and are old enough (2h+) 58 // We create them in /tmp which IS scanned by runCleanupTestDbs 59 const files = [ 60 createDb('test-monitor-12345.db', 180), 61 createDb('test-qa-98765.db', 180), 62 createDb('test-runner-coverage.db', 180), 63 createDb('test-architect-abc.db', 180), 64 createDb('test-developer-xyz.db', 180), 65 createDb('test-triage-foo.db', 180), 66 createDb('test-security-bar.db', 180), 67 createDb('test-sites-2024.db', 180), 68 ]; 69 70 // These files should be deleted 71 const result = runCleanupTestDbs(); 72 assert.ok( 73 result.deleted >= files.length, 74 `Expected at least ${files.length} deleted, got ${result.deleted}` 75 ); 76 assert.ok(result.freed_kb >= 0, 'freed_kb should be non-negative'); 77 78 // Verify files are actually gone 79 for (const f of files) { 80 assert.ok(!existsSync(f), `Expected ${f} to be deleted`); 81 } 82 }); 83 84 test('ignores non-test DB files', () => { 85 // Create non-matching files in /tmp 86 const nonTest = join('/tmp', `not-a-test-db-${process.pid}.db`); 87 writeFileSync(nonTest, 'data'); 88 const mtime = new Date(Date.now() - 200 * 60 * 1000); 89 utimesSync(nonTest, mtime, mtime); 90 91 const resultBefore = runCleanupTestDbs(); 92 // File should still exist since it doesn't match test DB patterns 93 assert.ok(existsSync(nonTest), 'Non-test DB should not be deleted'); 94 95 // Cleanup manually 96 rmSync(nonTest, { force: true }); 97 }); 98 99 test('ignores files younger than 1 hour', () => { 100 // Create a fresh test DB (5 minutes old) — should NOT be deleted 101 const fresh = join('/tmp', `test-sites-fresh-${process.pid}-${Date.now()}.db`); 102 writeFileSync(fresh, 'data'); 103 const mtime = new Date(Date.now() - 5 * 60 * 1000); // 5 min old 104 utimesSync(fresh, mtime, mtime); 105 106 runCleanupTestDbs(); 107 108 assert.ok(existsSync(fresh), 'Fresh test DB should NOT be deleted (< 1 hour old)'); 109 110 // Cleanup 111 rmSync(fresh, { force: true }); 112 }); 113 114 test('handles non-existent directories gracefully', () => { 115 // /tmp always exists but tests/ dir may or may not have test DBs 116 // runCleanupTestDbs scans tests/, tests/agents/, /tmp — should never throw 117 assert.doesNotThrow(() => runCleanupTestDbs()); 118 }); 119 });