162 lines
6.2 KiB
JavaScript
162 lines
6.2 KiB
JavaScript
/**
|
|
* Unit tests for tmp-cleanup.js -- orphaned temp files + stale Firefox profiles.
|
|
*/
|
|
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import os from 'os';
|
|
import { cleanupOrphanedTempFiles, cleanupStaleFirefoxProfiles } from '../../lib/tmp-cleanup.js';
|
|
|
|
function makeTmpDir() {
|
|
return fs.mkdtempSync(path.join(os.tmpdir(), 'camofox-test-'));
|
|
}
|
|
|
|
describe('cleanupOrphanedTempFiles', () => {
|
|
it('removes old orphaned .so files', () => {
|
|
const dir = makeTmpDir();
|
|
const name = '.fea5abcdef1234.so';
|
|
const full = path.join(dir, name);
|
|
fs.writeFileSync(full, 'data');
|
|
// Set mtime to 10 minutes ago
|
|
const oldTime = new Date(Date.now() - 10 * 60 * 1000);
|
|
fs.utimesSync(full, oldTime, oldTime);
|
|
|
|
const result = cleanupOrphanedTempFiles({ tmpDir: dir, minAgeMs: 5 * 60 * 1000 });
|
|
expect(result.removed).toBe(1);
|
|
expect(fs.existsSync(full)).toBe(false);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('skips recent orphaned files', () => {
|
|
const dir = makeTmpDir();
|
|
const name = '.fea5abcdef1234.so';
|
|
const full = path.join(dir, name);
|
|
fs.writeFileSync(full, 'data');
|
|
// mtime is now (recent)
|
|
|
|
const result = cleanupOrphanedTempFiles({ tmpDir: dir, minAgeMs: 5 * 60 * 1000 });
|
|
expect(result.removed).toBe(0);
|
|
expect(result.skipped).toBe(1);
|
|
expect(fs.existsSync(full)).toBe(true);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('ignores non-matching files', () => {
|
|
const dir = makeTmpDir();
|
|
fs.writeFileSync(path.join(dir, 'normal-file.txt'), 'data');
|
|
fs.writeFileSync(path.join(dir, '.fea5.so'), 'data'); // too short hex
|
|
fs.writeFileSync(path.join(dir, '.fea5abc.txt'), 'data'); // wrong extension
|
|
const result = cleanupOrphanedTempFiles({ tmpDir: dir });
|
|
expect(result.scanned).toBe(0);
|
|
expect(result.removed).toBe(0);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('returns zeros for nonexistent tmpDir', () => {
|
|
const result = cleanupOrphanedTempFiles({ tmpDir: '/tmp/camofox-nonexistent-xyz' });
|
|
expect(result).toEqual({ scanned: 0, removed: 0, bytes: 0, skipped: 0 });
|
|
});
|
|
|
|
it('supports injected now for deterministic age comparison', () => {
|
|
const dir = makeTmpDir();
|
|
const full = path.join(dir, '.fea5abc123.so');
|
|
fs.writeFileSync(full, 'x'.repeat(10));
|
|
const mtimeMs = fs.statSync(full).mtimeMs;
|
|
|
|
// 1 min after mtime: still fresh
|
|
const fresh = cleanupOrphanedTempFiles({ tmpDir: dir, minAgeMs: 5 * 60 * 1000, now: mtimeMs + 60 * 1000 });
|
|
expect(fresh.removed).toBe(0);
|
|
expect(fresh.skipped).toBe(1);
|
|
|
|
// 10 min after mtime: stale
|
|
const stale = cleanupOrphanedTempFiles({ tmpDir: dir, minAgeMs: 5 * 60 * 1000, now: mtimeMs + 10 * 60 * 1000 });
|
|
expect(stale.removed).toBe(1);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
});
|
|
|
|
describe('cleanupStaleFirefoxProfiles', () => {
|
|
it('removes old playwright_firefoxdev_profile- directories', () => {
|
|
const dir = makeTmpDir();
|
|
const profileDir = path.join(dir, 'playwright_firefoxdev_profile-abc123');
|
|
fs.mkdirSync(profileDir);
|
|
fs.writeFileSync(path.join(profileDir, 'cache.db'), 'x'.repeat(1000));
|
|
fs.writeFileSync(path.join(profileDir, 'prefs.js'), 'data');
|
|
// Set mtime to 5 minutes ago
|
|
const oldTime = new Date(Date.now() - 5 * 60 * 1000);
|
|
fs.utimesSync(profileDir, oldTime, oldTime);
|
|
|
|
const result = cleanupStaleFirefoxProfiles({ tmpDir: dir, minAgeMs: 2 * 60 * 1000 });
|
|
expect(result.removed).toBe(1);
|
|
expect(result.bytes).toBeGreaterThan(0);
|
|
expect(fs.existsSync(profileDir)).toBe(false);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('skips recent profile directories', () => {
|
|
const dir = makeTmpDir();
|
|
const profileDir = path.join(dir, 'playwright_firefoxdev_profile-recent');
|
|
fs.mkdirSync(profileDir);
|
|
fs.writeFileSync(path.join(profileDir, 'data.db'), 'data');
|
|
// mtime is now (recent)
|
|
|
|
const result = cleanupStaleFirefoxProfiles({ tmpDir: dir, minAgeMs: 2 * 60 * 1000 });
|
|
expect(result.removed).toBe(0);
|
|
expect(result.skipped).toBe(1);
|
|
expect(fs.existsSync(profileDir)).toBe(true);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('removes camoufox- prefixed temp dirs', () => {
|
|
const dir = makeTmpDir();
|
|
const camoDir = path.join(dir, 'camoufox-session-xyz');
|
|
fs.mkdirSync(camoDir);
|
|
fs.writeFileSync(path.join(camoDir, 'state'), 'data');
|
|
const oldTime = new Date(Date.now() - 5 * 60 * 1000);
|
|
fs.utimesSync(camoDir, oldTime, oldTime);
|
|
|
|
const result = cleanupStaleFirefoxProfiles({ tmpDir: dir, minAgeMs: 2 * 60 * 1000 });
|
|
expect(result.removed).toBe(1);
|
|
expect(fs.existsSync(camoDir)).toBe(false);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('calculates byte count of removed directories', () => {
|
|
const dir = makeTmpDir();
|
|
const profileDir = path.join(dir, 'playwright_firefoxdev_profile-sizeme');
|
|
fs.mkdirSync(profileDir);
|
|
const subDir = path.join(profileDir, 'cache2');
|
|
fs.mkdirSync(subDir);
|
|
fs.writeFileSync(path.join(subDir, 'big.dat'), 'x'.repeat(5000));
|
|
fs.writeFileSync(path.join(profileDir, 'small.dat'), 'x'.repeat(100));
|
|
const oldTime = new Date(Date.now() - 5 * 60 * 1000);
|
|
fs.utimesSync(profileDir, oldTime, oldTime);
|
|
|
|
const result = cleanupStaleFirefoxProfiles({ tmpDir: dir, minAgeMs: 2 * 60 * 1000 });
|
|
expect(result.removed).toBe(1);
|
|
expect(result.bytes).toBe(5100);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('ignores non-matching directories', () => {
|
|
const dir = makeTmpDir();
|
|
fs.mkdirSync(path.join(dir, 'some-other-dir'));
|
|
const result = cleanupStaleFirefoxProfiles({ tmpDir: dir });
|
|
expect(result.scanned).toBe(0);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('handles empty tmpDir', () => {
|
|
const dir = makeTmpDir();
|
|
const result = cleanupStaleFirefoxProfiles({ tmpDir: dir });
|
|
expect(result.scanned).toBe(0);
|
|
expect(result.removed).toBe(0);
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('handles nonexistent tmpDir gracefully', () => {
|
|
const result = cleanupStaleFirefoxProfiles({ tmpDir: '/tmp/camofox-nonexistent-dir-xyz' });
|
|
expect(result.scanned).toBe(0);
|
|
});
|
|
});
|