diff options
Diffstat (limited to 'tests/cache-lock.test.ts')
| -rw-r--r-- | tests/cache-lock.test.ts | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/tests/cache-lock.test.ts b/tests/cache-lock.test.ts new file mode 100644 index 0000000..c67ba01 --- /dev/null +++ b/tests/cache-lock.test.ts @@ -0,0 +1,141 @@ +import { test, expect } from 'bun:test'; +import { generateInstanceId } from '../scripts/cache/lock'; +import type { CacheLock } from '../scripts/cache/utils'; + +test('generateInstanceId returns non-empty string', () => { + const id = generateInstanceId(); + expect(typeof id).toBe('string'); + expect(id.length).toBeGreaterThan(0); +}); + +test('generateInstanceId includes timestamp', () => { + const before = Date.now(); + const id = generateInstanceId(); + const after = Date.now(); + + const timestampPart = id.split('-')[0]; + const timestamp = parseInt(timestampPart, 10); + + expect(timestamp).toBeGreaterThanOrEqual(before); + expect(timestamp).toBeLessThanOrEqual(after); +}); + +test('generateInstanceId includes random component', () => { + const id1 = generateInstanceId(); + const id2 = generateInstanceId(); + + expect(id1).not.toBe(id2); +}); + +test('generateInstanceId format is timestamp-randomstring', () => { + const id = generateInstanceId(); + const parts = id.split('-'); + expect(parts.length).toBe(2); + + const [timestamp, random] = parts; + expect(timestamp).toMatch(/^\d+$/); + expect(random).toMatch(/^[a-z0-9]+$/); + expect(random.length).toBeGreaterThan(0); + expect(random.length).toBeLessThan(10); +}); + +// Helper function to test isLockStale logic (since it's private) +function isLockStale(lock: CacheLock, currentHostname: string): boolean { + const lockAge = Date.now() - lock.timestamp; + const timeSinceRenewal = lock.renewedAt ? Date.now() - lock.renewedAt : lockAge; + + // Check 1: Timestamp-based staleness (30 minutes) + if (timeSinceRenewal > 30 * 60 * 1000) { + return true; + } + + // Check 2: Process-based staleness (only on same machine) + if (lock.hostname === currentHostname) { + // For testing, assume process doesn't exist if pid is -1 + if (lock.pid === -1) { + return true; + } + } + + return false; +} + +test('isLockStale returns true for old lock (over 30 minutes)', () => { + const lock: CacheLock = { + locked: true, + timestamp: Date.now() - 31 * 60 * 1000, // 31 minutes ago + instance: 'test-instance', + ttl: 30 * 60 * 1000, + pid: 12345, + hostname: 'test-host' + }; + + expect(isLockStale(lock, 'test-host')).toBe(true); +}); + +test('isLockStale returns false for recent lock (under 30 minutes)', () => { + const lock: CacheLock = { + locked: true, + timestamp: Date.now() - 29 * 60 * 1000, // 29 minutes ago + instance: 'test-instance', + ttl: 30 * 60 * 1000, + pid: 12345, + hostname: 'test-host' + }; + + expect(isLockStale(lock, 'test-host')).toBe(false); +}); + +test('isLockStale respects renewedAt timestamp', () => { + const now = Date.now(); + const lock: CacheLock = { + locked: true, + timestamp: now - 40 * 60 * 1000, // 40 minutes ago + instance: 'test-instance', + ttl: 30 * 60 * 1000, + renewedAt: now - 10 * 60 * 1000, // Renewed 10 minutes ago + pid: 12345, + hostname: 'test-host' + }; + + expect(isLockStale(lock, 'test-host')).toBe(false); +}); + +test('isLockStale returns true when lock on same host but process dead', () => { + const lock: CacheLock = { + locked: true, + timestamp: Date.now() - 10 * 60 * 1000, // 10 minutes ago + instance: 'test-instance', + ttl: 30 * 60 * 1000, + pid: -1, // Simulate dead process + hostname: 'test-host' + }; + + expect(isLockStale(lock, 'test-host')).toBe(true); +}); + +test('isLockStale returns false when lock on different host (even if old process)', () => { + const lock: CacheLock = { + locked: true, + timestamp: Date.now() - 10 * 60 * 1000, + instance: 'test-instance', + ttl: 30 * 60 * 1000, + pid: -1, + hostname: 'different-host' + }; + + expect(isLockStale(lock, 'test-host')).toBe(false); +}); + +test('isLockStale handles missing renewedAt', () => { + const lock: CacheLock = { + locked: true, + timestamp: Date.now() - 35 * 60 * 1000, // 35 minutes ago + instance: 'test-instance', + ttl: 30 * 60 * 1000, + pid: 12345, + hostname: 'test-host' + }; + + expect(isLockStale(lock, 'test-host')).toBe(true); +}); |
