Skip to main content
Glama
mkXultra
by mkXultra
stats-accuracy.test.ts19.6 kB
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { fs, vol } from 'memfs'; // Mock the fs module with memfs for testing vi.mock('fs', () => fs); vi.mock('fs/promises', () => fs.promises); describe('Management Statistics Accuracy Integration Tests', () => { let managementService: any; let dataScanner: any; let statsCollector: any; beforeEach(async () => { // Set environment variable to use 'data' directory process.env.AGENT_COMM_DATA_DIR = 'data'; // Reset the virtual file system vol.reset(); // Create a comprehensive test scenario with multiple rooms vol.fromJSON({ 'data/rooms.json': JSON.stringify({ rooms: { 'marketing-team': { createdAt: '2024-01-01T00:00:00.000Z', userCount: 6, messageCount: 245 }, 'dev-squad': { createdAt: '2024-01-02T00:00:00.000Z', userCount: 4, messageCount: 189 }, 'general-chat': { createdAt: '2024-01-03T00:00:00.000Z', userCount: 8, messageCount: 432 }, 'project-alpha': { createdAt: '2024-01-04T00:00:00.000Z', userCount: 3, messageCount: 76 }, 'empty-project': { createdAt: '2024-01-05T00:00:00.000Z', userCount: 0, messageCount: 0 }, 'archived-room': { createdAt: '2024-01-06T00:00:00.000Z', userCount: 2, messageCount: 15 } } }), // Marketing team - High activity 'data/rooms/marketing-team/messages.jsonl': new Array(245).fill(0) .map((_, i) => { const agents = ['sarah', 'mike', 'jessica', 'david', 'emma', 'alex']; const agentName = agents[i % agents.length]; const hour = 9 + Math.floor(i / 30); // Spread across work hours const minute = (i * 2) % 60; return `{"id":"msg-${i+1}","agentName":"${agentName}","message":"Marketing discussion ${i+1}","timestamp":"2024-01-01T${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:00.000Z"}`; }) .join('\n'), 'data/rooms/marketing-team/presence.json': JSON.stringify({ users: { sarah: { status: 'online', lastSeen: '2024-01-01T17:30:00.000Z' }, mike: { status: 'online', lastSeen: '2024-01-01T17:25:00.000Z' }, jessica: { status: 'offline', lastSeen: '2024-01-01T16:45:00.000Z' }, david: { status: 'online', lastSeen: '2024-01-01T17:28:00.000Z' }, emma: { status: 'away', lastSeen: '2024-01-01T17:00:00.000Z' }, alex: { status: 'offline', lastSeen: '2024-01-01T15:30:00.000Z' } } }), // Dev squad - Medium activity 'data/rooms/dev-squad/messages.jsonl': new Array(189).fill(0) .map((_, i) => { const agents = ['alice', 'bob', 'charlie', 'diana']; const agentName = agents[i % agents.length]; return `{"id":"dev-msg-${i+1}","agentName":"${agentName}","message":"Code review comment ${i+1}","timestamp":"2024-01-02T${String(10 + Math.floor(i / 20)).padStart(2, '0')}:${String((i * 3) % 60).padStart(2, '0')}:00.000Z"}`; }) .join('\n'), 'data/rooms/dev-squad/presence.json': JSON.stringify({ users: { alice: { status: 'online', lastSeen: '2024-01-02T18:00:00.000Z' }, bob: { status: 'online', lastSeen: '2024-01-02T17:55:00.000Z' }, charlie: { status: 'offline', lastSeen: '2024-01-02T17:00:00.000Z' }, diana: { status: 'online', lastSeen: '2024-01-02T18:05:00.000Z' } } }), // General chat - High activity, many users 'data/rooms/general-chat/messages.jsonl': new Array(432).fill(0) .map((_, i) => { const agents = ['user1', 'user2', 'user3', 'user4', 'user5', 'user6', 'user7', 'user8']; const agentName = agents[i % agents.length]; return `{"id":"general-${i+1}","agentName":"${agentName}","message":"General chat message ${i+1}","timestamp":"2024-01-03T${String(8 + Math.floor(i / 50)).padStart(2, '0')}:${String((i * 1.5) % 60).padStart(2, '0')}:00.000Z"}`; }) .join('\n'), 'data/rooms/general-chat/presence.json': JSON.stringify({ users: { user1: { status: 'online', lastSeen: '2024-01-03T19:00:00.000Z' }, user2: { status: 'online', lastSeen: '2024-01-03T18:58:00.000Z' }, user3: { status: 'online', lastSeen: '2024-01-03T19:02:00.000Z' }, user4: { status: 'offline', lastSeen: '2024-01-03T17:30:00.000Z' }, user5: { status: 'online', lastSeen: '2024-01-03T18:55:00.000Z' }, user6: { status: 'offline', lastSeen: '2024-01-03T16:00:00.000Z' }, user7: { status: 'online', lastSeen: '2024-01-03T19:01:00.000Z' }, user8: { status: 'offline', lastSeen: '2024-01-03T18:00:00.000Z' } } }), // Project alpha - Small focused team 'data/rooms/project-alpha/messages.jsonl': new Array(76).fill(0) .map((_, i) => { const agents = ['lead', 'dev1', 'designer']; const agentName = agents[i % agents.length]; return `{"id":"alpha-${i+1}","agentName":"${agentName}","message":"Project alpha update ${i+1}","timestamp":"2024-01-04T${String(9 + Math.floor(i / 10)).padStart(2, '0')}:${String((i * 5) % 60).padStart(2, '0')}:00.000Z"}`; }) .join('\n'), 'data/rooms/project-alpha/presence.json': JSON.stringify({ users: { lead: { status: 'online', lastSeen: '2024-01-04T16:30:00.000Z' }, dev1: { status: 'offline', lastSeen: '2024-01-04T15:45:00.000Z' }, designer: { status: 'online', lastSeen: '2024-01-04T16:25:00.000Z' } } }), // Empty project - No activity 'data/rooms/empty-project/messages.jsonl': '', 'data/rooms/empty-project/presence.json': JSON.stringify({ users: {} }), // Archived room - Minimal activity, users offline 'data/rooms/archived-room/messages.jsonl': new Array(15).fill(0) .map((_, i) => `{"id":"arch-${i+1}","agentName":"olduser${(i % 2) + 1}","message":"Old message ${i+1}","timestamp":"2024-01-06T10:${String(i * 2).padStart(2, '0')}:00.000Z"}`) .join('\n'), 'data/rooms/archived-room/presence.json': JSON.stringify({ users: { olduser1: { status: 'offline', lastSeen: '2024-01-06T10:28:00.000Z' }, olduser2: { status: 'offline', lastSeen: '2024-01-06T10:30:00.000Z' } } }) }); // Import the services using ES modules const { ManagementService } = await import('../../../src/features/management'); const { DataScanner } = await import('../../../src/features/management/DataScanner'); const { StatsCollector } = await import('../../../src/features/management/StatsCollector'); managementService = new ManagementService(); dataScanner = new DataScanner(); statsCollector = new StatsCollector(); }); afterEach(() => { vi.clearAllMocks(); delete process.env.AGENT_COMM_DATA_DIR; }); describe('Cross-service Statistics Consistency', () => { it('should have consistent statistics across all services', async () => { // Get stats from all three services const [systemStats, allRooms, collectorStats] = await Promise.all([ managementService.getSystemStatus(), dataScanner.getAllRooms(), statsCollector.collectSystemStatus() ]); // All services should report the same totals expect(systemStats.totalRooms).toBe(6); expect(allRooms.length).toBe(6); expect(collectorStats.totalRooms).toBe(6); expect(systemStats.totalMessages).toBe(957); // 245 + 189 + 432 + 76 + 0 + 15 expect(collectorStats.totalMessages).toBe(957); expect(systemStats.totalOnlineUsers).toBe(13); // 3 + 3 + 5 + 2 + 0 + 0 (only counting 'online' status) expect(collectorStats.totalOnlineUsers).toBe(13); // Calculate total storage size from rooms const totalStorageSize = systemStats.rooms.reduce((sum, room) => sum + room.storageSize, 0); expect(totalStorageSize).toBeGreaterThan(0); }); it('should have consistent room-level statistics', async () => { const roomName = 'marketing-team'; // Get room stats from different services const [roomStats, scanResult, collectorRoom] = await Promise.all([ managementService.getRoomStatistics(roomName), dataScanner.scanRoomDirectory(roomName), statsCollector.getRoomStatistics(roomName) ]); // All services should report the same room data expect(roomStats.totalMessages).toBe(245); expect(scanResult.messageCount).toBe(245); expect(collectorRoom.totalMessages).toBe(245); expect(roomStats.onlineUsers).toBe(3); // sarah, mike, david are online expect(scanResult.onlineUsers).toBe(3); expect(collectorRoom.onlineUsers).toBe(3); // Storage sizes should match expect(roomStats.storageSize).toBe(scanResult.storageSize); expect(roomStats.storageSize).toBe(collectorRoom.storageSize); }); }); describe('Message Count Accuracy', () => { it('should count messages accurately across different room sizes', async () => { const expectedCounts = { 'marketing-team': 245, 'dev-squad': 189, 'general-chat': 432, 'project-alpha': 76, 'empty-project': 0, 'archived-room': 15 }; for (const [roomName, expectedCount] of Object.entries(expectedCounts)) { const roomStats = await managementService.getRoomStatistics(roomName); const scanResult = await dataScanner.scanRoomDirectory(roomName); expect(roomStats.totalMessages).toBe(expectedCount); expect(scanResult.messageCount).toBe(expectedCount); // Verify by actually counting lines in the file const actualLines = await dataScanner.countLines(`data/rooms/${roomName}/messages.jsonl`); expect(actualLines).toBe(expectedCount); } }); it('should accurately count messages by agent', async () => { const roomStats = await statsCollector.getRoomStatistics('marketing-team'); // Verify total message count expect(roomStats.totalMessages).toBe(245); // Verify user presence is tracked expect(roomStats.users).toBeDefined(); if (roomStats.users) { const userNames = Object.keys(roomStats.users); expect(userNames).toContain('sarah'); expect(userNames).toContain('mike'); expect(userNames).toContain('jessica'); expect(userNames).toContain('david'); expect(userNames).toContain('emma'); expect(userNames).toContain('alex'); } }); }); describe('Online User Count Accuracy', () => { it('should count online users accurately across all rooms', async () => { const expectedOnlineCounts = { 'marketing-team': 3, // sarah, mike, david 'dev-squad': 3, // alice, bob, diana 'general-chat': 5, // user1, user2, user3, user5, user7 'project-alpha': 2, // lead, designer 'empty-project': 0, 'archived-room': 0 // all offline }; for (const [roomName, expectedCount] of Object.entries(expectedOnlineCounts)) { const roomStats = await managementService.getRoomStatistics(roomName); const scanResult = await dataScanner.scanRoomDirectory(roomName); expect(roomStats.onlineUsers).toBe(expectedCount); expect(scanResult.onlineUsers).toBe(expectedCount); // Verify by checking presence file directly const actualOnlineCount = await dataScanner.countOnlineUsers(`data/rooms/${roomName}/presence.json`); expect(actualOnlineCount).toBe(expectedCount); } }); it('should handle different user status types correctly', async () => { // Marketing team has mixed status types (online, offline, away) const roomStats = await managementService.getRoomStatistics('marketing-team'); // Only 'online' status should be counted (not 'away' or 'offline') expect(roomStats.onlineUsers).toBe(3); }); }); describe('Storage Size Accuracy', () => { it('should calculate storage sizes accurately', async () => { const systemStats = await managementService.getSystemStatus(); // Calculate expected total storage size let expectedTotalSize = 0; for (const room of systemStats.rooms) { const messagesPath = `data/rooms/${room.name}/messages.jsonl`; const content = fs.readFileSync(messagesPath, 'utf8'); const expectedSize = Buffer.from(content).length; expect(room.storageSize).toBe(expectedSize); expectedTotalSize += expectedSize; } expect(systemStats.totalStorageSize).toBe(expectedTotalSize); }); it('should handle empty files correctly', async () => { const roomStats = await managementService.getRoomStatistics('empty-project'); expect(roomStats.storageSize).toBe(0); }); }); describe('Data Integrity After Operations', () => { it('should maintain accuracy after clearing room messages', async () => { // Get initial system stats const initialStats = await managementService.getSystemStatus(); const initialTotalMessages = initialStats.totalMessages; const roomToSlear = 'project-alpha'; const roomMessagesBefore = initialStats.rooms.find(r => r.name === roomToSlear)?.totalMessages || 0; // Clear messages from one room const clearResult = await managementService.clearRoomMessages(roomToSlear, true); expect(clearResult.success).toBe(true); expect(clearResult.clearedCount).toBe(76); // Get updated stats const updatedStats = await managementService.getSystemStatus(); // Total messages should decrease by the cleared amount expect(updatedStats.totalMessages).toBe(initialTotalMessages - roomMessagesBefore); // Cleared room should have 0 messages const clearedRoom = updatedStats.rooms.find(r => r.name === roomToSlear); expect(clearedRoom?.totalMessages).toBe(0); expect(clearedRoom?.storageSize).toBe(0); // Other rooms should be unaffected const otherRooms = updatedStats.rooms.filter(r => r.name !== roomToSlear); for (const room of otherRooms) { const originalRoom = initialStats.rooms.find(r => r.name === room.name); expect(room.totalMessages).toBe(originalRoom?.totalMessages); expect(room.storageSize).toBe(originalRoom?.storageSize); } }); it('should maintain consistency across services after data changes', async () => { // Add new messages to a room by directly modifying the file const newMessages = [ '{"id":"new-1","agentName":"newuser","message":"New message 1","timestamp":"2024-01-07T10:00:00.000Z"}', '{"id":"new-2","agentName":"newuser","message":"New message 2","timestamp":"2024-01-07T10:01:00.000Z"}' ]; const currentContent = fs.readFileSync('data/rooms/project-alpha/messages.jsonl', 'utf8'); const newContent = currentContent + '\n' + newMessages.join('\n'); fs.writeFileSync('data/rooms/project-alpha/messages.jsonl', newContent); // Update rooms.json to reflect the change const roomsData = JSON.parse(fs.readFileSync('data/rooms.json', 'utf8')); roomsData.rooms['project-alpha'].messageCount = 78; // 76 + 2 fs.writeFileSync('data/rooms.json', JSON.stringify(roomsData)); // All services should report the new count const [systemStats, scanResult, collectorStats] = await Promise.all([ managementService.getSystemStatus(), dataScanner.scanRoomDirectory('project-alpha'), statsCollector.getRoomStatistics('project-alpha') ]); expect(systemStats.totalMessages).toBe(959); // 957 + 2 expect(scanResult.messageCount).toBe(78); expect(collectorStats.totalMessages).toBe(78); }); }); describe('Performance Under Load', () => { it('should maintain accuracy even with concurrent access', async () => { // Simulate concurrent requests to different services const concurrentPromises = [ managementService.getSystemStatus(), dataScanner.getAllRooms(), statsCollector.collectSystemStatus(), managementService.getRoomStatistics('general-chat'), managementService.getRoomStatistics('marketing-team'), dataScanner.scanRoomDirectory('dev-squad'), statsCollector.getRoomStatistics('project-alpha'), statsCollector.getMostActiveRoom() ]; const results = await Promise.all(concurrentPromises); // All system-level stats should be consistent const [systemStats1, allRooms, collectorStats] = results.slice(0, 3); expect(systemStats1.totalRooms).toBe(allRooms.length); expect(allRooms.length).toBe(collectorStats.totalRooms); expect(systemStats1.totalMessages).toBe(collectorStats.totalMessages); expect(systemStats1.totalOnlineUsers).toBe(collectorStats.totalOnlineUsers); expect(systemStats1.totalStorageSize).toBe(collectorStats.totalStorageSize); }); }); describe('Edge Cases and Error Scenarios', () => { it('should handle partially corrupted data gracefully while maintaining accuracy for valid data', async () => { // Corrupt one room's presence file fs.writeFileSync('data/rooms/dev-squad/presence.json', 'invalid json'); // System should still process other rooms correctly const systemStats = await managementService.getSystemStatus(); expect(systemStats.totalRooms).toBe(6); // All rooms should still be counted // The corrupted room should have 0 online users but correct message count const devSquadRoom = systemStats.rooms.find(r => r.name === 'dev-squad'); expect(devSquadRoom?.onlineUsers).toBe(0); // Presence file corrupted expect(devSquadRoom?.totalMessages).toBe(189); // Messages should still be counted correctly // Other rooms should be unaffected const marketingRoom = systemStats.rooms.find(r => r.name === 'marketing-team'); expect(marketingRoom?.onlineUsers).toBe(3); expect(marketingRoom?.totalMessages).toBe(245); }); it('should maintain accuracy when rooms have malformed message lines', async () => { // Add some malformed lines to a room's messages const validMessages = fs.readFileSync('data/rooms/project-alpha/messages.jsonl', 'utf8'); const messagesWithErrors = validMessages + '\n' + 'invalid json line\n' + '{"incomplete": "json"}\n' + '{"id":"valid","agentName":"user","message":"This is valid","timestamp":"2024-01-04T16:00:00.000Z"}'; fs.writeFileSync('data/rooms/project-alpha/messages.jsonl', messagesWithErrors); const roomStats = await statsCollector.getRoomStatistics('project-alpha'); // Should count only valid JSON lines (76 original + 2 new valid JSON = 78) // Note: '{"incomplete": "json"}' is valid JSON even though it lacks message fields expect(roomStats.totalMessages).toBe(78); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mkXultra/agent-communication-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server