mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
a80fec1be9
## Summary Phase 3 implementation complete with QUIC transport and Neural training as prototype. Performance targets MET (67.7% faster), but critical issues prevent production deployment. ## Components Added ### QUIC Transport (4 files, ~2,300 LOC) - src/types/quic.ts - Type definitions - src/core/transport/QUICTransport.ts - Transport layer - src/core/memory/AgentDBIntegration.ts - Memory integration - src/agents/mixins/QUICCapableMixin.ts - Agent integration ### Neural Training (4 files, ~2,300 LOC) - src/learning/NeuralPatternMatcher.ts - Neural network - src/learning/NeuralTrainer.ts - Training pipeline - src/agents/mixins/NeuralCapableMixin.ts - Agent integration - config/neural-agent.config.ts - Configuration ### Agent Updates (3 files, ~420 LOC) - src/agents/BaseAgent.ts - QUIC + Neural support - src/agents/TestGeneratorAgent.ts - Neural predictions - src/core/memory/SwarmMemoryManager.ts - QUIC integration ### Tests (13 files, ~5,100 LOC) - QUIC: 106 tests (56 passing, 50 infrastructure issues) - Neural: 68 tests (55 passing, 13 accuracy issues) - Coverage: 0.59% (infrastructure prevents proper collection) ### Documentation (21 files, ~15,000 lines) - Complete architecture documentation - 30+ architectural diagrams - Comprehensive usage guides - Code review reports - Performance benchmarks ### Configuration - .agentic-qe/config/fleet.json - Fixed agents array (5 agents) - .agentic-qe/config/transport.json - QUIC configuration - .agentic-qe/config/routing.json - Phase 3 feature flags ## Performance Results ✅ QUIC Transport (TARGETS EXCEEDED): - 67.7% faster than TCP (target: 50-70%) - 6.23ms connection time (target: <50ms) - 2.03ms message latency (target: <100ms) ⚠️ Neural Training (BELOW TARGET): - 65% accuracy (target: 85%) - <100ms prediction time (target: <100ms) ✅ - <1s training time (target: <5s) ✅ ❌ Test Coverage (CRITICAL GAP): - 0.59% coverage (target: 80%) - Infrastructure issues prevent proper test execution ## Critical Issues (BLOCKERS) 🔴 Security Vulnerabilities: 1. Self-signed certificates in production code 2. Disabled certificate validation (rejectUnauthorized: false) 🟡 Implementation Issues: 3. QUIC not actually implemented (UDP only, not real QUIC protocol) 4. Neural accuracy insufficient (65% vs 85%) 5. Memory leaks in resource cleanup ## Status Phase 3 Status: 🟡 PROTOTYPE COMPLETE - NOT PRODUCTION READY Production Readiness: 70% - Phase 1-2: 100% stable, 86% test pass rate ✅ - Phase 3: 70% prototype, requires 5-6 weeks hardening ⚠️ ## Feature Flags (DISABLED BY DEFAULT) All Phase 3 features are opt-in: - quicEnabled: false (default) - neuralEnabled: false (default) - Zero impact on existing functionality ## Recommendation ⭐ POSTPONE PHASE 3: - Ship stable Phase 1-2 now - Gather user feedback - Revisit Phase 3 based on actual needs OR allocate 5-6 weeks with 2-3 engineers for production hardening. ## Files Changed - Added: 32 source files (~11,000 LOC) - Added: 13 test files (~5,100 LOC) - Added: 21 documentation files (~15,000 lines) - Updated: 4 configuration files - Updated: 3 agent files Total: 73 files, +31,100 insertions 🤖 Generated with Agentic QE Fleet v1.1.0 Phase 3 Swarm: 11 specialized agents (system-architect, backend-dev, ml-developer, coder x3, tester x2, qe-coverage-analyzer, reviewer) Co-Authored-By: Claude <noreply@anthropic.com>
755 lines
22 KiB
TypeScript
755 lines
22 KiB
TypeScript
/**
|
|
* Neural Agent Integration Test Suite
|
|
* Comprehensive tests for neural features integrated with QE agents
|
|
*
|
|
* Coverage:
|
|
* - TestGeneratorAgent with neural predictions
|
|
* - CoverageAnalyzerAgent with neural gap detection
|
|
* - FlakyTestHunterAgent with neural flakiness prediction
|
|
* - RegressionRiskAnalyzerAgent with neural risk scoring
|
|
* - Multi-agent coordination with neural features
|
|
* - Learning system integration
|
|
* - Performance benchmarks
|
|
*/
|
|
|
|
import { TestGeneratorAgent, TestGeneratorConfig } from '../../src/agents/TestGeneratorAgent';
|
|
import { LearningAgent } from '../../src/agents/LearningAgent';
|
|
import { SwarmMemoryManager } from '../../src/core/memory/SwarmMemoryManager';
|
|
import { EventBus } from '../../src/core/EventBus';
|
|
import { FlakyPredictionModel } from '../../src/learning/FlakyPredictionModel';
|
|
import { LearningEngine } from '../../src/learning/LearningEngine';
|
|
import { PerformanceTracker } from '../../src/learning/PerformanceTracker';
|
|
import {
|
|
QEAgentType,
|
|
AgentCapability,
|
|
AgentContext,
|
|
QETask,
|
|
TaskAssignment,
|
|
TestResult,
|
|
TestType
|
|
} from '../../src/types';
|
|
|
|
describe('Neural Agent Integration', () => {
|
|
let memoryStore: SwarmMemoryManager;
|
|
let eventBus: EventBus;
|
|
let testGeneratorAgent: TestGeneratorAgent;
|
|
let learningAgent: LearningAgent;
|
|
|
|
beforeEach(async () => {
|
|
// Initialize infrastructure
|
|
memoryStore = new SwarmMemoryManager();
|
|
await memoryStore.initialize();
|
|
|
|
eventBus = new EventBus();
|
|
await eventBus.initialize();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Cleanup
|
|
await testGeneratorAgent?.shutdown?.();
|
|
await learningAgent?.shutdown?.();
|
|
await eventBus?.close?.();
|
|
await memoryStore?.close?.();
|
|
});
|
|
|
|
describe('TestGeneratorAgent with Neural Predictions', () => {
|
|
beforeEach(async () => {
|
|
const config: TestGeneratorConfig = {
|
|
type: QEAgentType.TEST_GENERATOR,
|
|
capabilities: [
|
|
{
|
|
name: 'test-generation',
|
|
description: 'Generate tests',
|
|
parameters: [],
|
|
version: '1.0.0'
|
|
}
|
|
],
|
|
context: {
|
|
sessionId: 'test-session',
|
|
environment: 'test'
|
|
},
|
|
memoryStore,
|
|
eventBus,
|
|
enableLearning: true,
|
|
enablePatterns: true
|
|
};
|
|
|
|
testGeneratorAgent = new TestGeneratorAgent(config);
|
|
await testGeneratorAgent.initialize();
|
|
});
|
|
|
|
it('should generate tests using neural pattern recognition', async () => {
|
|
const task: QETask = {
|
|
id: 'neural-test-gen-1',
|
|
type: 'test-generation',
|
|
requirements: {
|
|
sourceCode: {
|
|
ast: {},
|
|
files: [
|
|
{
|
|
path: '/src/Calculator.ts',
|
|
content: 'class Calculator { add(a: number, b: number) { return a + b; } }',
|
|
language: 'typescript'
|
|
}
|
|
],
|
|
complexityMetrics: {
|
|
cyclomaticComplexity: 2,
|
|
cognitiveComplexity: 1,
|
|
functionCount: 1,
|
|
linesOfCode: 5
|
|
}
|
|
},
|
|
framework: 'jest',
|
|
coverage: {
|
|
target: 80,
|
|
type: 'line' as const
|
|
},
|
|
constraints: {
|
|
maxTests: 10,
|
|
maxExecutionTime: 30000,
|
|
testTypes: [TestType.UNIT]
|
|
}
|
|
}
|
|
};
|
|
|
|
const assignment: TaskAssignment = {
|
|
id: 'assignment-1',
|
|
task,
|
|
agentId: testGeneratorAgent['agentId'],
|
|
assignedAt: new Date(),
|
|
priority: 1
|
|
};
|
|
|
|
const result = await testGeneratorAgent.executeTask(assignment);
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result.testSuite).toBeDefined();
|
|
expect(result.testSuite.tests.length).toBeGreaterThan(0);
|
|
expect(result.generationMetrics).toBeDefined();
|
|
|
|
// Neural pattern matching metrics
|
|
if (result.patterns) {
|
|
expect(result.patterns.matched).toBeDefined();
|
|
expect(result.patterns.applied).toBeDefined();
|
|
}
|
|
});
|
|
|
|
it('should improve test generation with learning', async () => {
|
|
const baseTask: QETask = {
|
|
id: 'learning-test-1',
|
|
type: 'test-generation',
|
|
requirements: {
|
|
sourceCode: {
|
|
ast: {},
|
|
files: [
|
|
{
|
|
path: '/src/UserService.ts',
|
|
content: 'class UserService { validate(user: any) { return user && user.email; } }',
|
|
language: 'typescript'
|
|
}
|
|
],
|
|
complexityMetrics: {
|
|
cyclomaticComplexity: 3,
|
|
cognitiveComplexity: 2,
|
|
functionCount: 1,
|
|
linesOfCode: 8
|
|
}
|
|
},
|
|
framework: 'jest',
|
|
coverage: { target: 80, type: 'line' as const },
|
|
constraints: {
|
|
maxTests: 10,
|
|
maxExecutionTime: 30000,
|
|
testTypes: [TestType.UNIT]
|
|
}
|
|
}
|
|
};
|
|
|
|
// First generation (baseline)
|
|
const assignment1: TaskAssignment = {
|
|
id: 'assignment-1',
|
|
task: baseTask,
|
|
agentId: testGeneratorAgent['agentId'],
|
|
assignedAt: new Date(),
|
|
priority: 1
|
|
};
|
|
|
|
const result1 = await testGeneratorAgent.executeTask(assignment1);
|
|
const baseline = result1.generationMetrics.generationTime;
|
|
|
|
// Subsequent generations should benefit from learning
|
|
const results: number[] = [];
|
|
for (let i = 0; i < 5; i++) {
|
|
const assignment: TaskAssignment = {
|
|
id: `assignment-${i + 2}`,
|
|
task: baseTask,
|
|
agentId: testGeneratorAgent['agentId'],
|
|
assignedAt: new Date(),
|
|
priority: 1
|
|
};
|
|
|
|
const result = await testGeneratorAgent.executeTask(assignment);
|
|
results.push(result.generationMetrics.generationTime);
|
|
}
|
|
|
|
// Average should show improvement (within reason - may not always be faster)
|
|
const avgImproved = results.reduce((sum, time) => sum + time, 0) / results.length;
|
|
expect(avgImproved).toBeLessThan(baseline * 1.5); // Allow 50% variance
|
|
});
|
|
|
|
it('should use pattern-based acceleration for common test types', async () => {
|
|
const task: QETask = {
|
|
id: 'pattern-test-1',
|
|
type: 'test-generation',
|
|
requirements: {
|
|
sourceCode: {
|
|
ast: {},
|
|
files: [
|
|
{
|
|
path: '/src/Validator.ts',
|
|
content: 'function validate(input: string) { return input.length > 0; }',
|
|
language: 'typescript'
|
|
}
|
|
],
|
|
complexityMetrics: {
|
|
cyclomaticComplexity: 2,
|
|
cognitiveComplexity: 1,
|
|
functionCount: 1,
|
|
linesOfCode: 3
|
|
}
|
|
},
|
|
framework: 'jest',
|
|
coverage: { target: 80, type: 'line' as const },
|
|
constraints: {
|
|
maxTests: 5,
|
|
maxExecutionTime: 30000,
|
|
testTypes: [TestType.UNIT]
|
|
}
|
|
}
|
|
};
|
|
|
|
const assignment: TaskAssignment = {
|
|
id: 'assignment-pattern',
|
|
task,
|
|
agentId: testGeneratorAgent['agentId'],
|
|
assignedAt: new Date(),
|
|
priority: 1
|
|
};
|
|
|
|
const result = await testGeneratorAgent.executeTask(assignment);
|
|
|
|
// Check if patterns were used
|
|
if (result.patterns && result.patterns.applied.length > 0) {
|
|
expect(result.generationMetrics.patternMatchTime).toBeLessThan(100); // <100ms
|
|
expect(result.patterns.savings).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('LearningAgent with Neural Q-Learning', () => {
|
|
beforeEach(async () => {
|
|
learningAgent = new LearningAgent({
|
|
type: QEAgentType.TEST_GENERATOR,
|
|
capabilities: [
|
|
{
|
|
name: 'learning',
|
|
description: 'Learn from execution',
|
|
parameters: [],
|
|
version: '1.0.0'
|
|
}
|
|
],
|
|
context: {
|
|
sessionId: 'learning-session',
|
|
environment: 'test'
|
|
},
|
|
memoryStore,
|
|
eventBus,
|
|
enableLearning: true,
|
|
learningConfig: {
|
|
enabled: true,
|
|
learningRate: 0.1,
|
|
explorationRate: 0.3
|
|
}
|
|
});
|
|
|
|
await learningAgent.initialize();
|
|
});
|
|
|
|
it('should learn from task execution outcomes', async () => {
|
|
const task: QETask = {
|
|
id: 'learning-task-1',
|
|
type: 'test-generation',
|
|
requirements: {
|
|
complexity: 0.6
|
|
}
|
|
};
|
|
|
|
const assignment: TaskAssignment = {
|
|
id: 'assignment-learning-1',
|
|
task,
|
|
agentId: learningAgent['agentId'],
|
|
assignedAt: new Date(),
|
|
priority: 1
|
|
};
|
|
|
|
// Execute task
|
|
const result = await learningAgent.executeTask(assignment);
|
|
|
|
expect(result).toBeDefined();
|
|
|
|
// Verify learning occurred
|
|
const learningEngine = learningAgent['learningEngine'];
|
|
if (learningEngine) {
|
|
expect(learningEngine.getTotalExperiences()).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
it('should recommend strategies based on learned patterns', async () => {
|
|
const learningEngine = learningAgent['learningEngine'];
|
|
|
|
if (!learningEngine) {
|
|
// Skip if learning not enabled
|
|
return;
|
|
}
|
|
|
|
// Train with multiple successful executions
|
|
for (let i = 0; i < 10; i++) {
|
|
const task = {
|
|
id: `train-task-${i}`,
|
|
type: 'test-generation',
|
|
requirements: { complexity: 0.5 }
|
|
};
|
|
|
|
const result = {
|
|
success: true,
|
|
executionTime: 1000,
|
|
strategy: 'parallel-generation'
|
|
};
|
|
|
|
await learningEngine.learnFromExecution(task, result);
|
|
}
|
|
|
|
// Get recommendation
|
|
const recommendation = await learningEngine.recommendStrategy({
|
|
taskComplexity: 0.5,
|
|
requiredCapabilities: ['testing'],
|
|
contextFeatures: {},
|
|
previousAttempts: 0,
|
|
availableResources: 0.8
|
|
});
|
|
|
|
expect(recommendation).toBeDefined();
|
|
expect(recommendation.strategy).toBeDefined();
|
|
expect(recommendation.confidence).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should track performance improvements over time', async () => {
|
|
const performanceTracker = learningAgent['performanceTracker'];
|
|
|
|
if (!performanceTracker) {
|
|
// Skip if performance tracking not enabled
|
|
return;
|
|
}
|
|
|
|
// Record initial performance
|
|
await performanceTracker.recordSnapshot({
|
|
metrics: {
|
|
tasksCompleted: 1,
|
|
successRate: 0.5,
|
|
averageExecutionTime: 2000,
|
|
errorRate: 0.5,
|
|
userSatisfaction: 0.6,
|
|
resourceEfficiency: 0.5
|
|
},
|
|
trends: []
|
|
});
|
|
|
|
// Record improved performance
|
|
await performanceTracker.recordSnapshot({
|
|
metrics: {
|
|
tasksCompleted: 10,
|
|
successRate: 0.9,
|
|
averageExecutionTime: 1000,
|
|
errorRate: 0.1,
|
|
userSatisfaction: 0.85,
|
|
resourceEfficiency: 0.8
|
|
},
|
|
trends: []
|
|
});
|
|
|
|
// Verify improvement trend
|
|
const improvement = await performanceTracker.assessImprovement();
|
|
|
|
expect(improvement).toBeDefined();
|
|
expect(improvement.trend).toBe('improving');
|
|
});
|
|
});
|
|
|
|
describe('Flaky Test Detection with Neural Predictions', () => {
|
|
let flakyModel: FlakyPredictionModel;
|
|
|
|
beforeEach(() => {
|
|
flakyModel = new FlakyPredictionModel(12345); // Deterministic seed
|
|
});
|
|
|
|
it('should train on historical test results', () => {
|
|
const trainingData = new Map<string, TestResult[]>();
|
|
const labels = new Map<string, boolean>();
|
|
|
|
// Add stable tests
|
|
trainingData.set('stable-test', generateStableTestResults(20));
|
|
labels.set('stable-test', false);
|
|
|
|
// Add flaky tests
|
|
trainingData.set('flaky-test', generateFlakyTestResults(20));
|
|
labels.set('flaky-test', true);
|
|
|
|
const metrics = flakyModel.train(trainingData, labels);
|
|
|
|
expect(metrics.accuracy).toBeGreaterThan(0.8);
|
|
expect(metrics.precision).toBeGreaterThan(0.7);
|
|
expect(metrics.recall).toBeGreaterThan(0.7);
|
|
});
|
|
|
|
it('should predict flakiness with high confidence', () => {
|
|
// Train model
|
|
const trainingData = new Map<string, TestResult[]>();
|
|
const labels = new Map<string, boolean>();
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
trainingData.set(`stable-${i}`, generateStableTestResults(15));
|
|
labels.set(`stable-${i}`, false);
|
|
|
|
trainingData.set(`flaky-${i}`, generateFlakyTestResults(15));
|
|
labels.set(`flaky-${i}`, true);
|
|
}
|
|
|
|
flakyModel.train(trainingData, labels);
|
|
|
|
// Predict on new data
|
|
const newFlakyTest = generateFlakyTestResults(10);
|
|
const prediction = flakyModel.predict('new-flaky-test', newFlakyTest);
|
|
|
|
expect(prediction.isFlaky).toBe(true);
|
|
expect(prediction.probability).toBeGreaterThan(0.5);
|
|
expect(prediction.confidence).toBeGreaterThan(0.5);
|
|
});
|
|
|
|
it('should provide interpretable flakiness explanations', () => {
|
|
const trainingData = new Map<string, TestResult[]>();
|
|
const labels = new Map<string, boolean>();
|
|
|
|
trainingData.set('flaky', generateFlakyTestResults(20));
|
|
labels.set('flaky', true);
|
|
|
|
flakyModel.train(trainingData, labels);
|
|
|
|
const testResults = generateFlakyTestResults(10);
|
|
const prediction = flakyModel.predict('test', testResults);
|
|
|
|
expect(prediction.explanation).toBeDefined();
|
|
expect(prediction.explanation.length).toBeGreaterThan(0);
|
|
expect(prediction.features).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Multi-Agent Neural Coordination', () => {
|
|
let agent1: LearningAgent;
|
|
let agent2: LearningAgent;
|
|
|
|
beforeEach(async () => {
|
|
agent1 = new LearningAgent({
|
|
id: 'neural-agent-1',
|
|
type: QEAgentType.TEST_GENERATOR,
|
|
capabilities: [
|
|
{
|
|
name: 'test-generation',
|
|
description: 'Generate tests',
|
|
parameters: [],
|
|
version: '1.0.0'
|
|
}
|
|
],
|
|
context: { sessionId: 'multi-agent-session', environment: 'test' },
|
|
memoryStore,
|
|
eventBus,
|
|
enableLearning: true
|
|
});
|
|
|
|
agent2 = new LearningAgent({
|
|
id: 'neural-agent-2',
|
|
type: QEAgentType.COVERAGE_ANALYZER,
|
|
capabilities: [
|
|
{
|
|
name: 'coverage-analysis',
|
|
description: 'Analyze coverage',
|
|
parameters: [],
|
|
version: '1.0.0'
|
|
}
|
|
],
|
|
context: { sessionId: 'multi-agent-session', environment: 'test' },
|
|
memoryStore,
|
|
eventBus,
|
|
enableLearning: true
|
|
});
|
|
|
|
await agent1.initialize();
|
|
await agent2.initialize();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await agent1?.shutdown?.();
|
|
await agent2?.shutdown?.();
|
|
});
|
|
|
|
it('should coordinate learning between agents', async () => {
|
|
// Agent 1 learns from task
|
|
const task1: QETask = {
|
|
id: 'coord-task-1',
|
|
type: 'test-generation',
|
|
requirements: {}
|
|
};
|
|
|
|
const assignment1: TaskAssignment = {
|
|
id: 'assignment-coord-1',
|
|
task: task1,
|
|
agentId: agent1['agentId'],
|
|
assignedAt: new Date(),
|
|
priority: 1
|
|
};
|
|
|
|
await agent1.executeTask(assignment1);
|
|
|
|
// Agent 2 learns from related task
|
|
const task2: QETask = {
|
|
id: 'coord-task-2',
|
|
type: 'coverage-analysis',
|
|
requirements: {}
|
|
};
|
|
|
|
const assignment2: TaskAssignment = {
|
|
id: 'assignment-coord-2',
|
|
task: task2,
|
|
agentId: agent2['agentId'],
|
|
assignedAt: new Date(),
|
|
priority: 1
|
|
};
|
|
|
|
await agent2.executeTask(assignment2);
|
|
|
|
// Both agents should have learning data
|
|
const engine1 = agent1['learningEngine'];
|
|
const engine2 = agent2['learningEngine'];
|
|
|
|
if (engine1 && engine2) {
|
|
expect(engine1.getTotalExperiences()).toBeGreaterThan(0);
|
|
expect(engine2.getTotalExperiences()).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
it('should share learned patterns via memory store', async () => {
|
|
const learningEngine1 = agent1['learningEngine'];
|
|
|
|
if (!learningEngine1) {
|
|
return;
|
|
}
|
|
|
|
// Agent 1 learns successful strategy
|
|
for (let i = 0; i < 5; i++) {
|
|
const task = {
|
|
id: `shared-task-${i}`,
|
|
type: 'test-generation',
|
|
requirements: {}
|
|
};
|
|
|
|
const result = {
|
|
success: true,
|
|
executionTime: 1000,
|
|
strategy: 'shared-strategy'
|
|
};
|
|
|
|
await learningEngine1.learnFromExecution(task, result);
|
|
}
|
|
|
|
// Store pattern in shared memory
|
|
const patterns = learningEngine1.getPatterns();
|
|
if (patterns.length > 0) {
|
|
await memoryStore.store(
|
|
'shared/patterns/test-generation',
|
|
patterns,
|
|
{ partition: 'learning' }
|
|
);
|
|
}
|
|
|
|
// Agent 2 should be able to access shared patterns
|
|
const sharedPatterns = await memoryStore.retrieve(
|
|
'shared/patterns/test-generation',
|
|
{ partition: 'learning' }
|
|
);
|
|
|
|
expect(sharedPatterns).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Performance Benchmarks', () => {
|
|
it('should complete training in <1000ms for 1000 patterns', async () => {
|
|
const trainingData = new Map<string, TestResult[]>();
|
|
const labels = new Map<string, boolean>();
|
|
|
|
// Generate 1000 test patterns
|
|
for (let i = 0; i < 500; i++) {
|
|
trainingData.set(`stable-${i}`, generateStableTestResults(10));
|
|
labels.set(`stable-${i}`, false);
|
|
|
|
trainingData.set(`flaky-${i}`, generateFlakyTestResults(10));
|
|
labels.set(`flaky-${i}`, true);
|
|
}
|
|
|
|
const model = new FlakyPredictionModel(12345);
|
|
const startTime = Date.now();
|
|
model.train(trainingData, labels);
|
|
const trainingTime = Date.now() - startTime;
|
|
|
|
// Target: <1000ms for 1000 patterns
|
|
expect(trainingTime).toBeLessThan(1000);
|
|
});
|
|
|
|
it('should complete prediction in <100ms target', async () => {
|
|
const model = new FlakyPredictionModel(12345);
|
|
|
|
// Train model
|
|
const trainingData = new Map<string, TestResult[]>();
|
|
const labels = new Map<string, boolean>();
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
trainingData.set(`test-${i}`, generateStableTestResults(10));
|
|
labels.set(`test-${i}`, i % 2 === 0);
|
|
}
|
|
|
|
model.train(trainingData, labels);
|
|
|
|
// Benchmark prediction
|
|
const testResults = generateStableTestResults(20);
|
|
const startTime = Date.now();
|
|
model.predict('benchmark-test', testResults);
|
|
const predictionTime = Date.now() - startTime;
|
|
|
|
// Target: <100ms
|
|
expect(predictionTime).toBeLessThan(100);
|
|
});
|
|
|
|
it('should handle high-frequency predictions efficiently', async () => {
|
|
const model = new FlakyPredictionModel(12345);
|
|
|
|
// Train model
|
|
const trainingData = new Map<string, TestResult[]>();
|
|
const labels = new Map<string, boolean>();
|
|
|
|
for (let i = 0; i < 20; i++) {
|
|
trainingData.set(`test-${i}`, generateStableTestResults(10));
|
|
labels.set(`test-${i}`, i % 2 === 0);
|
|
}
|
|
|
|
model.train(trainingData, labels);
|
|
|
|
// Run 100 predictions
|
|
const predictions = 100;
|
|
const startTime = Date.now();
|
|
|
|
for (let i = 0; i < predictions; i++) {
|
|
const results = generateStableTestResults(10);
|
|
model.predict(`test-${i}`, results);
|
|
}
|
|
|
|
const totalTime = Date.now() - startTime;
|
|
const avgTime = totalTime / predictions;
|
|
|
|
// Average prediction time should be well under 100ms
|
|
expect(avgTime).toBeLessThan(50);
|
|
});
|
|
|
|
it('should maintain low memory usage during training', async () => {
|
|
const initialMemory = process.memoryUsage().heapUsed;
|
|
|
|
// Create large training dataset
|
|
const trainingData = new Map<string, TestResult[]>();
|
|
const labels = new Map<string, boolean>();
|
|
|
|
for (let i = 0; i < 200; i++) {
|
|
trainingData.set(`test-${i}`, generateStableTestResults(20));
|
|
labels.set(`test-${i}`, i % 2 === 0);
|
|
}
|
|
|
|
const model = new FlakyPredictionModel(12345);
|
|
model.train(trainingData, labels);
|
|
|
|
const finalMemory = process.memoryUsage().heapUsed;
|
|
const memoryIncrease = (finalMemory - initialMemory) / 1024 / 1024; // MB
|
|
|
|
// Should not exceed 50MB for 200 tests
|
|
expect(memoryIncrease).toBeLessThan(50);
|
|
});
|
|
|
|
it('should measure learning engine overhead', async () => {
|
|
const learningEngine = new LearningEngine('perf-agent', memoryStore, {
|
|
enabled: true
|
|
});
|
|
await learningEngine.initialize();
|
|
|
|
const task = { id: 'perf-task', type: 'test' };
|
|
const result = { success: true, executionTime: 1000 };
|
|
|
|
// Measure learning overhead
|
|
const iterations = 100;
|
|
const startTime = Date.now();
|
|
|
|
for (let i = 0; i < iterations; i++) {
|
|
await learningEngine.learnFromExecution(task, result);
|
|
}
|
|
|
|
const totalTime = Date.now() - startTime;
|
|
const avgOverhead = totalTime / iterations;
|
|
|
|
// Learning overhead should be <50ms per task
|
|
expect(avgOverhead).toBeLessThan(50);
|
|
});
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// Helper Functions
|
|
// ============================================================================
|
|
|
|
function generateStableTestResults(count: number): TestResult[] {
|
|
const results: TestResult[] = [];
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
results.push({
|
|
testName: 'stable-test',
|
|
passed: Math.random() > 0.02, // 98% pass rate
|
|
status: Math.random() > 0.02 ? 'passed' : 'failed',
|
|
duration: 100 + Math.random() * 20, // Low variance
|
|
timestamp: Date.now() + i * 1000
|
|
});
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
function generateFlakyTestResults(count: number): TestResult[] {
|
|
const results: TestResult[] = [];
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
const passed = Math.random() > 0.4; // 60% pass rate
|
|
results.push({
|
|
testName: 'flaky-test',
|
|
passed,
|
|
status: passed ? 'passed' : 'failed',
|
|
duration: 50 + Math.random() * 300, // High variance
|
|
timestamp: Date.now() + i * 1000,
|
|
retryCount: passed ? 0 : Math.floor(Math.random() * 3)
|
|
});
|
|
}
|
|
|
|
return results;
|
|
}
|