semblance-dev/src/utils/websocketTestUtils.ts
2025-08-10 18:08:34 -05:00

301 lines
No EOL
7.7 KiB
TypeScript

/**
* WebSocket Testing and Monitoring Utilities
* Provides tools for testing WebSocket functionality and monitoring performance
*/
interface WebSocketTestResult {
success: boolean;
message: string;
latency?: number;
error?: string;
}
interface WebSocketPerformanceMetrics {
connectionTime: number;
averageLatency: number;
messagesSent: number;
messagesReceived: number;
reconnections: number;
errors: number;
}
export class WebSocketTester {
private metrics: WebSocketPerformanceMetrics = {
connectionTime: 0,
averageLatency: 0,
messagesSent: 0,
messagesReceived: 0,
reconnections: 0,
errors: 0
};
private latencies: number[] = [];
private connectionStartTime: number = 0;
/**
* Test basic WebSocket connection
*/
async testConnection(token: string): Promise<WebSocketTestResult> {
return new Promise((resolve) => {
try {
const { io } = require('socket.io-client');
this.connectionStartTime = Date.now();
const socket = io('http://localhost:5137', {
auth: { token },
transports: ['websocket'],
timeout: 5000
});
const timeout = setTimeout(() => {
socket.close();
resolve({
success: false,
message: 'Connection timeout (5s)',
error: 'Timeout'
});
}, 5000);
socket.on('connect', () => {
clearTimeout(timeout);
const connectionTime = Date.now() - this.connectionStartTime;
this.metrics.connectionTime = connectionTime;
socket.close();
resolve({
success: true,
message: 'Connection successful',
latency: connectionTime
});
});
socket.on('connect_error', (error: any) => {
clearTimeout(timeout);
this.metrics.errors++;
resolve({
success: false,
message: 'Connection failed',
error: error.message
});
});
} catch (error: any) {
resolve({
success: false,
message: 'Test setup failed',
error: error.message
});
}
});
}
/**
* Test message round-trip latency
*/
async testMessageLatency(token: string, focusGroupId: string): Promise<WebSocketTestResult> {
return new Promise((resolve) => {
try {
const { io } = require('socket.io-client');
const startTime = Date.now();
const socket = io('http://localhost:5137', {
auth: { token },
transports: ['websocket'],
timeout: 5000
});
const timeout = setTimeout(() => {
socket.close();
resolve({
success: false,
message: 'Message test timeout',
error: 'Timeout'
});
}, 10000);
socket.on('connect', () => {
// Join focus group room
socket.emit('join_focus_group', { focus_group_id: focusGroupId });
});
socket.on('joined_focus_group', () => {
// Send a test event and measure response time
const messageStartTime = Date.now();
socket.emit('test_message', { timestamp: messageStartTime });
});
socket.on('test_response', () => {
clearTimeout(timeout);
const latency = Date.now() - startTime;
this.latencies.push(latency);
this.updateLatencyMetrics();
socket.close();
resolve({
success: true,
message: 'Message test successful',
latency
});
});
socket.on('error', (error: any) => {
clearTimeout(timeout);
this.metrics.errors++;
socket.close();
resolve({
success: false,
message: 'Message test failed',
error: error.message
});
});
} catch (error: any) {
resolve({
success: false,
message: 'Message test setup failed',
error: error.message
});
}
});
}
/**
* Run comprehensive WebSocket test suite
*/
async runTestSuite(token: string, focusGroupId: string): Promise<{
connectionTest: WebSocketTestResult;
messageTest: WebSocketTestResult;
metrics: WebSocketPerformanceMetrics;
}> {
console.log('🧪 Starting WebSocket test suite...');
const connectionTest = await this.testConnection(token);
let messageTest: WebSocketTestResult = {
success: false,
message: 'Skipped due to connection failure'
};
if (connectionTest.success) {
messageTest = await this.testMessageLatency(token, focusGroupId);
}
return {
connectionTest,
messageTest,
metrics: { ...this.metrics }
};
}
/**
* Update latency metrics
*/
private updateLatencyMetrics(): void {
if (this.latencies.length > 0) {
this.metrics.averageLatency =
this.latencies.reduce((sum, lat) => sum + lat, 0) / this.latencies.length;
}
}
/**
* Start performance monitoring
*/
startMonitoring(websocketHook: any): () => void {
const interval = setInterval(() => {
if (websocketHook.isConnected) {
this.logPerformanceMetrics();
}
}, 30000); // Log every 30 seconds
return () => clearInterval(interval);
}
/**
* Log performance metrics
*/
private logPerformanceMetrics(): void {
console.log('📊 WebSocket Performance Metrics:', {
averageLatency: `${this.metrics.averageLatency.toFixed(2)}ms`,
connectionTime: `${this.metrics.connectionTime}ms`,
messagesSent: this.metrics.messagesSent,
messagesReceived: this.metrics.messagesReceived,
reconnections: this.metrics.reconnections,
errors: this.metrics.errors,
uptime: this.connectionStartTime ?
`${Math.round((Date.now() - this.connectionStartTime) / 1000)}s` : '0s'
});
}
/**
* Increment message counters
*/
incrementMessagesSent(): void {
this.metrics.messagesSent++;
}
incrementMessagesReceived(): void {
this.metrics.messagesReceived++;
}
incrementReconnections(): void {
this.metrics.reconnections++;
}
incrementErrors(): void {
this.metrics.errors++;
}
/**
* Get current metrics
*/
getMetrics(): WebSocketPerformanceMetrics {
return { ...this.metrics };
}
/**
* Reset metrics
*/
resetMetrics(): void {
this.metrics = {
connectionTime: 0,
averageLatency: 0,
messagesSent: 0,
messagesReceived: 0,
reconnections: 0,
errors: 0
};
this.latencies = [];
}
}
// Global tester instance
export const websocketTester = new WebSocketTester();
// Development-only testing function
export async function runWebSocketDiagnostics(token: string, focusGroupId: string) {
if (process.env.NODE_ENV !== 'development') {
console.warn('WebSocket diagnostics only available in development mode');
return;
}
console.log('🔧 Running WebSocket diagnostics...');
const results = await websocketTester.runTestSuite(token, focusGroupId);
console.log('📋 WebSocket Test Results:', {
connection: results.connectionTest.success ? '✅ PASS' : '❌ FAIL',
message: results.messageTest.success ? '✅ PASS' : '❌ FAIL',
connectionLatency: results.connectionTest.latency ?
`${results.connectionTest.latency}ms` : 'N/A',
messageLatency: results.messageTest.latency ?
`${results.messageTest.latency}ms` : 'N/A'
});
if (!results.connectionTest.success) {
console.error('❌ Connection Error:', results.connectionTest.error);
}
if (!results.messageTest.success) {
console.error('❌ Message Error:', results.messageTest.error);
}
return results;
}