@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.
393 lines (327 loc) • 12.5 kB
JavaScript
/**
* Integration Tests for Model Orchestrator
*
* Tests the complete multi-model orchestration pipeline
*/
const { ModelOrchestrator } = require('../../dist/core/model-orchestrator');
const { AuthenticationManager } = require('../../dist/core/auth-manager');
const { PerformanceMonitor } = require('../../dist/core/performance-monitor');
describe('Model Orchestrator Integration Tests', () => {
let orchestrator;
let authManager;
let performanceMonitor;
beforeAll(async () => {
// Initialize with test configuration
orchestrator = new ModelOrchestrator({
cacheSize: 100,
performanceThreshold: 1000
});
authManager = new AuthenticationManager({
projectId: 'test-project'
});
performanceMonitor = new PerformanceMonitor();
// Wait for initialization
await new Promise(resolve => setTimeout(resolve, 1000));
});
afterAll(async () => {
if (orchestrator) {
orchestrator.shutdown?.();
}
});
describe('Model Selection and Routing', () => {
test('should route free tier users to appropriate models', async () => {
const context = {
task: 'Simple text completion',
userTier: 'free',
priority: 'low',
latencyRequirement: 2000
};
const mockResponse = {
modelUsed: 'gemini-2.0-flash',
content: 'Test response',
latency: 800,
tokenUsage: { input: 10, output: 20, total: 30 },
cost: 0.00003,
cached: false,
metadata: { tier: 'free' }
};
// Mock the orchestration method
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValue(mockResponse);
const result = await orchestrator.orchestrate('Test prompt', context);
expect(result).toEqual(mockResponse);
expect(result.modelUsed).toBe('gemini-2.0-flash');
expect(result.metadata.tier).toBe('free');
});
test('should route enterprise users to premium models', async () => {
const context = {
task: 'Complex reasoning task',
userTier: 'enterprise',
priority: 'high',
latencyRequirement: 3000,
capabilities: ['advanced-reasoning', 'long-context']
};
const mockResponse = {
modelUsed: 'gemini-2.5-deepmind',
content: 'Complex reasoning response',
latency: 1500,
tokenUsage: { input: 1000, output: 500, total: 1500 },
cost: 0.0075,
cached: false,
metadata: { tier: 'enterprise' }
};
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValue(mockResponse);
const result = await orchestrator.orchestrate('Complex prompt', context);
expect(result).toEqual(mockResponse);
expect(result.modelUsed).toBe('gemini-2.5-deepmind');
expect(result.metadata.tier).toBe('enterprise');
});
test('should handle routing with latency requirements', async () => {
const context = {
task: 'Fast response needed',
userTier: 'pro',
priority: 'critical',
latencyRequirement: 500
};
const mockResponse = {
modelUsed: 'gemini-2.0-flash',
content: 'Fast response',
latency: 400,
tokenUsage: { input: 5, output: 10, total: 15 },
cost: 0.000015,
cached: false,
metadata: { tier: 'pro' }
};
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValue(mockResponse);
const result = await orchestrator.orchestrate('Quick question', context);
expect(result).toEqual(mockResponse);
expect(result.latency).toBeLessThan(context.latencyRequirement);
});
});
describe('Performance Monitoring', () => {
test('should track routing overhead under 100ms', async () => {
const startTime = performance.now();
const context = {
task: 'Performance test',
userTier: 'free',
priority: 'medium',
latencyRequirement: 1000
};
// Mock fast response
jest.spyOn(orchestrator, 'orchestrate').mockImplementation(async () => {
await new Promise(resolve => setTimeout(resolve, 50)); // Simulate processing
return {
modelUsed: 'gemini-2.0-flash',
content: 'Performance test response',
latency: 50,
tokenUsage: { input: 10, output: 10, total: 20 },
cost: 0.00002,
cached: false,
metadata: {}
};
});
const result = await orchestrator.orchestrate('Performance test', context);
const totalTime = performance.now() - startTime;
expect(result).toBeDefined();
expect(totalTime).toBeLessThan(200); // Total overhead should be minimal
});
test('should provide accurate performance metrics', async () => {
// Get initial metrics
const initialMetrics = performanceMonitor.getMetrics();
// Record some test metrics
performanceMonitor.recordMetric('test_latency', 100);
performanceMonitor.recordMetric('test_latency', 150);
performanceMonitor.recordMetric('test_latency', 200);
const stats = performanceMonitor.getStats('test_latency');
expect(stats).toBeDefined();
expect(stats.count).toBe(3);
expect(stats.mean).toBeCloseTo(150, 1);
expect(stats.min).toBe(100);
expect(stats.max).toBe(200);
});
});
describe('Caching System', () => {
test('should cache and retrieve responses correctly', async () => {
const context = {
task: 'Cacheable request',
userTier: 'pro',
priority: 'medium',
latencyRequirement: 1000
};
const mockResponse = {
modelUsed: 'gemini-2.0-flash',
content: 'Cached response',
latency: 800,
tokenUsage: { input: 20, output: 30, total: 50 },
cost: 0.00005,
cached: false,
metadata: {}
};
// First call - should not be cached
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValueOnce(mockResponse);
const firstResult = await orchestrator.orchestrate('Cache test', context);
expect(firstResult.cached).toBe(false);
// Second call - should be cached
const cachedResponse = { ...mockResponse, cached: true };
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValueOnce(cachedResponse);
const secondResult = await orchestrator.orchestrate('Cache test', context);
expect(secondResult.cached).toBe(true);
});
});
describe('Error Handling and Failover', () => {
test('should handle model failures with failover', async () => {
const context = {
task: 'Failover test',
userTier: 'pro',
priority: 'high',
latencyRequirement: 2000,
retryCount: 0
};
// First attempt fails
jest.spyOn(orchestrator, 'orchestrate')
.mockRejectedValueOnce(new Error('Model unavailable'))
.mockResolvedValueOnce({
modelUsed: 'gemini-2.0-flash', // Fallback model
content: 'Failover response',
latency: 1200,
tokenUsage: { input: 15, output: 25, total: 40 },
cost: 0.00004,
cached: false,
metadata: { failover: true }
});
const result = await orchestrator.orchestrate('Failover test', context);
expect(result).toBeDefined();
expect(result.modelUsed).toBe('gemini-2.0-flash');
expect(result.metadata.failover).toBe(true);
});
test('should handle authentication errors gracefully', async () => {
// Mock authentication failure
jest.spyOn(authManager, 'determineUserTier').mockRejectedValue(
new Error('Authentication failed')
);
const context = {
task: 'Auth test',
userTier: 'free', // Fallback tier
priority: 'low',
latencyRequirement: 1000
};
// Should still work with fallback
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValue({
modelUsed: 'gemini-2.0-flash',
content: 'Fallback response',
latency: 900,
tokenUsage: { input: 10, output: 15, total: 25 },
cost: 0.000025,
cached: false,
metadata: { authFallback: true }
});
const result = await orchestrator.orchestrate('Auth test', context);
expect(result).toBeDefined();
expect(result.modelUsed).toBe('gemini-2.0-flash');
});
});
describe('Load Balancing', () => {
test('should distribute load across multiple models', async () => {
const models = ['gemini-2.0-flash', 'gemini-2.0-flash-thinking'];
const usedModels = new Set();
// Make multiple requests
for (let i = 0; i < 10; i++) {
const context = {
task: `Load test ${i}`,
userTier: 'pro',
priority: 'medium',
latencyRequirement: 1500
};
const selectedModel = models[i % models.length];
usedModels.add(selectedModel);
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValueOnce({
modelUsed: selectedModel,
content: `Response ${i}`,
latency: 800 + (i * 10),
tokenUsage: { input: 10, output: 20, total: 30 },
cost: 0.00003,
cached: false,
metadata: {}
});
const result = await orchestrator.orchestrate(`Load test ${i}`, context);
expect(result.modelUsed).toBe(selectedModel);
}
// Should have used multiple models
expect(usedModels.size).toBeGreaterThan(1);
});
});
describe('Health Monitoring', () => {
test('should perform health checks on all models', async () => {
const mockHealthResults = {
'gemini-2.0-flash': true,
'gemini-2.0-flash-thinking': true,
'gemini-2.5-deepmind': false, // Simulate one model being down
'gemini-pro-vertex': true
};
jest.spyOn(orchestrator, 'healthCheck').mockResolvedValue(mockHealthResults);
const health = await orchestrator.healthCheck();
expect(health).toEqual(mockHealthResults);
expect(health['gemini-2.0-flash']).toBe(true);
expect(health['gemini-2.5-deepmind']).toBe(false);
});
test('should provide comprehensive metrics', async () => {
const mockMetrics = {
totalRequests: 100,
avgRoutingTime: 75,
cacheHitRate: 0.65,
failoverRate: 0.02,
modelDistribution: {
'gemini-2.0-flash': 60,
'gemini-2.0-flash-thinking': 30,
'gemini-pro-vertex': 10
},
performance: {
orchestration_latency: { mean: 1200, p95: 2000 },
routing_overhead: { mean: 80, p95: 120 }
}
};
jest.spyOn(orchestrator, 'getMetrics').mockReturnValue(mockMetrics);
const metrics = orchestrator.getMetrics();
expect(metrics).toEqual(mockMetrics);
expect(metrics.avgRoutingTime).toBeLessThan(100);
expect(metrics.cacheHitRate).toBeGreaterThan(0.5);
expect(metrics.performance.routing_overhead.p95).toBeLessThan(150);
});
});
describe('Stress Testing', () => {
test('should handle concurrent requests efficiently', async () => {
const concurrentRequests = 20;
const requests = [];
for (let i = 0; i < concurrentRequests; i++) {
const context = {
task: `Concurrent test ${i}`,
userTier: 'pro',
priority: 'medium',
latencyRequirement: 2000
};
// Mock varying response times
const mockResponse = {
modelUsed: 'gemini-2.0-flash',
content: `Concurrent response ${i}`,
latency: 500 + Math.random() * 1000,
tokenUsage: { input: 15, output: 25, total: 40 },
cost: 0.00004,
cached: false,
metadata: { concurrent: true }
};
jest.spyOn(orchestrator, 'orchestrate').mockResolvedValue(mockResponse);
requests.push(orchestrator.orchestrate(`Concurrent test ${i}`, context));
}
const startTime = performance.now();
const results = await Promise.all(requests);
const totalTime = performance.now() - startTime;
expect(results).toHaveLength(concurrentRequests);
expect(totalTime).toBeLessThan(5000); // Should complete within 5 seconds
// All requests should succeed
results.forEach(result => {
expect(result).toBeDefined();
expect(result.modelUsed).toBeDefined();
expect(result.content).toBeDefined();
});
});
});
});