UNPKG

@clduab11/gemini-flow

Version:

Revolutionary AI agent swarm coordination platform with Google Services integration, multimedia processing, and production-ready monitoring. Features 8 Google AI services, quantum computing capabilities, and enterprise-grade security.

838 lines (744 loc) 24.5 kB
/** * Unit Tests for Enhanced Streaming API * * Comprehensive test suite following TDD practices for the EnhancedStreamingAPI * class, covering all functionality including streaming, quality adaptation, * multi-modal processing, and error handling. */ import { describe, it, expect, beforeEach, afterEach, jest, } from "@jest/globals"; import { EventEmitter } from "events"; import { EnhancedStreamingAPI } from "../enhanced-streaming-api.js"; import { UnifiedAPI } from "../../../adapters/unified-api.js"; import { Logger } from "../../../utils/logger.js"; // Mock dependencies jest.mock("../../../adapters/unified-api.js"); jest.mock("../../../utils/logger.js"); describe("EnhancedStreamingAPI", () => { let streamingAPI: EnhancedStreamingAPI; let mockConfig: any; let mockLogger: jest.Mocked<Logger>; let mockUnifiedAPI: jest.Mocked<UnifiedAPI>; beforeEach(() => { // Setup mock configuration mockConfig = { apiKey: "test-api-key", projectId: "test-project", streaming: { maxConcurrentStreams: 10, defaultChunkSize: 8192, compressionEnabled: true, qualityAdaptation: true, bufferSize: 32768, maxRetries: 3, }, qualityProfiles: { low: { bitrate: 500000, resolution: "480p" }, medium: { bitrate: 1000000, resolution: "720p" }, high: { bitrate: 2000000, resolution: "1080p" }, }, }; // Setup mock logger mockLogger = { info: jest.fn(), debug: jest.fn(), warn: jest.fn(), error: jest.fn(), } as any; // Setup mock UnifiedAPI mockUnifiedAPI = { initialize: jest.fn().mockResolvedValue(undefined), shutdown: jest.fn().mockResolvedValue(undefined), on: jest.fn(), emit: jest.fn(), } as any; // Mock constructor dependencies (Logger as jest.MockedClass<typeof Logger>).mockReturnValue(mockLogger); (UnifiedAPI as jest.MockedClass<typeof UnifiedAPI>).mockReturnValue( mockUnifiedAPI, ); streamingAPI = new EnhancedStreamingAPI(mockConfig); }); afterEach(() => { jest.clearAllMocks(); }); describe("Initialization", () => { it("should initialize successfully with valid configuration", async () => { // Arrange const initializeSpy = jest.spyOn(streamingAPI, "initialize"); // Act await streamingAPI.initialize(); // Assert expect(initializeSpy).toHaveBeenCalledTimes(1); expect(mockUnifiedAPI.initialize).toHaveBeenCalled(); expect(mockLogger.info).toHaveBeenCalledWith( "EnhancedStreamingAPI initialized", ); }); it("should throw error when initialization fails", async () => { // Arrange const initError = new Error("Initialization failed"); mockUnifiedAPI.initialize.mockRejectedValue(initError); // Act & Assert await expect(streamingAPI.initialize()).rejects.toThrow( "Initialization failed", ); expect(mockLogger.error).toHaveBeenCalledWith( "Failed to initialize streaming API", initError, ); }); it("should setup event handlers during initialization", async () => { // Act await streamingAPI.initialize(); // Assert expect(mockUnifiedAPI.on).toHaveBeenCalledWith( "quality_changed", expect.any(Function), ); expect(mockUnifiedAPI.on).toHaveBeenCalledWith( "connection_lost", expect.any(Function), ); }); }); describe("Session Management", () => { beforeEach(async () => { await streamingAPI.initialize(); }); it("should create streaming session successfully", async () => { // Arrange const sessionId = "test-session-123"; const sessionType = "video"; const mockContext = { sessionId, userId: "user-123", userPreferences: { qualityPriority: "balanced" }, deviceCapabilities: { cpu: { cores: 4 } }, networkConditions: { bandwidth: { download: 10000000 } }, constraints: {}, metadata: {}, }; // Act const result = await streamingAPI.createSession( sessionId, sessionType, mockContext, ); // Assert expect(result.success).toBe(true); expect(result.data).toBeDefined(); expect(result.data.id).toBe(sessionId); expect(result.data.type).toBe(sessionType); expect(result.data.status).toBe("active"); expect(mockLogger.info).toHaveBeenCalledWith( "Creating streaming session", { sessionId, type: sessionType, }, ); }); it("should handle session creation with invalid parameters", async () => { // Arrange const invalidSessionId = ""; const sessionType = "video"; const mockContext = {}; // Act const result = await streamingAPI.createSession( invalidSessionId, sessionType, mockContext as any, ); // Assert expect(result.success).toBe(false); expect(result.error?.code).toBe("INVALID_SESSION_PARAMETERS"); }); it("should end session and cleanup resources", async () => { // Arrange const sessionId = "test-session-123"; await streamingAPI.createSession(sessionId, "video", {} as any); // Act const result = await streamingAPI.endSession(sessionId); // Assert expect(result.success).toBe(true); expect(mockLogger.info).toHaveBeenCalledWith("Ending streaming session", { sessionId, }); }); it("should handle ending non-existent session", async () => { // Arrange const nonExistentSessionId = "non-existent-session"; // Act const result = await streamingAPI.endSession(nonExistentSessionId); // Assert expect(result.success).toBe(false); expect(result.error?.code).toBe("SESSION_NOT_FOUND"); }); }); describe("Video Streaming", () => { const sessionId = "test-session-video"; const mockContext = { sessionId, userId: "user-123", userPreferences: { qualityPriority: "balanced" }, deviceCapabilities: { cpu: { cores: 4 } }, networkConditions: { bandwidth: { download: 10000000 } }, constraints: {}, metadata: {}, }; beforeEach(async () => { await streamingAPI.initialize(); await streamingAPI.createSession(sessionId, "video", mockContext); }); it("should start video stream successfully", async () => { // Arrange const videoRequest = { id: "video-stream-1", source: "camera" as const, quality: { level: "high" as const, video: { codec: { name: "H264", mimeType: "video/mp4", bitrate: 2000000 }, resolution: { width: 1920, height: 1080 }, framerate: 30, bitrate: 2000000, keyframeInterval: 30, adaptiveBitrate: true, }, bandwidth: 2500000, latency: 100, }, constraints: { video: { width: { ideal: 1920 }, height: { ideal: 1080 }, frameRate: { ideal: 30 }, }, }, metadata: { timestamp: Date.now(), sessionId, }, }; // Act const result = await streamingAPI.startVideoStream( sessionId, videoRequest, mockContext, ); // Assert expect(result.success).toBe(true); expect(result.data).toBeDefined(); expect(result.data.streamId).toBe(videoRequest.id); expect(result.data.status).toBe("streaming"); expect(mockLogger.info).toHaveBeenCalledWith("Starting video stream", { sessionId, streamId: videoRequest.id, source: videoRequest.source, }); }); it("should handle video stream start failure", async () => { // Arrange const invalidVideoRequest = { id: "", source: "invalid-source" as any, quality: null, constraints: {}, metadata: {}, }; // Act const result = await streamingAPI.startVideoStream( sessionId, invalidVideoRequest, mockContext, ); // Assert expect(result.success).toBe(false); expect(result.error?.code).toBe("INVALID_VIDEO_STREAM_CONFIG"); }); it("should adapt video quality based on network conditions", async () => { // Arrange const videoRequest = { id: "video-stream-adaptive", source: "camera" as const, quality: { level: "adaptive" as const, video: { codec: { name: "H264", mimeType: "video/mp4", bitrate: 2000000 }, resolution: { width: 1920, height: 1080 }, framerate: 30, bitrate: 2000000, keyframeInterval: 30, adaptiveBitrate: true, }, bandwidth: 2500000, latency: 100, }, constraints: { video: {} }, metadata: { timestamp: Date.now(), sessionId }, }; // Mock network degradation const degradedContext = { ...mockContext, networkConditions: { bandwidth: { download: 500000 } }, }; // Act const result = await streamingAPI.startVideoStream( sessionId, videoRequest, degradedContext, ); // Assert expect(result.success).toBe(true); // Quality should be automatically adapted down expect(result.data.adaptedQuality).toBeDefined(); }); }); describe("Audio Streaming", () => { const sessionId = "test-session-audio"; const mockContext = { sessionId, userId: "user-123", userPreferences: { qualityPriority: "balanced" }, deviceCapabilities: { cpu: { cores: 4 } }, networkConditions: { bandwidth: { download: 10000000 } }, constraints: {}, metadata: {}, }; beforeEach(async () => { await streamingAPI.initialize(); await streamingAPI.createSession(sessionId, "audio", mockContext); }); it("should start audio stream successfully", async () => { // Arrange const audioRequest = { id: "audio-stream-1", source: "microphone" as const, quality: { level: "high" as const, audio: { codec: { name: "Opus", mimeType: "audio/opus", bitrate: 128000 }, sampleRate: 48000, channels: 2, bitrate: 128000, bufferSize: 1024, }, bandwidth: 150000, latency: 50, }, constraints: { audio: { sampleRate: { ideal: 48000 }, channelCount: { ideal: 2 }, }, }, processing: { noiseReduction: true, echoCancellation: true, }, metadata: { timestamp: Date.now(), sessionId, }, }; // Act const result = await streamingAPI.startAudioStream( sessionId, audioRequest, mockContext, ); // Assert expect(result.success).toBe(true); expect(result.data).toBeDefined(); expect(result.data.streamId).toBe(audioRequest.id); expect(result.data.status).toBe("streaming"); expect(mockLogger.info).toHaveBeenCalledWith("Starting audio stream", { sessionId, streamId: audioRequest.id, source: audioRequest.source, }); }); it("should apply audio processing filters", async () => { // Arrange const audioRequest = { id: "audio-stream-processed", source: "microphone" as const, quality: { level: "medium" as const, audio: { codec: { name: "Opus", mimeType: "audio/opus", bitrate: 96000 }, sampleRate: 44100, channels: 1, bitrate: 96000, bufferSize: 512, }, bandwidth: 110000, latency: 30, }, constraints: { audio: {} }, processing: { noiseReduction: true, echoCancellation: true, gainControl: true, voiceActivityDetection: true, }, metadata: { timestamp: Date.now(), sessionId }, }; // Act const result = await streamingAPI.startAudioStream( sessionId, audioRequest, mockContext, ); // Assert expect(result.success).toBe(true); expect(result.data.processingEnabled).toBe(true); expect(result.data.appliedFilters).toContain("noise_reduction"); expect(result.data.appliedFilters).toContain("echo_cancellation"); }); }); describe("Multi-Modal Processing", () => { const sessionId = "test-session-multimodal"; const mockContext = { sessionId, userId: "user-123", userPreferences: { qualityPriority: "balanced" }, deviceCapabilities: { cpu: { cores: 4 } }, networkConditions: { bandwidth: { download: 10000000 } }, constraints: {}, metadata: {}, }; beforeEach(async () => { await streamingAPI.initialize(); await streamingAPI.createSession(sessionId, "multimodal", mockContext); }); it("should process multi-modal chunk successfully", async () => { // Arrange const multiModalChunk = { id: "chunk-001", type: "mixed" as const, timestamp: new Date(), sequence: 1, data: { video: Buffer.from("video-data"), audio: Buffer.from("audio-data"), text: "sample text", metadata: { scene: "outdoor", lighting: "bright" }, }, synchronization: { globalTimestamp: new Date(), mediaTimestamp: 1000, sequenceId: "seq-001", }, quality: { video: { resolution: "1080p", bitrate: 2000000 }, audio: { sampleRate: 48000, bitrate: 128000 }, }, processing: { compression: "gzip", encryption: false, validation: true, }, metadata: { size: 8192, checksum: "abc123", contentType: "multimodal/mixed", }, }; // Act const result = await streamingAPI.processMultiModalChunk( sessionId, multiModalChunk, ); // Assert expect(result.success).toBe(true); expect(result.data).toBeDefined(); expect(result.data.processed).toBe(true); expect(result.data.chunkId).toBe(multiModalChunk.id); expect(mockLogger.debug).toHaveBeenCalledWith( "Processing multi-modal chunk", { sessionId, chunkId: multiModalChunk.id, type: multiModalChunk.type, sequence: multiModalChunk.sequence, }, ); }); it("should handle synchronization across multiple chunks", async () => { // Arrange const chunks = [ { id: "chunk-001", type: "video" as const, timestamp: new Date(), sequence: 1, data: { video: Buffer.from("video-1") }, synchronization: { globalTimestamp: new Date(1000), mediaTimestamp: 1000, sequenceId: "seq-001", }, quality: {}, processing: {}, metadata: { size: 4096, checksum: "video1", contentType: "video/mp4", }, }, { id: "chunk-002", type: "audio" as const, timestamp: new Date(), sequence: 2, data: { audio: Buffer.from("audio-1") }, synchronization: { globalTimestamp: new Date(1000), mediaTimestamp: 1000, sequenceId: "seq-001", }, quality: {}, processing: {}, metadata: { size: 2048, checksum: "audio1", contentType: "audio/opus", }, }, ]; // Act const results = await Promise.all( chunks.map((chunk) => streamingAPI.processMultiModalChunk(sessionId, chunk), ), ); // Assert expect(results.every((result) => result.success)).toBe(true); expect(results[0].data.synchronizationGroup).toBe( results[1].data.synchronizationGroup, ); }); }); describe("Quality Adaptation", () => { const sessionId = "test-session-adaptation"; const mockContext = { sessionId, userId: "user-123", userPreferences: { qualityPriority: "balanced" }, deviceCapabilities: { cpu: { cores: 4 } }, networkConditions: { bandwidth: { download: 10000000 } }, constraints: {}, metadata: {}, }; beforeEach(async () => { await streamingAPI.initialize(); await streamingAPI.createSession(sessionId, "video", mockContext); }); it("should adapt quality based on network conditions", async () => { // Arrange const adaptationRequest = { sessionId, targetQuality: "adaptive" as const, networkConditions: { bandwidth: { download: 1000000 }, // Reduced bandwidth latency: { rtt: 150 }, // Increased latency quality: { packetLoss: 0.02 }, // Some packet loss }, deviceConstraints: { cpu: { usage: 80 }, // High CPU usage memory: { usage: 70 }, }, preferences: { prioritizeLatency: true, maxBitrate: 1500000, }, }; // Act const result = await streamingAPI.adaptQuality(adaptationRequest); // Assert expect(result.success).toBe(true); expect(result.data).toBeDefined(); expect(result.data.adaptedQuality).toBeDefined(); expect(result.data.adaptedQuality.level).toBe("medium"); expect(result.data.adaptationReason).toContain("network_conditions"); expect(mockLogger.info).toHaveBeenCalledWith( "Adapting stream quality", expect.objectContaining({ sessionId, targetQuality: "adaptive", adaptedTo: "medium", }), ); }); it("should maintain quality when conditions are optimal", async () => { // Arrange const adaptationRequest = { sessionId, targetQuality: "high" as const, networkConditions: { bandwidth: { download: 50000000 }, // High bandwidth latency: { rtt: 20 }, // Low latency quality: { packetLoss: 0.001 }, // Minimal packet loss }, deviceConstraints: { cpu: { usage: 30 }, // Low CPU usage memory: { usage: 40 }, }, preferences: { prioritizeQuality: true, }, }; // Act const result = await streamingAPI.adaptQuality(adaptationRequest); // Assert expect(result.success).toBe(true); expect(result.data.adaptedQuality.level).toBe("high"); expect(result.data.adaptationReason).toBe("optimal_conditions"); }); }); describe("Error Handling", () => { beforeEach(async () => { await streamingAPI.initialize(); }); it("should handle network disconnection gracefully", async () => { // Arrange const sessionId = "test-session-disconnect"; await streamingAPI.createSession(sessionId, "video", {} as any); // Simulate network disconnection const networkError = new Error("Network disconnected"); // Act const eventSpy = jest.fn(); streamingAPI.on("connection:lost", eventSpy); streamingAPI.emit("connection:lost", { sessionId, error: networkError }); // Assert expect(eventSpy).toHaveBeenCalledWith({ sessionId, error: networkError }); }); it("should implement circuit breaker for repeated failures", async () => { // Arrange const sessionId = "test-session-failures"; // Simulate repeated failures const failingOperation = jest .fn() .mockRejectedValue(new Error("Service unavailable")); // Act - Attempt multiple operations that fail const results = await Promise.all([ streamingAPI .createSession(sessionId + "1", "video", {} as any) .catch((e) => ({ error: e })), streamingAPI .createSession(sessionId + "2", "video", {} as any) .catch((e) => ({ error: e })), streamingAPI .createSession(sessionId + "3", "video", {} as any) .catch((e) => ({ error: e })), streamingAPI .createSession(sessionId + "4", "video", {} as any) .catch((e) => ({ error: e })), streamingAPI .createSession(sessionId + "5", "video", {} as any) .catch((e) => ({ error: e })), ]); // Assert - Should eventually trigger circuit breaker const errorResults = results.filter((r) => "error" in r); expect(errorResults.length).toBeGreaterThan(0); }); it("should retry failed operations with exponential backoff", async () => { // Arrange const sessionId = "test-session-retry"; let attemptCount = 0; // Mock a function that fails twice then succeeds const flakyOperation = jest.fn().mockImplementation(() => { attemptCount++; if (attemptCount < 3) { throw new Error("Temporary failure"); } return { success: true, data: { id: sessionId } }; }); // Act const result = await streamingAPI.createSession( sessionId, "video", {} as any, ); // Assert - Should eventually succeed after retries expect(result.success).toBe(true); }); }); describe("Performance Metrics", () => { beforeEach(async () => { await streamingAPI.initialize(); }); it("should collect streaming performance metrics", async () => { // Arrange const sessionId = "test-session-metrics"; await streamingAPI.createSession(sessionId, "video", {} as any); // Act const metrics = await streamingAPI.getStreamingMetrics(sessionId); // Assert expect(metrics.success).toBe(true); expect(metrics.data).toBeDefined(); expect(metrics.data.sessionId).toBe(sessionId); expect(metrics.data.performance).toBeDefined(); expect(metrics.data.performance.latency).toBeDefined(); expect(metrics.data.performance.throughput).toBeDefined(); expect(metrics.data.performance.quality).toBeDefined(); }); it("should track quality adaptation events", async () => { // Arrange const sessionId = "test-session-quality-metrics"; await streamingAPI.createSession(sessionId, "video", {} as any); // Perform quality adaptations await streamingAPI.adaptQuality({ sessionId, targetQuality: "medium", networkConditions: { bandwidth: { download: 1000000 } }, deviceConstraints: {}, preferences: {}, }); // Act const metrics = await streamingAPI.getStreamingMetrics(sessionId); // Assert expect(metrics.data.qualityAdaptations).toBeGreaterThan(0); expect(metrics.data.adaptationHistory).toBeDefined(); expect(Array.isArray(metrics.data.adaptationHistory)).toBe(true); }); }); describe("Cleanup and Resource Management", () => { it("should cleanup resources on shutdown", async () => { // Arrange await streamingAPI.initialize(); const sessionId1 = "session-1"; const sessionId2 = "session-2"; await streamingAPI.createSession(sessionId1, "video", {} as any); await streamingAPI.createSession(sessionId2, "audio", {} as any); // Act await streamingAPI.shutdown(); // Assert expect(mockUnifiedAPI.shutdown).toHaveBeenCalled(); expect(mockLogger.info).toHaveBeenCalledWith( "Enhanced Streaming API shutdown complete", ); }); it("should handle graceful session termination", async () => { // Arrange await streamingAPI.initialize(); const sessionId = "test-session-terminate"; await streamingAPI.createSession(sessionId, "multimodal", {} as any); // Act const result = await streamingAPI.endSession(sessionId); // Assert expect(result.success).toBe(true); expect(mockLogger.info).toHaveBeenCalledWith("Ending streaming session", { sessionId, }); }); }); });