/** * Layer 6: Runtime Unit Tests * * Tests for runtime infrastructure: RealmRegistry, ShardAllocator, etc. */ import test from 'node:test'; import assert from 'node:assert/strict'; import { RealmRegistry, type RealmEndpoint } from '@open-matrix/federation/runtime/realm_registry'; import { ShardAllocator, DEFAULT_SHARD, allocateShardForTab, getGlobalShardAllocator, } from '@open-matrix/federation/runtime/shard_allocator'; // ============================================================================ // RealmRegistry Tests // ============================================================================ test('RealmRegistry: register and resolve single endpoint', () => { const registry = new RealmRegistry(); registry.register('acme.com', [ { type: 'nats', url: 'nats://broker.acme.com', priority: 0 }, ]); const endpoint = registry.resolve('acme.com'); assert.ok(endpoint !== null); assert.equal(endpoint.type, 'nats'); assert.equal(endpoint.url, 'nats://broker.acme.com'); assert.equal(endpoint.priority, 0); }); test('RealmRegistry: resolve returns highest priority endpoint', () => { const registry = new RealmRegistry(); registry.register('example.com', [ { type: 'ws', url: 'ws://secondary.example.com', priority: 10 }, { type: 'nats', url: 'nats://primary.example.com', priority: 0 }, { type: 'wss', url: 'wss://backup.example.com', priority: 20 }, ]); const endpoint = registry.resolve('example.com'); assert.ok(endpoint !== null); assert.equal(endpoint.priority, 0); assert.equal(endpoint.url, 'nats://primary.example.com'); }); test('RealmRegistry: resolveAll returns sorted endpoints', () => { const registry = new RealmRegistry(); registry.register('multi.com', [ { type: 'wss', url: 'wss://c.multi.com', priority: 30 }, { type: 'ws', url: 'ws://a.multi.com', priority: 10 }, { type: 'nats', url: 'nats://b.multi.com', priority: 20 }, ]); const endpoints = registry.resolveAll('multi.com'); assert.equal(endpoints.length, 3); assert.equal(endpoints[0].priority, 10); assert.equal(endpoints[1].priority, 20); assert.equal(endpoints[2].priority, 30); }); test('RealmRegistry: resolve returns null for unknown realm', () => { const registry = new RealmRegistry(); const endpoint = registry.resolve('unknown.realm'); assert.equal(endpoint, null); }); test('RealmRegistry: resolveAll returns empty array for unknown realm', () => { const registry = new RealmRegistry(); const endpoints = registry.resolveAll('unknown.realm'); assert.deepEqual(endpoints, []); }); test('RealmRegistry: has() checks realm registration', () => { const registry = new RealmRegistry(); assert.equal(registry.has('test.com'), false); registry.register('test.com', [ { type: 'nats', url: 'nats://test.com', priority: 0 }, ]); assert.equal(registry.has('test.com'), true); assert.equal(registry.has('other.com'), false); }); test('RealmRegistry: realms() lists all registered realms', () => { const registry = new RealmRegistry(); registry.register('alpha.com', [{ type: 'nats', url: 'nats://alpha.com', priority: 0 }]); registry.register('beta.com', [{ type: 'nats', url: 'nats://beta.com', priority: 0 }]); registry.register('gamma.com', [{ type: 'nats', url: 'nats://gamma.com', priority: 0 }]); const realms = registry.realms(); assert.equal(realms.length, 3); assert.ok(realms.includes('alpha.com')); assert.ok(realms.includes('beta.com')); assert.ok(realms.includes('gamma.com')); }); test('RealmRegistry: register merges endpoints', () => { const registry = new RealmRegistry(); // Register initial endpoint registry.register('merge.com', [ { type: 'nats', url: 'nats://a.merge.com', priority: 10 }, ]); // Register additional endpoint registry.register('merge.com', [ { type: 'ws', url: 'ws://b.merge.com', priority: 5 }, ]); const endpoints = registry.resolveAll('merge.com'); assert.equal(endpoints.length, 2); // ws has higher priority (lower number) assert.equal(endpoints[0].type, 'ws'); assert.equal(endpoints[1].type, 'nats'); }); test('RealmRegistry: register updates existing endpoint by type+url', () => { const registry = new RealmRegistry(); registry.register('update.com', [ { type: 'nats', url: 'nats://broker.update.com', priority: 10 }, ]); // Update same type+url with different priority registry.register('update.com', [ { type: 'nats', url: 'nats://broker.update.com', priority: 5, shard: '01' }, ]); const endpoints = registry.resolveAll('update.com'); assert.equal(endpoints.length, 1); assert.equal(endpoints[0].priority, 5); assert.equal(endpoints[0].shard, '01'); }); test('RealmRegistry: deregister removes entire realm', () => { const registry = new RealmRegistry(); registry.register('remove.com', [ { type: 'nats', url: 'nats://remove.com', priority: 0 }, { type: 'ws', url: 'ws://remove.com', priority: 1 }, ]); assert.equal(registry.has('remove.com'), true); registry.deregister('remove.com'); assert.equal(registry.has('remove.com'), false); assert.equal(registry.resolve('remove.com'), null); }); test('RealmRegistry: deregister removes specific endpoint', () => { const registry = new RealmRegistry(); registry.register('partial.com', [ { type: 'nats', url: 'nats://a.partial.com', priority: 0 }, { type: 'ws', url: 'ws://b.partial.com', priority: 1 }, ]); registry.deregister('partial.com', { type: 'nats', url: 'nats://a.partial.com', priority: 0 }); const endpoints = registry.resolveAll('partial.com'); assert.equal(endpoints.length, 1); assert.equal(endpoints[0].type, 'ws'); }); test('RealmRegistry: deregister last endpoint removes realm', () => { const registry = new RealmRegistry(); registry.register('single.com', [ { type: 'nats', url: 'nats://single.com', priority: 0 }, ]); registry.deregister('single.com', { type: 'nats', url: 'nats://single.com', priority: 0 }); assert.equal(registry.has('single.com'), false); }); test('RealmRegistry: watch notifies on changes', () => { const registry = new RealmRegistry(); const notifications: RealmEndpoint[][] = []; const unsub = registry.watch('watch.com', (endpoints) => { notifications.push([...endpoints]); }); // Register registry.register('watch.com', [ { type: 'nats', url: 'nats://watch.com', priority: 0 }, ]); assert.equal(notifications.length, 1); assert.equal(notifications[0].length, 1); // Add another endpoint registry.register('watch.com', [ { type: 'ws', url: 'ws://watch.com', priority: 1 }, ]); assert.equal(notifications.length, 2); assert.equal(notifications[1].length, 2); // Deregister registry.deregister('watch.com'); assert.equal(notifications.length, 3); assert.equal(notifications[2].length, 0); unsub(); }); test('RealmRegistry: watch unsub stops notifications', () => { const registry = new RealmRegistry(); let notificationCount = 0; const unsub = registry.watch('unsub.com', () => { notificationCount++; }); registry.register('unsub.com', [{ type: 'nats', url: 'nats://unsub.com', priority: 0 }]); assert.equal(notificationCount, 1); unsub(); registry.register('unsub.com', [{ type: 'ws', url: 'ws://unsub.com', priority: 1 }]); assert.equal(notificationCount, 1); // No change after unsub }); test('RealmRegistry: resolve uses cache', () => { const registry = new RealmRegistry(); registry.register('cache.com', [ { type: 'nats', url: 'nats://cache.com', priority: 0 }, ]); const first = registry.resolve('cache.com'); const second = registry.resolve('cache.com'); // Both should return the same object (cached) assert.equal(first, second); }); test('RealmRegistry: register invalidates cache', () => { const registry = new RealmRegistry(); registry.register('invalidate.com', [ { type: 'nats', url: 'nats://old.invalidate.com', priority: 10 }, ]); const before = registry.resolve('invalidate.com'); assert.equal(before?.url, 'nats://old.invalidate.com'); // Register new higher-priority endpoint registry.register('invalidate.com', [ { type: 'nats', url: 'nats://new.invalidate.com', priority: 0 }, ]); const after = registry.resolve('invalidate.com'); assert.equal(after?.url, 'nats://new.invalidate.com'); }); // ============================================================================ // ShardAllocator Tests // ============================================================================ test('ShardAllocator: allocate always returns DEFAULT_SHARD', () => { const allocator = new ShardAllocator(); // Different realms should all get same shard (single-shard model) assert.equal(allocator.allocate('realm-1'), DEFAULT_SHARD); assert.equal(allocator.allocate('realm-2'), DEFAULT_SHARD); assert.equal(allocator.allocate('realm-3'), DEFAULT_SHARD); }); test('ShardAllocator: get always returns DEFAULT_SHARD', () => { const allocator = new ShardAllocator(); assert.equal(allocator.get('any-realm'), DEFAULT_SHARD); assert.equal(allocator.get('another-realm'), DEFAULT_SHARD); }); test('ShardAllocator: release is no-op', () => { const allocator = new ShardAllocator(); // Should not throw allocator.release('realm'); allocator.release('nonexistent'); // Get still works assert.equal(allocator.get('realm'), DEFAULT_SHARD); }); test('ShardAllocator: allocations returns empty map (single-shard model)', () => { const allocator = new ShardAllocator(); allocator.allocate('realm-1'); allocator.allocate('realm-2'); // Single-shard model doesn't track allocations const allocations = allocator.allocations(); assert.equal(allocations.size, 0); }); test('DEFAULT_SHARD is "00"', () => { assert.equal(DEFAULT_SHARD, '00'); }); test('allocateShardForTab always returns DEFAULT_SHARD', () => { assert.equal(allocateShardForTab('flowpad'), DEFAULT_SHARD); assert.equal(allocateShardForTab('flowpad.tab-abc'), DEFAULT_SHARD); assert.equal(allocateShardForTab('matrix-3'), DEFAULT_SHARD); }); test('getGlobalShardAllocator returns singleton', () => { const a1 = getGlobalShardAllocator(); const a2 = getGlobalShardAllocator(); assert.equal(a1, a2); }); // ============================================================================ // TransportSelector Tests (if exported) // ============================================================================ test('TransportSelector: disabled mode returns memory endpoint', async () => { const { TransportSelector } = await import('../../src/runtime/transport_selector'); const registry = new RealmRegistry(); // In 'disabled' mode, always returns memory endpoint const selector = new TransportSelector(registry, 'disabled'); const endpoint = await selector.select('any.realm'); assert.equal(endpoint.type, 'memory'); assert.equal(endpoint.url, ''); }); test('TransportSelector: auto mode checks registry first', async () => { const { TransportSelector } = await import('../../src/runtime/transport_selector'); const registry = new RealmRegistry(); // Register an endpoint registry.register('selectable.com', [ { type: 'nats', url: 'nats://selectable.com', priority: 0 }, ]); // In auto mode, it will check registry and probe // Since we can't easily probe NATS in tests, just verify getCandidates behavior const selector = new TransportSelector(registry, 'auto'); // Auto mode with no working probes falls back to memory const endpoint = await selector.select('selectable.com'); // Falls back to memory since NATS probe fails without real server assert.equal(endpoint.type, 'memory'); }); // ============================================================================ // TransportPool Tests // ============================================================================ test('TransportPool: stores and retrieves transport', async () => { const { TransportPool } = await import('../../src/runtime/transport_pool'); const pool = new TransportPool(); const mockTransport = { publish: () => {}, subscribe: () => () => {}, }; const mockEndpoint = { type: 'memory' as const, url: 'memory://test', priority: 0 }; pool.set('test-realm', mockEndpoint, mockTransport); const result = pool.get('test-realm'); assert.ok(result !== undefined && result !== null); assert.equal(result!.transport, mockTransport); assert.equal(result!.endpoint, mockEndpoint); }); test('TransportPool: returns null for unknown realm', async () => { const { TransportPool } = await import('../../src/runtime/transport_pool'); const pool = new TransportPool(); const result = pool.get('nonexistent'); assert.equal(result, null); }); test('TransportPool: clear removes all entries', async () => { const { TransportPool } = await import('../../src/runtime/transport_pool'); const pool = new TransportPool(); const mockTransport = { publish: () => {}, subscribe: () => () => {}, }; const mockEndpoint = { type: 'memory' as const, url: 'memory://test', priority: 0 }; pool.set('realm-1', mockEndpoint, mockTransport); pool.set('realm-2', mockEndpoint, mockTransport); pool.clear(); assert.equal(pool.get('realm-1'), null); assert.equal(pool.get('realm-2'), null); }); // ============================================================================ // Clock Tests // ============================================================================ test('SystemClock: nowMs returns number', async () => { const { SystemClock } = await import('../../src/runtime/clock'); const clock = new SystemClock(); const now = clock.nowMs(); assert.equal(typeof now, 'number'); assert.ok(now > 0); }); test('SystemClock: nowIso returns ISO string', async () => { const { SystemClock } = await import('../../src/runtime/clock'); const clock = new SystemClock(); const iso = clock.nowIso(); assert.equal(typeof iso, 'string'); assert.ok(iso.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)); }); test('TestClock: returns configured time', async () => { const { TestClock } = await import('../../src/runtime/clock'); const fixedTime = 1700000000000; const clock = new TestClock(fixedTime); assert.equal(clock.nowMs(), fixedTime); // ISO should match fixed time const iso = clock.nowIso(); const parsed = new Date(iso).getTime(); assert.equal(parsed, fixedTime); }); test('TestClock: advanceMs moves time forward', async () => { const { TestClock } = await import('../../src/runtime/clock'); const clock = new TestClock(1000); assert.equal(clock.nowMs(), 1000); clock.advanceMs(500); assert.equal(clock.nowMs(), 1500); clock.advanceMs(1000); assert.equal(clock.nowMs(), 2500); });