Skip to main content
Glama
ooples

MCP Console Automation Server

error-detection.test.ts21.7 kB
import { describe, beforeAll, afterAll, beforeEach, afterEach, it, expect, jest } from '@jest/globals'; import { ErrorDetector } from '../../src/core/ErrorDetector.js'; import { ConsoleManager } from '../../src/core/ConsoleManager.js'; import { ErrorPattern } from '../../src/types/index.js'; import { platform } from 'os'; // Skip hardware-intensive integration tests in CI const describeIfHardware = process.env.SKIP_HARDWARE_TESTS ? describe.skip : describe; describeIfHardware('Error Detection Integration Tests', () => { let errorDetector: ErrorDetector; let consoleManager: ConsoleManager; beforeAll(() => { errorDetector = new ErrorDetector(); consoleManager = new ConsoleManager(); }); afterAll(async () => { await consoleManager.destroy(); }); beforeEach(() => { jest.clearAllMocks(); }); describe('Error Pattern Matching Across Languages', () => { it('should detect JavaScript/Node.js errors', () => { const nodeError = ` ReferenceError: undefinedVariable is not defined at Object.<anonymous> (/app/test.js:5:1) at Module._compile (module.js:573:30) at Object.Module._extensions..js (module.js:584:10) at Module.load (module.js:507:32) at tryModuleLoad (module.js:447:12) `; const errors = errorDetector.detect(nodeError); expect(errors).toHaveLength(1); expect(errors[0].pattern.type).toBe('error'); expect(errors[0].pattern.severity).toBe('high'); // Test stack trace analysis const stackTrace = errorDetector.analyzeStackTrace(nodeError); expect(stackTrace.language).toBe('javascript'); expect(stackTrace.frames.length).toBeGreaterThan(0); }); it('should detect Python errors and tracebacks', () => { const pythonError = ` Traceback (most recent call last): File "test.py", line 10, in <module> result = divide(10, 0) File "test.py", line 5, in divide return a / b ZeroDivisionError: division by zero `; const errors = errorDetector.detect(pythonError); expect(errors.length).toBeGreaterThan(0); const exceptionErrors = errors.filter(e => e.pattern.type === 'exception'); expect(exceptionErrors.length).toBeGreaterThan(0); // Test stack trace analysis const stackTrace = errorDetector.analyzeStackTrace(pythonError); expect(stackTrace.language).toBe('python'); expect(stackTrace.frames.length).toBeGreaterThan(0); expect(stackTrace.frames[0]).toContain('File "test.py"'); }); it('should detect Java errors and stack traces', () => { const javaError = ` Exception in thread "main" java.lang.NullPointerException at com.example.MyClass.process(MyClass.java:42) at com.example.Main.main(Main.java:15) `; const errors = errorDetector.detect(javaError); expect(errors.length).toBeGreaterThan(0); const nullPointerErrors = errors.filter(e => e.pattern.description.includes('Null pointer') ); expect(nullPointerErrors.length).toBeGreaterThan(0); // Test stack trace analysis const stackTrace = errorDetector.analyzeStackTrace(javaError); expect(stackTrace.language).toBe('java'); expect(stackTrace.frames.length).toBeGreaterThan(0); expect(stackTrace.frames[0]).toContain('at com.example'); }); it('should detect C/C++ errors', () => { const cppError = ` Segmentation fault (core dumped) *** stack smashing detected ***: ./program terminated Assertion 'ptr != NULL' failed. `; const errors = errorDetector.detect(cppError); expect(errors.length).toBeGreaterThan(0); const segFaultErrors = errors.filter(e => e.pattern.description.includes('Segmentation fault') ); expect(segFaultErrors.length).toBeGreaterThan(0); const assertionErrors = errors.filter(e => e.pattern.description.includes('Assertion failed') ); expect(assertionErrors.length).toBeGreaterThan(0); }); it('should detect compilation errors across languages', () => { const compilationErrors = ` gcc: error: unrecognized command line option '-invalid' javac: error: file not found: NonExistent.java error CS1002: ; expected SyntaxError: invalid syntax (line 5) `; const errors = errorDetector.detect(compilationErrors); expect(errors.length).toBeGreaterThan(0); const syntaxErrors = errors.filter(e => e.pattern.description.includes('Syntax error') || e.pattern.type === 'error' ); expect(syntaxErrors.length).toBeGreaterThan(0); }); it('should detect database errors', () => { const dbError = ` SQLException: Column 'invalid_column' doesn't exist in table 'users' Connection refused: unable to connect to database server Access denied for user 'test'@'localhost' to database 'production' `; const errors = errorDetector.detect(dbError); expect(errors.length).toBeGreaterThan(0); const accessErrors = errors.filter(e => e.pattern.description.includes('Access denied') ); expect(accessErrors.length).toBeGreaterThan(0); const connectionErrors = errors.filter(e => e.pattern.description.includes('Connection refused') ); expect(connectionErrors.length).toBeGreaterThan(0); }); it('should detect network and system errors', () => { const networkError = ` curl: (7) Failed to connect to localhost port 8080: Connection refused ping: cannot resolve example.invalid: Name or service not known Permission denied (publickey) Timeout: operation took too long to complete `; const errors = errorDetector.detect(networkError); expect(errors.length).toBeGreaterThan(0); const permissionErrors = errors.filter(e => e.pattern.description.includes('Permission denied') ); expect(permissionErrors.length).toBeGreaterThan(0); const timeoutErrors = errors.filter(e => e.pattern.description.includes('timeout') ); expect(timeoutErrors.length).toBeGreaterThan(0); }); }); describe('Error Severity Classification', () => { it('should classify critical errors correctly', () => { const criticalErrors = ` FATAL: database connection lost Out of memory: killed process Segmentation fault occurred Exception: null pointer dereference Stack trace detected `; const errors = errorDetector.detect(criticalErrors); const criticalCount = errors.filter(e => e.pattern.severity === 'critical').length; expect(criticalCount).toBeGreaterThan(0); const severityScore = errorDetector.getSeverityScore(errors); expect(severityScore).toBeGreaterThan(10); // Multiple critical errors }); it('should classify high severity errors correctly', () => { const highErrors = ` ERROR: failed to start service Access denied to critical resource Permission denied for admin operation `; const errors = errorDetector.detect(highErrors); const highSeverityErrors = errors.filter(e => e.pattern.severity === 'high'); expect(highSeverityErrors.length).toBeGreaterThan(0); const severityScore = errorDetector.getSeverityScore(errors); expect(severityScore).toBeGreaterThan(5); }); it('should classify medium severity errors correctly', () => { const mediumErrors = ` Cannot find configuration file Unable to load optional module Not found: resource missing Connection timeout occurred `; const errors = errorDetector.detect(mediumErrors); const mediumSeverityErrors = errors.filter(e => e.pattern.severity === 'medium'); expect(mediumSeverityErrors.length).toBeGreaterThan(0); const severityScore = errorDetector.getSeverityScore(errors); expect(severityScore).toBeGreaterThan(2); expect(severityScore).toBeLessThan(15); }); it('should classify low severity errors correctly', () => { const lowErrors = ` Warning: deprecated function used Warning: configuration value ignored `; const errors = errorDetector.detect(lowErrors); const lowSeverityErrors = errors.filter(e => e.pattern.severity === 'low'); expect(lowSeverityErrors.length).toBeGreaterThan(0); const severityScore = errorDetector.getSeverityScore(errors); expect(severityScore).toBeLessThan(5); }); it('should handle mixed severity scenarios', () => { const mixedErrors = ` Warning: minor issue detected ERROR: critical system failure Cannot find optional file FATAL: system crash imminent `; const errors = errorDetector.detect(mixedErrors); const severities = errors.map(e => e.pattern.severity); expect(severities).toContain('low'); expect(severities).toContain('high'); expect(severities).toContain('critical'); expect(severities).toContain('medium'); const severityScore = errorDetector.getSeverityScore(errors); expect(severityScore).toBeGreaterThan(8); // Mixed but high due to critical errors }); }); describe('Error Recovery Strategies', () => { it('should suggest recovery for connection errors', async () => { const sessionId = await consoleManager.createSession({ command: platform() === 'win32' ? 'echo Connection refused: unable to connect to server' : 'echo Connection refused: unable to connect to server', detectErrors: true, timeout: 5000 }); let errorEvent: any = null; consoleManager.on('console-event', (event) => { if (event.sessionId === sessionId && event.type === 'error') { errorEvent = event; } }); await new Promise(resolve => setTimeout(resolve, 2000)); expect(errorEvent).toBeTruthy(); expect(errorEvent.data.errors.length).toBeGreaterThan(0); const connectionErrors = errorEvent.data.errors.filter((e: any) => e.pattern.description.includes('Connection refused') ); expect(connectionErrors.length).toBeGreaterThan(0); await consoleManager.stopSession(sessionId); }, 10000); it('should handle permission errors with recovery suggestions', async () => { const sessionId = await consoleManager.createSession({ command: platform() === 'win32' ? 'echo Access denied: insufficient privileges' : 'echo Permission denied: operation not permitted', detectErrors: true, timeout: 5000 }); let errorEvent: any = null; consoleManager.on('console-event', (event) => { if (event.sessionId === sessionId && event.type === 'error') { errorEvent = event; } }); await new Promise(resolve => setTimeout(resolve, 2000)); expect(errorEvent).toBeTruthy(); expect(errorEvent.data.errors.length).toBeGreaterThan(0); const permissionErrors = errorEvent.data.errors.filter((e: any) => e.pattern.description.includes('Access denied') || e.pattern.description.includes('Permission denied') ); expect(permissionErrors.length).toBeGreaterThan(0); await consoleManager.stopSession(sessionId); }, 10000); it('should handle timeout errors with retry suggestions', async () => { const sessionId = await consoleManager.createSession({ command: platform() === 'win32' ? 'echo Timeout: operation exceeded time limit' : 'echo Timeout: operation exceeded time limit', detectErrors: true, timeout: 5000 }); let errorEvent: any = null; consoleManager.on('console-event', (event) => { if (event.sessionId === sessionId && event.type === 'error') { errorEvent = event; } }); await new Promise(resolve => setTimeout(resolve, 2000)); expect(errorEvent).toBeTruthy(); expect(errorEvent.data.errors.length).toBeGreaterThan(0); const timeoutErrors = errorEvent.data.errors.filter((e: any) => e.pattern.description.includes('timeout') ); expect(timeoutErrors.length).toBeGreaterThan(0); await consoleManager.stopSession(sessionId); }, 10000); it('should identify recoverable vs non-recoverable errors', () => { const recoverableErrors = ` Connection timeout occurred Unable to connect to service Resource temporarily unavailable `; const nonRecoverableErrors = ` Segmentation fault occurred Out of memory: process killed FATAL: corrupted data detected `; const recoverable = errorDetector.detect(recoverableErrors); const nonRecoverable = errorDetector.detect(nonRecoverableErrors); // Recoverable errors typically have medium or high severity const recoverableScore = errorDetector.getSeverityScore(recoverable); const nonRecoverableScore = errorDetector.getSeverityScore(nonRecoverable); expect(nonRecoverableScore).toBeGreaterThan(recoverableScore); const criticalCount = nonRecoverable.filter(e => e.pattern.severity === 'critical').length; expect(criticalCount).toBeGreaterThan(0); }); }); describe('Performance Under High Error Rates', () => { it('should handle high-frequency error detection efficiently', async () => { const errorCount = 100; const errors = Array.from({ length: errorCount }, (_, i) => `ERROR: Test error number ${i + 1}\nException: Critical failure ${i + 1}` ).join('\n'); const startTime = Date.now(); const detectedErrors = errorDetector.detect(errors); const endTime = Date.now(); const processingTime = endTime - startTime; expect(detectedErrors.length).toBe(errorCount * 2); // ERROR + Exception per iteration expect(processingTime).toBeLessThan(1000); // Should complete in under 1 second }); it('should maintain performance with complex error patterns', async () => { const complexErrors = ` [2023-12-01 10:30:15] ERROR in module.py:42 - Database connection failed [2023-12-01 10:30:16] FATAL: System crash detected in component X Traceback (most recent call last): File "complex.py", line 100, in process_data result = risky_operation() File "complex.py", line 85, in risky_operation raise ValueError("Invalid input data") ValueError: Invalid input data Connection refused: Could not establish connection to remote server Permission denied: User lacks sufficient privileges WARNING: Deprecated API usage detected `; const iterations = 50; const startTime = Date.now(); for (let i = 0; i < iterations; i++) { const errors = errorDetector.detect(complexErrors); expect(errors.length).toBeGreaterThan(0); } const endTime = Date.now(); const avgProcessingTime = (endTime - startTime) / iterations; expect(avgProcessingTime).toBeLessThan(50); // Average should be under 50ms per iteration }); it('should handle concurrent error detection', async () => { const errorText = ` Multiple ERROR messages Several FATAL issues Various WARNING indicators Many EXCEPTION cases `; const concurrentPromises = Array.from({ length: 20 }, async (_, i) => { const errors = errorDetector.detect(`${errorText} - Batch ${i}`); return errors.length; }); const startTime = Date.now(); const results = await Promise.all(concurrentPromises); const endTime = Date.now(); expect(results.every(count => count > 0)).toBe(true); expect(endTime - startTime).toBeLessThan(2000); // Should complete within 2 seconds }); it('should handle memory efficiently with large error logs', () => { // Generate a large error log (simulate real-world scenario) const largeErrorLog = Array.from({ length: 1000 }, (_, i) => { const errorTypes = [ `ERROR: Database query failed on line ${i}`, `WARNING: Deprecated method used in function ${i}`, `FATAL: Memory allocation failed for object ${i}`, `Exception: Null pointer at address ${i * 1000}` ]; return errorTypes[i % 4]; }).join('\n'); const initialMemory = process.memoryUsage().heapUsed; const errors = errorDetector.detect(largeErrorLog); const finalMemory = process.memoryUsage().heapUsed; const memoryIncrease = (finalMemory - initialMemory) / (1024 * 1024); // MB expect(errors.length).toBe(1000); // Should detect all errors expect(memoryIncrease).toBeLessThan(50); // Should not use excessive memory }); it('should handle streaming error detection performance', async () => { const command = platform() === 'win32' ? 'for /L %i in (1,1,50) do @echo ERROR: Test error %i & @echo WARNING: Test warning %i' : 'for i in {1..50}; do echo "ERROR: Test error $i"; echo "WARNING: Test warning $i"; done'; const sessionId = await consoleManager.createSession({ command: command, detectErrors: true, streaming: true, timeout: 15000 }); const errorEvents: any[] = []; const startTime = Date.now(); consoleManager.on('console-event', (event) => { if (event.sessionId === sessionId && event.type === 'error') { errorEvents.push({ ...event, detectionTime: Date.now() - startTime }); } }); // Wait for command completion await new Promise(resolve => setTimeout(resolve, 10000)); expect(errorEvents.length).toBeGreaterThan(0); // Check that error detection didn't cause significant delays const avgDetectionTime = errorEvents.reduce((sum, event) => sum + (event.detectionTime || 0), 0) / errorEvents.length; expect(avgDetectionTime).toBeLessThan(5000); // Should detect errors promptly await consoleManager.stopSession(sessionId); }, 20000); }); describe('Custom Error Patterns', () => { it('should support adding custom error patterns', () => { const customPattern: ErrorPattern = { pattern: /CUSTOM_ERROR:\s+.*/i, type: 'error', description: 'Custom application error', severity: 'high' }; errorDetector.addPattern(customPattern); const testText = 'CUSTOM_ERROR: Something went wrong in our app'; const errors = errorDetector.detect(testText); const customErrors = errors.filter(e => e.pattern.description === 'Custom application error' ); expect(customErrors.length).toBe(1); }); it('should support domain-specific error patterns', () => { const customPatterns: ErrorPattern[] = [ { pattern: /BILLING_ERROR:\s+.*/i, type: 'error', description: 'Billing system error', severity: 'critical' }, { pattern: /USER_AUTH_FAILED:\s+.*/i, type: 'error', description: 'User authentication failure', severity: 'high' } ]; customPatterns.forEach(pattern => errorDetector.addPattern(pattern)); const testText = ` BILLING_ERROR: Payment processing failed USER_AUTH_FAILED: Invalid credentials provided `; const errors = errorDetector.detect(testText); const billingErrors = errors.filter(e => e.pattern.description === 'Billing system error' ); const authErrors = errors.filter(e => e.pattern.description === 'User authentication failure' ); expect(billingErrors.length).toBe(1); expect(authErrors.length).toBe(1); }); it('should support removing custom patterns', () => { const tempPattern: ErrorPattern = { pattern: /TEMP_ERROR:\s+.*/i, type: 'error', description: 'Temporary error pattern', severity: 'low' }; errorDetector.addPattern(tempPattern); let errors = errorDetector.detect('TEMP_ERROR: This should be detected'); expect(errors.length).toBe(1); errorDetector.removePattern(tempPattern.pattern); errors = errorDetector.detect('TEMP_ERROR: This should not be detected'); const tempErrors = errors.filter(e => e.pattern.description === 'Temporary error pattern' ); expect(tempErrors.length).toBe(0); }); it('should integrate custom patterns with ConsoleManager', async () => { const customPattern: ErrorPattern = { pattern: /APPLICATION_CRASH:\s+.*/i, type: 'exception', description: 'Application crash detected', severity: 'critical' }; const sessionId = await consoleManager.createSession({ command: platform() === 'win32' ? 'echo APPLICATION_CRASH: Main thread terminated' : 'echo APPLICATION_CRASH: Main thread terminated', patterns: [customPattern], detectErrors: true, timeout: 5000 }); let errorEvent: any = null; consoleManager.on('console-event', (event) => { if (event.sessionId === sessionId && event.type === 'error') { errorEvent = event; } }); await new Promise(resolve => setTimeout(resolve, 2000)); expect(errorEvent).toBeTruthy(); expect(errorEvent.data.errors.length).toBeGreaterThan(0); const crashErrors = errorEvent.data.errors.filter((e: any) => e.pattern.description === 'Application crash detected' ); expect(crashErrors.length).toBeGreaterThan(0); await consoleManager.stopSession(sessionId); }, 10000); }); });

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/ooples/mcp-console-automation'

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