agentic-qe 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/analysis/code-analyzer.md +209 -0
- package/.claude/agents/analysis/code-review/analyze-code-quality.md +180 -0
- package/.claude/agents/architecture/system-design/arch-system-design.md +156 -0
- package/.claude/agents/base-template-generator.md +42 -0
- package/.claude/agents/consensus/byzantine-coordinator.md +63 -0
- package/.claude/agents/consensus/crdt-synchronizer.md +997 -0
- package/.claude/agents/consensus/gossip-coordinator.md +63 -0
- package/.claude/agents/consensus/performance-benchmarker.md +851 -0
- package/.claude/agents/consensus/quorum-manager.md +823 -0
- package/.claude/agents/consensus/raft-manager.md +63 -0
- package/.claude/agents/consensus/security-manager.md +622 -0
- package/.claude/agents/core/coder.md +266 -0
- package/.claude/agents/core/planner.md +168 -0
- package/.claude/agents/core/researcher.md +190 -0
- package/.claude/agents/core/reviewer.md +326 -0
- package/.claude/agents/core/tester.md +319 -0
- package/.claude/agents/data/ml/data-ml-model.md +193 -0
- package/.claude/agents/development/backend/dev-backend-api.md +142 -0
- package/.claude/agents/devops/ci-cd/ops-cicd-github.md +164 -0
- package/.claude/agents/documentation/api-docs/docs-api-openapi.md +174 -0
- package/.claude/agents/flow-nexus/app-store.md +88 -0
- package/.claude/agents/flow-nexus/authentication.md +69 -0
- package/.claude/agents/flow-nexus/challenges.md +81 -0
- package/.claude/agents/flow-nexus/neural-network.md +88 -0
- package/.claude/agents/flow-nexus/payments.md +83 -0
- package/.claude/agents/flow-nexus/sandbox.md +76 -0
- package/.claude/agents/flow-nexus/swarm.md +76 -0
- package/.claude/agents/flow-nexus/user-tools.md +96 -0
- package/.claude/agents/flow-nexus/workflow.md +84 -0
- package/.claude/agents/github/code-review-swarm.md +538 -0
- package/.claude/agents/github/github-modes.md +173 -0
- package/.claude/agents/github/issue-tracker.md +319 -0
- package/.claude/agents/github/multi-repo-swarm.md +553 -0
- package/.claude/agents/github/pr-manager.md +191 -0
- package/.claude/agents/github/project-board-sync.md +509 -0
- package/.claude/agents/github/release-manager.md +367 -0
- package/.claude/agents/github/release-swarm.md +583 -0
- package/.claude/agents/github/repo-architect.md +398 -0
- package/.claude/agents/github/swarm-issue.md +573 -0
- package/.claude/agents/github/swarm-pr.md +428 -0
- package/.claude/agents/github/sync-coordinator.md +452 -0
- package/.claude/agents/github/workflow-automation.md +635 -0
- package/.claude/agents/goal/code-goal-planner.md +446 -0
- package/.claude/agents/goal/goal-planner.md +168 -0
- package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +130 -0
- package/.claude/agents/hive-mind/queen-coordinator.md +203 -0
- package/.claude/agents/hive-mind/scout-explorer.md +242 -0
- package/.claude/agents/hive-mind/swarm-memory-manager.md +193 -0
- package/.claude/agents/hive-mind/worker-specialist.md +217 -0
- package/.claude/agents/neural/safla-neural.md +74 -0
- package/.claude/agents/optimization/benchmark-suite.md +665 -0
- package/.claude/agents/optimization/load-balancer.md +431 -0
- package/.claude/agents/optimization/performance-monitor.md +672 -0
- package/.claude/agents/optimization/resource-allocator.md +674 -0
- package/.claude/agents/optimization/topology-optimizer.md +808 -0
- package/.claude/agents/qe-api-contract-validator.md +1088 -0
- package/.claude/agents/qe-chaos-engineer.md +736 -0
- package/.claude/agents/qe-coverage-analyzer.md +282 -0
- package/.claude/agents/qe-deployment-readiness.md +1109 -0
- package/.claude/agents/qe-flaky-test-hunter.md +1121 -0
- package/.claude/agents/qe-fleet-commander.md +641 -0
- package/.claude/agents/qe-performance-tester.md +354 -0
- package/.claude/agents/qe-production-intelligence.md +1162 -0
- package/.claude/agents/qe-quality-gate.md +294 -0
- package/.claude/agents/qe-regression-risk-analyzer.md +947 -0
- package/.claude/agents/qe-requirements-validator.md +691 -0
- package/.claude/agents/qe-security-scanner.md +430 -0
- package/.claude/agents/qe-test-data-architect.md +1007 -0
- package/.claude/agents/qe-test-executor.md +365 -0
- package/.claude/agents/qe-test-generator.md +332 -0
- package/.claude/agents/qe-visual-tester.md +754 -0
- package/.claude/agents/sparc/architecture.md +472 -0
- package/.claude/agents/sparc/pseudocode.md +318 -0
- package/.claude/agents/sparc/refinement.md +525 -0
- package/.claude/agents/sparc/specification.md +276 -0
- package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +226 -0
- package/.claude/agents/swarm/adaptive-coordinator.md +396 -0
- package/.claude/agents/swarm/hierarchical-coordinator.md +327 -0
- package/.claude/agents/swarm/mesh-coordinator.md +392 -0
- package/.claude/agents/templates/automation-smart-agent.md +205 -0
- package/.claude/agents/templates/coordinator-swarm-init.md +105 -0
- package/.claude/agents/templates/github-pr-manager.md +177 -0
- package/.claude/agents/templates/implementer-sparc-coder.md +259 -0
- package/.claude/agents/templates/memory-coordinator.md +187 -0
- package/.claude/agents/templates/migration-plan.md +746 -0
- package/.claude/agents/templates/orchestrator-task.md +139 -0
- package/.claude/agents/templates/performance-analyzer.md +199 -0
- package/.claude/agents/templates/sparc-coordinator.md +183 -0
- package/.claude/agents/testing/unit/tdd-london-swarm.md +244 -0
- package/.claude/agents/testing/validation/production-validator.md +395 -0
- package/.claude/aqe-fleet.json +47 -0
- package/.claude/commands/README.md +106 -0
- package/.claude/commands/agents/README.md +10 -0
- package/.claude/commands/agents/agent-capabilities.md +21 -0
- package/.claude/commands/agents/agent-coordination.md +28 -0
- package/.claude/commands/agents/agent-spawning.md +28 -0
- package/.claude/commands/agents/agent-types.md +26 -0
- package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +54 -0
- package/.claude/commands/analysis/README.md +9 -0
- package/.claude/commands/analysis/bottleneck-detect.md +162 -0
- package/.claude/commands/analysis/performance-bottlenecks.md +59 -0
- package/.claude/commands/analysis/performance-report.md +25 -0
- package/.claude/commands/analysis/token-efficiency.md +45 -0
- package/.claude/commands/analysis/token-usage.md +25 -0
- package/.claude/commands/aqe-analyze.md +344 -0
- package/.claude/commands/aqe-benchmark.md +466 -0
- package/.claude/commands/aqe-chaos.md +443 -0
- package/.claude/commands/aqe-execute.md +322 -0
- package/.claude/commands/aqe-fleet-status.md +431 -0
- package/.claude/commands/aqe-generate.md +301 -0
- package/.claude/commands/aqe-optimize.md +361 -0
- package/.claude/commands/aqe-report.md +411 -0
- package/.claude/commands/automation/README.md +9 -0
- package/.claude/commands/automation/auto-agent.md +122 -0
- package/.claude/commands/automation/self-healing.md +106 -0
- package/.claude/commands/automation/session-memory.md +90 -0
- package/.claude/commands/automation/smart-agents.md +73 -0
- package/.claude/commands/automation/smart-spawn.md +25 -0
- package/.claude/commands/automation/workflow-select.md +25 -0
- package/.claude/commands/coordination/README.md +9 -0
- package/.claude/commands/coordination/agent-spawn.md +25 -0
- package/.claude/commands/coordination/init.md +44 -0
- package/.claude/commands/coordination/orchestrate.md +43 -0
- package/.claude/commands/coordination/spawn.md +45 -0
- package/.claude/commands/coordination/swarm-init.md +85 -0
- package/.claude/commands/coordination/task-orchestrate.md +25 -0
- package/.claude/commands/flow-nexus/app-store.md +124 -0
- package/.claude/commands/flow-nexus/challenges.md +120 -0
- package/.claude/commands/flow-nexus/login-registration.md +65 -0
- package/.claude/commands/flow-nexus/neural-network.md +134 -0
- package/.claude/commands/flow-nexus/payments.md +116 -0
- package/.claude/commands/flow-nexus/sandbox.md +83 -0
- package/.claude/commands/flow-nexus/swarm.md +87 -0
- package/.claude/commands/flow-nexus/user-tools.md +152 -0
- package/.claude/commands/flow-nexus/workflow.md +115 -0
- package/.claude/commands/github/README.md +11 -0
- package/.claude/commands/github/code-review-swarm.md +514 -0
- package/.claude/commands/github/code-review.md +25 -0
- package/.claude/commands/github/github-modes.md +147 -0
- package/.claude/commands/github/github-swarm.md +121 -0
- package/.claude/commands/github/issue-tracker.md +292 -0
- package/.claude/commands/github/issue-triage.md +25 -0
- package/.claude/commands/github/multi-repo-swarm.md +519 -0
- package/.claude/commands/github/pr-enhance.md +26 -0
- package/.claude/commands/github/pr-manager.md +170 -0
- package/.claude/commands/github/project-board-sync.md +471 -0
- package/.claude/commands/github/release-manager.md +338 -0
- package/.claude/commands/github/release-swarm.md +544 -0
- package/.claude/commands/github/repo-analyze.md +25 -0
- package/.claude/commands/github/repo-architect.md +367 -0
- package/.claude/commands/github/swarm-issue.md +482 -0
- package/.claude/commands/github/swarm-pr.md +285 -0
- package/.claude/commands/github/sync-coordinator.md +301 -0
- package/.claude/commands/github/workflow-automation.md +442 -0
- package/.claude/commands/hive-mind/README.md +17 -0
- package/.claude/commands/hive-mind/hive-mind-consensus.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-init.md +18 -0
- package/.claude/commands/hive-mind/hive-mind-memory.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-metrics.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-resume.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-sessions.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-spawn.md +21 -0
- package/.claude/commands/hive-mind/hive-mind-status.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-stop.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-wizard.md +8 -0
- package/.claude/commands/hive-mind/hive-mind.md +27 -0
- package/.claude/commands/hooks/README.md +11 -0
- package/.claude/commands/hooks/overview.md +132 -0
- package/.claude/commands/hooks/post-edit.md +117 -0
- package/.claude/commands/hooks/post-task.md +112 -0
- package/.claude/commands/hooks/pre-edit.md +113 -0
- package/.claude/commands/hooks/pre-task.md +111 -0
- package/.claude/commands/hooks/session-end.md +118 -0
- package/.claude/commands/hooks/setup.md +103 -0
- package/.claude/commands/memory/README.md +9 -0
- package/.claude/commands/memory/memory-persist.md +25 -0
- package/.claude/commands/memory/memory-search.md +25 -0
- package/.claude/commands/memory/memory-usage.md +25 -0
- package/.claude/commands/memory/neural.md +47 -0
- package/.claude/commands/memory/usage.md +46 -0
- package/.claude/commands/monitoring/README.md +9 -0
- package/.claude/commands/monitoring/agent-metrics.md +25 -0
- package/.claude/commands/monitoring/agents.md +44 -0
- package/.claude/commands/monitoring/real-time-view.md +25 -0
- package/.claude/commands/monitoring/status.md +46 -0
- package/.claude/commands/monitoring/swarm-monitor.md +25 -0
- package/.claude/commands/optimization/README.md +9 -0
- package/.claude/commands/optimization/auto-topology.md +62 -0
- package/.claude/commands/optimization/cache-manage.md +25 -0
- package/.claude/commands/optimization/parallel-execute.md +25 -0
- package/.claude/commands/optimization/parallel-execution.md +50 -0
- package/.claude/commands/optimization/topology-optimize.md +25 -0
- package/.claude/commands/pair/commands.md +546 -0
- package/.claude/commands/pair/config.md +510 -0
- package/.claude/commands/pair/examples.md +512 -0
- package/.claude/commands/pair/modes.md +348 -0
- package/.claude/commands/pair/session.md +407 -0
- package/.claude/commands/pair/start.md +209 -0
- package/.claude/commands/sparc/analyzer.md +52 -0
- package/.claude/commands/sparc/architect.md +53 -0
- package/.claude/commands/sparc/batch-executor.md +54 -0
- package/.claude/commands/sparc/coder.md +54 -0
- package/.claude/commands/sparc/debugger.md +54 -0
- package/.claude/commands/sparc/designer.md +53 -0
- package/.claude/commands/sparc/documenter.md +54 -0
- package/.claude/commands/sparc/innovator.md +54 -0
- package/.claude/commands/sparc/memory-manager.md +54 -0
- package/.claude/commands/sparc/optimizer.md +54 -0
- package/.claude/commands/sparc/orchestrator.md +132 -0
- package/.claude/commands/sparc/researcher.md +54 -0
- package/.claude/commands/sparc/reviewer.md +54 -0
- package/.claude/commands/sparc/sparc-modes.md +174 -0
- package/.claude/commands/sparc/swarm-coordinator.md +54 -0
- package/.claude/commands/sparc/tdd.md +54 -0
- package/.claude/commands/sparc/tester.md +54 -0
- package/.claude/commands/sparc/workflow-manager.md +54 -0
- package/.claude/commands/stream-chain/pipeline.md +121 -0
- package/.claude/commands/stream-chain/run.md +70 -0
- package/.claude/commands/swarm/README.md +15 -0
- package/.claude/commands/swarm/analysis.md +95 -0
- package/.claude/commands/swarm/development.md +96 -0
- package/.claude/commands/swarm/examples.md +168 -0
- package/.claude/commands/swarm/maintenance.md +102 -0
- package/.claude/commands/swarm/optimization.md +117 -0
- package/.claude/commands/swarm/research.md +136 -0
- package/.claude/commands/swarm/swarm-analysis.md +8 -0
- package/.claude/commands/swarm/swarm-background.md +8 -0
- package/.claude/commands/swarm/swarm-init.md +19 -0
- package/.claude/commands/swarm/swarm-modes.md +8 -0
- package/.claude/commands/swarm/swarm-monitor.md +8 -0
- package/.claude/commands/swarm/swarm-spawn.md +19 -0
- package/.claude/commands/swarm/swarm-status.md +8 -0
- package/.claude/commands/swarm/swarm-strategies.md +8 -0
- package/.claude/commands/swarm/swarm.md +27 -0
- package/.claude/commands/swarm/testing.md +131 -0
- package/.claude/commands/training/README.md +9 -0
- package/.claude/commands/training/model-update.md +25 -0
- package/.claude/commands/training/neural-patterns.md +74 -0
- package/.claude/commands/training/neural-train.md +25 -0
- package/.claude/commands/training/pattern-learn.md +25 -0
- package/.claude/commands/training/specialization.md +63 -0
- package/.claude/commands/truth/start.md +143 -0
- package/.claude/commands/verify/check.md +50 -0
- package/.claude/commands/verify/start.md +128 -0
- package/.claude/commands/workflows/README.md +9 -0
- package/.claude/commands/workflows/development.md +78 -0
- package/.claude/commands/workflows/research.md +63 -0
- package/.claude/commands/workflows/workflow-create.md +25 -0
- package/.claude/commands/workflows/workflow-execute.md +25 -0
- package/.claude/commands/workflows/workflow-export.md +25 -0
- package/.claude/helpers/checkpoint-manager.sh +251 -0
- package/.claude/helpers/github-safe.js +106 -0
- package/.claude/helpers/github-setup.sh +28 -0
- package/.claude/helpers/quick-start.sh +19 -0
- package/.claude/helpers/setup-mcp.sh +18 -0
- package/.claude/helpers/standard-checkpoint-hooks.sh +179 -0
- package/.claude/settings.json +114 -0
- package/.claude/settings.local.json +10 -0
- package/CONTRIBUTING.md +897 -0
- package/LICENSE +21 -0
- package/README.md +632 -0
- package/bin/aqe +959 -0
- package/config/fleet.yaml +50 -0
- package/dist/agents/ApiContractValidatorAgent.d.ts +222 -0
- package/dist/agents/ApiContractValidatorAgent.d.ts.map +1 -0
- package/dist/agents/ApiContractValidatorAgent.js +787 -0
- package/dist/agents/ApiContractValidatorAgent.js.map +1 -0
- package/dist/agents/BaseAgent.d.ts +147 -0
- package/dist/agents/BaseAgent.d.ts.map +1 -0
- package/dist/agents/BaseAgent.js +374 -0
- package/dist/agents/BaseAgent.js.map +1 -0
- package/dist/agents/CoverageAnalyzerAgent.d.ts +103 -0
- package/dist/agents/CoverageAnalyzerAgent.d.ts.map +1 -0
- package/dist/agents/CoverageAnalyzerAgent.js +466 -0
- package/dist/agents/CoverageAnalyzerAgent.js.map +1 -0
- package/dist/agents/DeploymentReadinessAgent.d.ts +244 -0
- package/dist/agents/DeploymentReadinessAgent.d.ts.map +1 -0
- package/dist/agents/DeploymentReadinessAgent.js +974 -0
- package/dist/agents/DeploymentReadinessAgent.js.map +1 -0
- package/dist/agents/FlakyTestHunterAgent.d.ts +172 -0
- package/dist/agents/FlakyTestHunterAgent.d.ts.map +1 -0
- package/dist/agents/FlakyTestHunterAgent.js +867 -0
- package/dist/agents/FlakyTestHunterAgent.js.map +1 -0
- package/dist/agents/FleetCommanderAgent.d.ts +154 -0
- package/dist/agents/FleetCommanderAgent.d.ts.map +1 -0
- package/dist/agents/FleetCommanderAgent.js +924 -0
- package/dist/agents/FleetCommanderAgent.js.map +1 -0
- package/dist/agents/PerformanceTesterAgent.d.ts +194 -0
- package/dist/agents/PerformanceTesterAgent.d.ts.map +1 -0
- package/dist/agents/PerformanceTesterAgent.js +972 -0
- package/dist/agents/PerformanceTesterAgent.js.map +1 -0
- package/dist/agents/ProductionIntelligenceAgent.d.ts +224 -0
- package/dist/agents/ProductionIntelligenceAgent.d.ts.map +1 -0
- package/dist/agents/ProductionIntelligenceAgent.js +856 -0
- package/dist/agents/ProductionIntelligenceAgent.js.map +1 -0
- package/dist/agents/QualityAnalyzerAgent.d.ts +67 -0
- package/dist/agents/QualityAnalyzerAgent.d.ts.map +1 -0
- package/dist/agents/QualityAnalyzerAgent.js +453 -0
- package/dist/agents/QualityAnalyzerAgent.js.map +1 -0
- package/dist/agents/QualityGateAgent.d.ts +104 -0
- package/dist/agents/QualityGateAgent.d.ts.map +1 -0
- package/dist/agents/QualityGateAgent.js +522 -0
- package/dist/agents/QualityGateAgent.js.map +1 -0
- package/dist/agents/RegressionRiskAnalyzerAgent.d.ts +274 -0
- package/dist/agents/RegressionRiskAnalyzerAgent.d.ts.map +1 -0
- package/dist/agents/RegressionRiskAnalyzerAgent.js +1076 -0
- package/dist/agents/RegressionRiskAnalyzerAgent.js.map +1 -0
- package/dist/agents/RequirementsValidatorAgent.d.ts +195 -0
- package/dist/agents/RequirementsValidatorAgent.d.ts.map +1 -0
- package/dist/agents/RequirementsValidatorAgent.js +992 -0
- package/dist/agents/RequirementsValidatorAgent.js.map +1 -0
- package/dist/agents/SecurityScannerAgent.d.ts +126 -0
- package/dist/agents/SecurityScannerAgent.d.ts.map +1 -0
- package/dist/agents/SecurityScannerAgent.js +695 -0
- package/dist/agents/SecurityScannerAgent.js.map +1 -0
- package/dist/agents/TestDataArchitectAgent.d.ts +452 -0
- package/dist/agents/TestDataArchitectAgent.d.ts.map +1 -0
- package/dist/agents/TestDataArchitectAgent.js +1346 -0
- package/dist/agents/TestDataArchitectAgent.js.map +1 -0
- package/dist/agents/TestExecutorAgent.d.ts +101 -0
- package/dist/agents/TestExecutorAgent.d.ts.map +1 -0
- package/dist/agents/TestExecutorAgent.js +730 -0
- package/dist/agents/TestExecutorAgent.js.map +1 -0
- package/dist/agents/TestGeneratorAgent.d.ts +109 -0
- package/dist/agents/TestGeneratorAgent.d.ts.map +1 -0
- package/dist/agents/TestGeneratorAgent.js +450 -0
- package/dist/agents/TestGeneratorAgent.js.map +1 -0
- package/dist/agents/index.d.ts +51 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +738 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +32 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +764 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/fleet.d.ts +36 -0
- package/dist/cli/commands/fleet.d.ts.map +1 -0
- package/dist/cli/commands/fleet.js +745 -0
- package/dist/cli/commands/fleet.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +24 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +424 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +17 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +570 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/run.d.ts +25 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +558 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/index-spec.d.ts +3 -0
- package/dist/cli/index-spec.d.ts.map +1 -0
- package/dist/cli/index-spec.js +154 -0
- package/dist/cli/index-spec.js.map +1 -0
- package/dist/cli/index-working.d.ts +7 -0
- package/dist/cli/index-working.d.ts.map +1 -0
- package/dist/cli/index-working.js +470 -0
- package/dist/cli/index-working.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +174 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/Agent.d.ts +189 -0
- package/dist/core/Agent.d.ts.map +1 -0
- package/dist/core/Agent.js +288 -0
- package/dist/core/Agent.js.map +1 -0
- package/dist/core/EventBus.d.ts +40 -0
- package/dist/core/EventBus.d.ts.map +1 -0
- package/dist/core/EventBus.js +114 -0
- package/dist/core/EventBus.js.map +1 -0
- package/dist/core/FleetManager.d.ts +219 -0
- package/dist/core/FleetManager.d.ts.map +1 -0
- package/dist/core/FleetManager.js +354 -0
- package/dist/core/FleetManager.js.map +1 -0
- package/dist/core/MemoryManager.d.ts +119 -0
- package/dist/core/MemoryManager.d.ts.map +1 -0
- package/dist/core/MemoryManager.js +460 -0
- package/dist/core/MemoryManager.js.map +1 -0
- package/dist/core/Task.d.ts +264 -0
- package/dist/core/Task.d.ts.map +1 -0
- package/dist/core/Task.js +397 -0
- package/dist/core/Task.js.map +1 -0
- package/dist/core/coverage-analyzer.d.ts +50 -0
- package/dist/core/coverage-analyzer.d.ts.map +1 -0
- package/dist/core/coverage-analyzer.js +146 -0
- package/dist/core/coverage-analyzer.js.map +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +20 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/quality-gate.d.ts +81 -0
- package/dist/core/quality-gate.d.ts.map +1 -0
- package/dist/core/quality-gate.js +254 -0
- package/dist/core/quality-gate.js.map +1 -0
- package/dist/coverage/coverage-collector.d.ts +62 -0
- package/dist/coverage/coverage-collector.d.ts.map +1 -0
- package/dist/coverage/coverage-collector.js +61 -0
- package/dist/coverage/coverage-collector.js.map +1 -0
- package/dist/coverage/coverage-reporter.d.ts +42 -0
- package/dist/coverage/coverage-reporter.d.ts.map +1 -0
- package/dist/coverage/coverage-reporter.js +53 -0
- package/dist/coverage/coverage-reporter.js.map +1 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/handlers/agent-spawn.d.ts +72 -0
- package/dist/mcp/handlers/agent-spawn.d.ts.map +1 -0
- package/dist/mcp/handlers/agent-spawn.js +255 -0
- package/dist/mcp/handlers/agent-spawn.js.map +1 -0
- package/dist/mcp/handlers/base-handler.d.ts +53 -0
- package/dist/mcp/handlers/base-handler.d.ts.map +1 -0
- package/dist/mcp/handlers/base-handler.js +77 -0
- package/dist/mcp/handlers/base-handler.js.map +1 -0
- package/dist/mcp/handlers/fleet-init.d.ts +55 -0
- package/dist/mcp/handlers/fleet-init.d.ts.map +1 -0
- package/dist/mcp/handlers/fleet-init.js +149 -0
- package/dist/mcp/handlers/fleet-init.js.map +1 -0
- package/dist/mcp/handlers/fleet-status.d.ts +103 -0
- package/dist/mcp/handlers/fleet-status.d.ts.map +1 -0
- package/dist/mcp/handlers/fleet-status.js +244 -0
- package/dist/mcp/handlers/fleet-status.js.map +1 -0
- package/dist/mcp/handlers/optimize-tests.d.ts +219 -0
- package/dist/mcp/handlers/optimize-tests.d.ts.map +1 -0
- package/dist/mcp/handlers/optimize-tests.js +532 -0
- package/dist/mcp/handlers/optimize-tests.js.map +1 -0
- package/dist/mcp/handlers/predict-defects.d.ts +194 -0
- package/dist/mcp/handlers/predict-defects.d.ts.map +1 -0
- package/dist/mcp/handlers/predict-defects.js +721 -0
- package/dist/mcp/handlers/predict-defects.js.map +1 -0
- package/dist/mcp/handlers/quality-analyze.d.ts +273 -0
- package/dist/mcp/handlers/quality-analyze.d.ts.map +1 -0
- package/dist/mcp/handlers/quality-analyze.js +702 -0
- package/dist/mcp/handlers/quality-analyze.js.map +1 -0
- package/dist/mcp/handlers/task-orchestrate.d.ts +152 -0
- package/dist/mcp/handlers/task-orchestrate.d.ts.map +1 -0
- package/dist/mcp/handlers/task-orchestrate.js +629 -0
- package/dist/mcp/handlers/task-orchestrate.js.map +1 -0
- package/dist/mcp/handlers/test-execute.d.ts +132 -0
- package/dist/mcp/handlers/test-execute.d.ts.map +1 -0
- package/dist/mcp/handlers/test-execute.js +436 -0
- package/dist/mcp/handlers/test-execute.js.map +1 -0
- package/dist/mcp/handlers/test-generate.d.ts +107 -0
- package/dist/mcp/handlers/test-generate.d.ts.map +1 -0
- package/dist/mcp/handlers/test-generate.js +437 -0
- package/dist/mcp/handlers/test-generate.js.map +1 -0
- package/dist/mcp/server.d.ts +99 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +214 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/services/AgentRegistry.d.ts +191 -0
- package/dist/mcp/services/AgentRegistry.d.ts.map +1 -0
- package/dist/mcp/services/AgentRegistry.js +403 -0
- package/dist/mcp/services/AgentRegistry.js.map +1 -0
- package/dist/mcp/services/HookExecutor.d.ts +165 -0
- package/dist/mcp/services/HookExecutor.d.ts.map +1 -0
- package/dist/mcp/services/HookExecutor.js +327 -0
- package/dist/mcp/services/HookExecutor.js.map +1 -0
- package/dist/mcp/start.d.ts +7 -0
- package/dist/mcp/start.d.ts.map +1 -0
- package/dist/mcp/start.js +35 -0
- package/dist/mcp/start.js.map +1 -0
- package/dist/mcp/tools.d.ts +81 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +471 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/optimization/sublinear-solver.d.ts +72 -0
- package/dist/optimization/sublinear-solver.d.ts.map +1 -0
- package/dist/optimization/sublinear-solver.js +263 -0
- package/dist/optimization/sublinear-solver.js.map +1 -0
- package/dist/scripts/verifyComplexity.d.ts +8 -0
- package/dist/scripts/verifyComplexity.d.ts.map +1 -0
- package/dist/scripts/verifyComplexity.js +56 -0
- package/dist/scripts/verifyComplexity.js.map +1 -0
- package/dist/types/api-contract.types.d.ts +273 -0
- package/dist/types/api-contract.types.d.ts.map +1 -0
- package/dist/types/api-contract.types.js +18 -0
- package/dist/types/api-contract.types.js.map +1 -0
- package/dist/types/errors.d.ts +104 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +226 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/events.d.ts +101 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +6 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +570 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +131 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/Config.d.ts +128 -0
- package/dist/utils/Config.d.ts.map +1 -0
- package/dist/utils/Config.js +232 -0
- package/dist/utils/Config.js.map +1 -0
- package/dist/utils/Database.d.ts +112 -0
- package/dist/utils/Database.d.ts.map +1 -0
- package/dist/utils/Database.js +352 -0
- package/dist/utils/Database.js.map +1 -0
- package/dist/utils/Logger.d.ts +58 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +125 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +14 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/sublinear/coverageOptimizer.d.ts +84 -0
- package/dist/utils/sublinear/coverageOptimizer.d.ts.map +1 -0
- package/dist/utils/sublinear/coverageOptimizer.js +415 -0
- package/dist/utils/sublinear/coverageOptimizer.js.map +1 -0
- package/dist/utils/sublinear/index.d.ts +50 -0
- package/dist/utils/sublinear/index.d.ts.map +1 -0
- package/dist/utils/sublinear/index.js +390 -0
- package/dist/utils/sublinear/index.js.map +1 -0
- package/dist/utils/sublinear/matrixSolver.d.ts +132 -0
- package/dist/utils/sublinear/matrixSolver.d.ts.map +1 -0
- package/dist/utils/sublinear/matrixSolver.js +642 -0
- package/dist/utils/sublinear/matrixSolver.js.map +1 -0
- package/dist/utils/sublinear/temporalPredictor.d.ts +195 -0
- package/dist/utils/sublinear/temporalPredictor.d.ts.map +1 -0
- package/dist/utils/sublinear/temporalPredictor.js +474 -0
- package/dist/utils/sublinear/temporalPredictor.js.map +1 -0
- package/dist/utils/sublinear/testSelector.d.ts +81 -0
- package/dist/utils/sublinear/testSelector.d.ts.map +1 -0
- package/dist/utils/sublinear/testSelector.js +303 -0
- package/dist/utils/sublinear/testSelector.js.map +1 -0
- package/package.json +131 -0
|
@@ -0,0 +1,972 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PerformanceTesterAgent - Load testing and bottleneck detection specialist
|
|
4
|
+
*
|
|
5
|
+
* Implements load testing orchestration (JMeter, K6, Gatling, Artillery),
|
|
6
|
+
* bottleneck detection, resource monitoring, SLA validation, performance
|
|
7
|
+
* regression detection, and load pattern generation.
|
|
8
|
+
*
|
|
9
|
+
* Based on SPARC methodology and AQE Fleet specification
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PerformanceTesterAgent = void 0;
|
|
13
|
+
const BaseAgent_1 = require("./BaseAgent");
|
|
14
|
+
const types_1 = require("../types");
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Performance Tester Agent Implementation
|
|
17
|
+
// ============================================================================
|
|
18
|
+
class PerformanceTesterAgent extends BaseAgent_1.BaseAgent {
|
|
19
|
+
constructor(config) {
|
|
20
|
+
const defaultThresholds = {
|
|
21
|
+
maxLatencyP95: 500,
|
|
22
|
+
maxLatencyP99: 1000,
|
|
23
|
+
minThroughput: 1000,
|
|
24
|
+
maxErrorRate: 0.01,
|
|
25
|
+
maxCpuUsage: 80,
|
|
26
|
+
maxMemoryUsage: 85
|
|
27
|
+
};
|
|
28
|
+
super({
|
|
29
|
+
...config,
|
|
30
|
+
type: types_1.QEAgentType.PERFORMANCE_TESTER,
|
|
31
|
+
capabilities: [
|
|
32
|
+
{
|
|
33
|
+
name: 'load-testing-orchestration',
|
|
34
|
+
version: '1.0.0',
|
|
35
|
+
description: 'Execute load tests using multiple tools (K6, JMeter, Gatling, Artillery)',
|
|
36
|
+
parameters: {
|
|
37
|
+
supportedTools: ['k6', 'jmeter', 'gatling', 'artillery'],
|
|
38
|
+
maxVirtualUsers: 10000,
|
|
39
|
+
maxDuration: 7200 // 2 hours
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'bottleneck-detection',
|
|
44
|
+
version: '1.0.0',
|
|
45
|
+
description: 'Identify performance bottlenecks in CPU, memory, I/O, database, and network',
|
|
46
|
+
parameters: {
|
|
47
|
+
analysisTypes: ['cpu', 'memory', 'io', 'database', 'network'],
|
|
48
|
+
detectionAlgorithm: 'statistical-analysis'
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'resource-monitoring',
|
|
53
|
+
version: '1.0.0',
|
|
54
|
+
description: 'Real-time resource monitoring during load tests',
|
|
55
|
+
parameters: {
|
|
56
|
+
metrics: ['cpu', 'memory', 'disk', 'network', 'connections'],
|
|
57
|
+
samplingInterval: 1000 // 1 second
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'sla-validation',
|
|
62
|
+
version: '1.0.0',
|
|
63
|
+
description: 'Validate performance against SLA thresholds',
|
|
64
|
+
parameters: {
|
|
65
|
+
thresholds: config.thresholds || defaultThresholds
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'performance-regression-detection',
|
|
70
|
+
version: '1.0.0',
|
|
71
|
+
description: 'Detect performance regressions by comparing against baselines',
|
|
72
|
+
parameters: {
|
|
73
|
+
comparisonStrategy: 'statistical',
|
|
74
|
+
regressionThreshold: 0.1 // 10% degradation
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'load-pattern-generation',
|
|
79
|
+
version: '1.0.0',
|
|
80
|
+
description: 'Generate realistic load patterns (spike, ramp-up, stress, soak)',
|
|
81
|
+
parameters: {
|
|
82
|
+
patterns: ['constant', 'ramp-up', 'spike', 'stress', 'soak']
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
this.activeTests = new Map();
|
|
88
|
+
this.baselines = new Map();
|
|
89
|
+
this.config = {
|
|
90
|
+
...config,
|
|
91
|
+
tools: {
|
|
92
|
+
loadTesting: 'k6',
|
|
93
|
+
monitoring: ['prometheus'],
|
|
94
|
+
...config.tools
|
|
95
|
+
},
|
|
96
|
+
thresholds: {
|
|
97
|
+
...defaultThresholds,
|
|
98
|
+
...config.thresholds
|
|
99
|
+
},
|
|
100
|
+
loadProfile: {
|
|
101
|
+
virtualUsers: 100,
|
|
102
|
+
duration: 300,
|
|
103
|
+
rampUpTime: 30,
|
|
104
|
+
pattern: 'ramp-up',
|
|
105
|
+
...config.loadProfile
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// BaseAgent Implementation
|
|
111
|
+
// ============================================================================
|
|
112
|
+
async initializeComponents() {
|
|
113
|
+
console.log(`PerformanceTesterAgent ${this.agentId.id} initializing...`);
|
|
114
|
+
// Initialize load testing client
|
|
115
|
+
await this.initializeLoadTestingClient();
|
|
116
|
+
// Initialize monitoring client
|
|
117
|
+
await this.initializeMonitoringClient();
|
|
118
|
+
// Load historical baselines
|
|
119
|
+
await this.loadBaselines();
|
|
120
|
+
// Register event handlers
|
|
121
|
+
this.registerPerformanceEventHandlers();
|
|
122
|
+
console.log(`PerformanceTesterAgent ${this.agentId.id} initialized successfully`);
|
|
123
|
+
}
|
|
124
|
+
async performTask(task) {
|
|
125
|
+
const { type, payload } = task;
|
|
126
|
+
console.log(`PerformanceTesterAgent executing ${type} task: ${task.id}`);
|
|
127
|
+
switch (type) {
|
|
128
|
+
case 'run-load-test':
|
|
129
|
+
return await this.runLoadTest(payload);
|
|
130
|
+
case 'detect-bottlenecks':
|
|
131
|
+
return await this.detectBottlenecks(payload);
|
|
132
|
+
case 'validate-sla':
|
|
133
|
+
return await this.validateSLA(payload);
|
|
134
|
+
case 'detect-regressions':
|
|
135
|
+
return await this.detectRegressions(payload);
|
|
136
|
+
case 'generate-load-pattern':
|
|
137
|
+
return await this.generateLoadPattern(payload);
|
|
138
|
+
case 'establish-baseline':
|
|
139
|
+
return await this.establishBaseline(payload);
|
|
140
|
+
case 'analyze-performance':
|
|
141
|
+
return await this.analyzePerformance(payload);
|
|
142
|
+
default:
|
|
143
|
+
throw new Error(`Unsupported task type: ${type}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async loadKnowledge() {
|
|
147
|
+
// Load performance testing knowledge from memory
|
|
148
|
+
const storedKnowledge = await this.retrieveMemory('performance-knowledge');
|
|
149
|
+
if (storedKnowledge) {
|
|
150
|
+
console.log('Loaded performance testing knowledge from memory');
|
|
151
|
+
}
|
|
152
|
+
// Load test results history
|
|
153
|
+
const resultsHistory = await this.memoryStore.retrieve('aqe/performance/results/history');
|
|
154
|
+
if (resultsHistory) {
|
|
155
|
+
console.log('Loaded test results history from memory');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async cleanup() {
|
|
159
|
+
// Save current state
|
|
160
|
+
await this.storeMemory('performance-state', {
|
|
161
|
+
activeTests: Array.from(this.activeTests.entries()),
|
|
162
|
+
baselines: Array.from(this.baselines.entries()),
|
|
163
|
+
timestamp: new Date()
|
|
164
|
+
});
|
|
165
|
+
// Cleanup load testing client
|
|
166
|
+
if (this.loadTestingClient) {
|
|
167
|
+
console.log('Cleaning up load testing client');
|
|
168
|
+
// In real implementation, close connections
|
|
169
|
+
this.loadTestingClient = undefined;
|
|
170
|
+
}
|
|
171
|
+
// Cleanup monitoring client
|
|
172
|
+
if (this.monitoringClient) {
|
|
173
|
+
console.log('Cleaning up monitoring client');
|
|
174
|
+
// In real implementation, close connections
|
|
175
|
+
this.monitoringClient = undefined;
|
|
176
|
+
}
|
|
177
|
+
this.activeTests.clear();
|
|
178
|
+
console.log(`PerformanceTesterAgent ${this.agentId.id} cleaned up`);
|
|
179
|
+
}
|
|
180
|
+
// ============================================================================
|
|
181
|
+
// Load Testing Orchestration
|
|
182
|
+
// ============================================================================
|
|
183
|
+
async runLoadTest(metadata) {
|
|
184
|
+
const testConfig = this.parseTestConfig(metadata);
|
|
185
|
+
const testId = `loadtest-${Date.now()}`;
|
|
186
|
+
console.log(`Starting load test ${testId} with ${testConfig.loadProfile.virtualUsers} VUs`);
|
|
187
|
+
// Emit test started event
|
|
188
|
+
this.emitEvent('performance.test.started', {
|
|
189
|
+
testId,
|
|
190
|
+
config: testConfig
|
|
191
|
+
}, 'medium');
|
|
192
|
+
const startTime = new Date();
|
|
193
|
+
try {
|
|
194
|
+
// Generate load test script
|
|
195
|
+
const script = this.generateLoadTestScript(testConfig);
|
|
196
|
+
// Execute load test
|
|
197
|
+
const rawResults = await this.executeLoadTest(script, testConfig);
|
|
198
|
+
// Collect monitoring data
|
|
199
|
+
const monitoringData = await this.collectMonitoringData(testId);
|
|
200
|
+
// Analyze results
|
|
201
|
+
const metrics = this.analyzeLoadTestResults(rawResults, monitoringData);
|
|
202
|
+
// Detect bottlenecks
|
|
203
|
+
const bottlenecks = await this.analyzeBottlenecks(metrics);
|
|
204
|
+
// Validate SLA
|
|
205
|
+
const slaViolations = this.checkSLAViolations(metrics, testConfig.thresholds);
|
|
206
|
+
// Generate recommendations
|
|
207
|
+
const recommendations = this.generateRecommendations(metrics, bottlenecks, slaViolations);
|
|
208
|
+
const endTime = new Date();
|
|
209
|
+
const result = {
|
|
210
|
+
id: testId,
|
|
211
|
+
startTime,
|
|
212
|
+
endTime,
|
|
213
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
214
|
+
metrics,
|
|
215
|
+
bottlenecks,
|
|
216
|
+
slaViolations,
|
|
217
|
+
recommendations
|
|
218
|
+
};
|
|
219
|
+
// Store results
|
|
220
|
+
await this.storeTestResults(testId, result);
|
|
221
|
+
// Emit test completed event
|
|
222
|
+
this.emitEvent('performance.test.completed', {
|
|
223
|
+
testId,
|
|
224
|
+
metrics,
|
|
225
|
+
passed: slaViolations.length === 0
|
|
226
|
+
}, slaViolations.length > 0 ? 'high' : 'medium');
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
console.error(`Load test ${testId} failed:`, error);
|
|
231
|
+
this.emitEvent('performance.test.failed', {
|
|
232
|
+
testId,
|
|
233
|
+
error: error instanceof Error ? error.message : String(error)
|
|
234
|
+
}, 'high');
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
generateLoadTestScript(config) {
|
|
239
|
+
const tool = this.config.tools.loadTesting;
|
|
240
|
+
switch (tool) {
|
|
241
|
+
case 'k6':
|
|
242
|
+
return this.generateK6Script(config);
|
|
243
|
+
case 'jmeter':
|
|
244
|
+
return this.generateJMeterScript(config);
|
|
245
|
+
case 'gatling':
|
|
246
|
+
return this.generateGatlingScript(config);
|
|
247
|
+
case 'artillery':
|
|
248
|
+
return this.generateArtilleryScript(config);
|
|
249
|
+
default:
|
|
250
|
+
throw new Error(`Unsupported load testing tool: ${tool}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
generateK6Script(config) {
|
|
254
|
+
const { loadProfile, thresholds } = config;
|
|
255
|
+
return `
|
|
256
|
+
import http from 'k6/http';
|
|
257
|
+
import { check, sleep } from 'k6';
|
|
258
|
+
import { Rate, Trend } from 'k6/metrics';
|
|
259
|
+
|
|
260
|
+
const errorRate = new Rate('errors');
|
|
261
|
+
const latency = new Trend('latency');
|
|
262
|
+
|
|
263
|
+
export let options = {
|
|
264
|
+
stages: ${this.generateStages(loadProfile)},
|
|
265
|
+
thresholds: {
|
|
266
|
+
'http_req_duration': ['p(95)<${thresholds.maxLatencyP95}', 'p(99)<${thresholds.maxLatencyP99}'],
|
|
267
|
+
'http_reqs': ['rate>${thresholds.minThroughput}'],
|
|
268
|
+
'errors': ['rate<${thresholds.maxErrorRate}']
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
export default function() {
|
|
273
|
+
const endpoints = ${JSON.stringify(loadProfile.endpoints || [])};
|
|
274
|
+
|
|
275
|
+
// Select endpoint based on distribution
|
|
276
|
+
const endpoint = selectEndpoint(endpoints);
|
|
277
|
+
|
|
278
|
+
const response = http.request(
|
|
279
|
+
endpoint.method,
|
|
280
|
+
\`${config.targetUrl}\${endpoint.path}\`,
|
|
281
|
+
endpoint.payload
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
check(response, {
|
|
285
|
+
'status is 2xx': (r) => r.status >= 200 && r.status < 300,
|
|
286
|
+
'response time < ${thresholds.maxLatencyP95}ms': (r) => r.timings.duration < ${thresholds.maxLatencyP95}
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
errorRate.add(response.status >= 400);
|
|
290
|
+
latency.add(response.timings.duration);
|
|
291
|
+
|
|
292
|
+
sleep(Math.random() * 2 + 1);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function selectEndpoint(endpoints) {
|
|
296
|
+
if (endpoints.length === 0) {
|
|
297
|
+
return { path: '/', method: 'GET', percentage: 100 };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const rand = Math.random() * 100;
|
|
301
|
+
let cumulative = 0;
|
|
302
|
+
|
|
303
|
+
for (const endpoint of endpoints) {
|
|
304
|
+
cumulative += endpoint.percentage;
|
|
305
|
+
if (rand <= cumulative) {
|
|
306
|
+
return endpoint;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return endpoints[0];
|
|
311
|
+
}
|
|
312
|
+
`.trim();
|
|
313
|
+
}
|
|
314
|
+
generateStages(profile) {
|
|
315
|
+
switch (profile.pattern) {
|
|
316
|
+
case 'constant':
|
|
317
|
+
return `[
|
|
318
|
+
{ duration: '${profile.duration}s', target: ${profile.virtualUsers} }
|
|
319
|
+
]`;
|
|
320
|
+
case 'ramp-up':
|
|
321
|
+
return `[
|
|
322
|
+
{ duration: '${profile.rampUpTime}s', target: ${profile.virtualUsers} },
|
|
323
|
+
{ duration: '${profile.duration - profile.rampUpTime}s', target: ${profile.virtualUsers} }
|
|
324
|
+
]`;
|
|
325
|
+
case 'spike':
|
|
326
|
+
const spikeVUs = profile.virtualUsers * 3;
|
|
327
|
+
return `[
|
|
328
|
+
{ duration: '${profile.rampUpTime}s', target: ${profile.virtualUsers} },
|
|
329
|
+
{ duration: '30s', target: ${spikeVUs} },
|
|
330
|
+
{ duration: '30s', target: ${profile.virtualUsers} },
|
|
331
|
+
{ duration: '${profile.duration - profile.rampUpTime - 60}s', target: ${profile.virtualUsers} }
|
|
332
|
+
]`;
|
|
333
|
+
case 'stress':
|
|
334
|
+
return `[
|
|
335
|
+
{ duration: '${Math.floor(profile.duration / 4)}s', target: ${profile.virtualUsers} },
|
|
336
|
+
{ duration: '${Math.floor(profile.duration / 4)}s', target: ${profile.virtualUsers * 2} },
|
|
337
|
+
{ duration: '${Math.floor(profile.duration / 4)}s', target: ${profile.virtualUsers * 3} },
|
|
338
|
+
{ duration: '${Math.floor(profile.duration / 4)}s', target: ${profile.virtualUsers * 4} }
|
|
339
|
+
]`;
|
|
340
|
+
case 'soak':
|
|
341
|
+
return `[
|
|
342
|
+
{ duration: '${profile.rampUpTime}s', target: ${profile.virtualUsers} },
|
|
343
|
+
{ duration: '${profile.duration}s', target: ${profile.virtualUsers} }
|
|
344
|
+
]`;
|
|
345
|
+
default:
|
|
346
|
+
return `[{ duration: '${profile.duration}s', target: ${profile.virtualUsers} }]`;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
generateJMeterScript(config) {
|
|
350
|
+
// JMeter XML test plan generation
|
|
351
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
352
|
+
<jmeterTestPlan version="1.2">
|
|
353
|
+
<hashTree>
|
|
354
|
+
<TestPlan>
|
|
355
|
+
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments">
|
|
356
|
+
<collectionProp name="Arguments.arguments"/>
|
|
357
|
+
</elementProp>
|
|
358
|
+
</TestPlan>
|
|
359
|
+
<hashTree>
|
|
360
|
+
<ThreadGroup>
|
|
361
|
+
<stringProp name="ThreadGroup.num_threads">${config.loadProfile.virtualUsers}</stringProp>
|
|
362
|
+
<stringProp name="ThreadGroup.ramp_time">${config.loadProfile.rampUpTime}</stringProp>
|
|
363
|
+
<stringProp name="ThreadGroup.duration">${config.loadProfile.duration}</stringProp>
|
|
364
|
+
</ThreadGroup>
|
|
365
|
+
</hashTree>
|
|
366
|
+
</hashTree>
|
|
367
|
+
</jmeterTestPlan>`;
|
|
368
|
+
}
|
|
369
|
+
generateGatlingScript(config) {
|
|
370
|
+
// Gatling Scala simulation
|
|
371
|
+
return `
|
|
372
|
+
import io.gatling.core.Predef._
|
|
373
|
+
import io.gatling.http.Predef._
|
|
374
|
+
|
|
375
|
+
class LoadTestSimulation extends Simulation {
|
|
376
|
+
val httpProtocol = http
|
|
377
|
+
.baseUrl("${config.targetUrl}")
|
|
378
|
+
.acceptHeader("application/json")
|
|
379
|
+
|
|
380
|
+
val scn = scenario("Load Test")
|
|
381
|
+
.exec(http("request")
|
|
382
|
+
.get("/")
|
|
383
|
+
.check(status.is(200))
|
|
384
|
+
.check(responseTimeInMillis.lt(${config.thresholds.maxLatencyP95})))
|
|
385
|
+
|
|
386
|
+
setUp(
|
|
387
|
+
scn.inject(rampUsers(${config.loadProfile.virtualUsers}) during (${config.loadProfile.rampUpTime} seconds))
|
|
388
|
+
).protocols(httpProtocol)
|
|
389
|
+
}
|
|
390
|
+
`.trim();
|
|
391
|
+
}
|
|
392
|
+
generateArtilleryScript(config) {
|
|
393
|
+
// Artillery YAML configuration
|
|
394
|
+
return JSON.stringify({
|
|
395
|
+
config: {
|
|
396
|
+
target: config.targetUrl,
|
|
397
|
+
phases: [
|
|
398
|
+
{
|
|
399
|
+
duration: config.loadProfile.rampUpTime,
|
|
400
|
+
arrivalRate: Math.floor(config.loadProfile.virtualUsers / config.loadProfile.rampUpTime),
|
|
401
|
+
rampTo: config.loadProfile.virtualUsers
|
|
402
|
+
}
|
|
403
|
+
]
|
|
404
|
+
},
|
|
405
|
+
scenarios: [
|
|
406
|
+
{
|
|
407
|
+
flow: [
|
|
408
|
+
{ get: { url: '/' } }
|
|
409
|
+
]
|
|
410
|
+
}
|
|
411
|
+
]
|
|
412
|
+
}, null, 2);
|
|
413
|
+
}
|
|
414
|
+
async executeLoadTest(script, config) {
|
|
415
|
+
// Simulate load test execution
|
|
416
|
+
// In real implementation, execute the actual tool
|
|
417
|
+
console.log(`Executing load test with ${config.loadProfile.virtualUsers} VUs for ${config.loadProfile.duration}s`);
|
|
418
|
+
// Simulate test duration
|
|
419
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
420
|
+
// Return simulated results
|
|
421
|
+
return {
|
|
422
|
+
requests: {
|
|
423
|
+
total: config.loadProfile.virtualUsers * Math.floor(config.loadProfile.duration / 2),
|
|
424
|
+
successful: config.loadProfile.virtualUsers * Math.floor(config.loadProfile.duration / 2) * 0.98,
|
|
425
|
+
failed: config.loadProfile.virtualUsers * Math.floor(config.loadProfile.duration / 2) * 0.02
|
|
426
|
+
},
|
|
427
|
+
latencies: Array.from({ length: 1000 }, () => Math.random() * 1000),
|
|
428
|
+
throughput: config.loadProfile.virtualUsers * 2
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
async collectMonitoringData(testId) {
|
|
432
|
+
// Simulate monitoring data collection
|
|
433
|
+
// In real implementation, query monitoring platform
|
|
434
|
+
return {
|
|
435
|
+
cpu: {
|
|
436
|
+
samples: Array.from({ length: 100 }, () => 60 + Math.random() * 30),
|
|
437
|
+
average: 75,
|
|
438
|
+
peak: 92
|
|
439
|
+
},
|
|
440
|
+
memory: {
|
|
441
|
+
samples: Array.from({ length: 100 }, () => 4 + Math.random() * 2),
|
|
442
|
+
average: 5.2,
|
|
443
|
+
peak: 6.8
|
|
444
|
+
},
|
|
445
|
+
network: {
|
|
446
|
+
samples: Array.from({ length: 100 }, () => 100 + Math.random() * 50),
|
|
447
|
+
average: 125,
|
|
448
|
+
peak: 180
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
analyzeLoadTestResults(rawResults, monitoringData) {
|
|
453
|
+
const latencies = rawResults.latencies.sort((a, b) => a - b);
|
|
454
|
+
return {
|
|
455
|
+
requests: {
|
|
456
|
+
total: rawResults.requests.total,
|
|
457
|
+
successful: rawResults.requests.successful,
|
|
458
|
+
failed: rawResults.requests.failed,
|
|
459
|
+
errorRate: (rawResults.requests.failed / rawResults.requests.total) * 100
|
|
460
|
+
},
|
|
461
|
+
latency: {
|
|
462
|
+
min: latencies[0],
|
|
463
|
+
max: latencies[latencies.length - 1],
|
|
464
|
+
mean: latencies.reduce((a, b) => a + b, 0) / latencies.length,
|
|
465
|
+
p50: latencies[Math.floor(latencies.length * 0.5)],
|
|
466
|
+
p95: latencies[Math.floor(latencies.length * 0.95)],
|
|
467
|
+
p99: latencies[Math.floor(latencies.length * 0.99)]
|
|
468
|
+
},
|
|
469
|
+
throughput: {
|
|
470
|
+
requestsPerSecond: rawResults.throughput,
|
|
471
|
+
bytesPerSecond: rawResults.throughput * 1024
|
|
472
|
+
},
|
|
473
|
+
resources: {
|
|
474
|
+
cpu: {
|
|
475
|
+
current: monitoringData.cpu.samples[monitoringData.cpu.samples.length - 1],
|
|
476
|
+
average: monitoringData.cpu.average,
|
|
477
|
+
peak: monitoringData.cpu.peak,
|
|
478
|
+
unit: '%'
|
|
479
|
+
},
|
|
480
|
+
memory: {
|
|
481
|
+
current: monitoringData.memory.samples[monitoringData.memory.samples.length - 1],
|
|
482
|
+
average: monitoringData.memory.average,
|
|
483
|
+
peak: monitoringData.memory.peak,
|
|
484
|
+
unit: 'GB'
|
|
485
|
+
},
|
|
486
|
+
network: {
|
|
487
|
+
current: monitoringData.network.samples[monitoringData.network.samples.length - 1],
|
|
488
|
+
average: monitoringData.network.average,
|
|
489
|
+
peak: monitoringData.network.peak,
|
|
490
|
+
unit: 'Mbps'
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
// ============================================================================
|
|
496
|
+
// Bottleneck Detection
|
|
497
|
+
// ============================================================================
|
|
498
|
+
async detectBottlenecks(metadata) {
|
|
499
|
+
const { metrics, testId } = metadata;
|
|
500
|
+
console.log(`Detecting bottlenecks for test ${testId}`);
|
|
501
|
+
const bottlenecks = [];
|
|
502
|
+
// Analyze CPU bottlenecks
|
|
503
|
+
if (metrics.resources.cpu.peak > this.config.thresholds.maxCpuUsage) {
|
|
504
|
+
bottlenecks.push({
|
|
505
|
+
type: 'CPU',
|
|
506
|
+
severity: this.calculateSeverity(metrics.resources.cpu.peak, this.config.thresholds.maxCpuUsage),
|
|
507
|
+
location: 'Application Server',
|
|
508
|
+
description: `CPU usage reached ${metrics.resources.cpu.peak}%, exceeding threshold of ${this.config.thresholds.maxCpuUsage}%`,
|
|
509
|
+
metrics: {
|
|
510
|
+
current: metrics.resources.cpu.peak,
|
|
511
|
+
average: metrics.resources.cpu.average,
|
|
512
|
+
threshold: this.config.thresholds.maxCpuUsage
|
|
513
|
+
},
|
|
514
|
+
remediation: [
|
|
515
|
+
'Profile application to identify CPU-intensive operations',
|
|
516
|
+
'Consider horizontal scaling',
|
|
517
|
+
'Optimize algorithms and reduce computational complexity',
|
|
518
|
+
'Implement caching for expensive operations'
|
|
519
|
+
],
|
|
520
|
+
impactEstimate: 'High - May cause request timeouts and degraded user experience'
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
// Analyze memory bottlenecks
|
|
524
|
+
if (metrics.resources.memory.peak > this.config.thresholds.maxMemoryUsage) {
|
|
525
|
+
bottlenecks.push({
|
|
526
|
+
type: 'MEMORY',
|
|
527
|
+
severity: this.calculateSeverity(metrics.resources.memory.peak, this.config.thresholds.maxMemoryUsage),
|
|
528
|
+
location: 'Application Server',
|
|
529
|
+
description: `Memory usage reached ${metrics.resources.memory.peak}GB, exceeding threshold`,
|
|
530
|
+
metrics: {
|
|
531
|
+
current: metrics.resources.memory.peak,
|
|
532
|
+
average: metrics.resources.memory.average,
|
|
533
|
+
threshold: this.config.thresholds.maxMemoryUsage
|
|
534
|
+
},
|
|
535
|
+
remediation: [
|
|
536
|
+
'Check for memory leaks',
|
|
537
|
+
'Implement connection pooling',
|
|
538
|
+
'Optimize data structures',
|
|
539
|
+
'Increase available memory'
|
|
540
|
+
],
|
|
541
|
+
impactEstimate: 'Critical - May cause OOM errors and application crashes'
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
// Analyze latency bottlenecks
|
|
545
|
+
if (metrics.latency.p95 > this.config.thresholds.maxLatencyP95) {
|
|
546
|
+
const latencyType = this.identifyLatencyBottleneck(metrics);
|
|
547
|
+
bottlenecks.push({
|
|
548
|
+
type: latencyType,
|
|
549
|
+
severity: 'HIGH',
|
|
550
|
+
location: 'Request Pipeline',
|
|
551
|
+
description: `P95 latency is ${metrics.latency.p95}ms, exceeding ${this.config.thresholds.maxLatencyP95}ms threshold`,
|
|
552
|
+
metrics: {
|
|
553
|
+
p95: metrics.latency.p95,
|
|
554
|
+
p99: metrics.latency.p99,
|
|
555
|
+
mean: metrics.latency.mean,
|
|
556
|
+
threshold: this.config.thresholds.maxLatencyP95
|
|
557
|
+
},
|
|
558
|
+
remediation: [
|
|
559
|
+
'Optimize database queries',
|
|
560
|
+
'Implement caching layer',
|
|
561
|
+
'Add CDN for static assets',
|
|
562
|
+
'Review external API calls'
|
|
563
|
+
],
|
|
564
|
+
impactEstimate: 'High - Affects user experience and conversion rates'
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
// Store bottleneck analysis
|
|
568
|
+
await this.memoryStore.store(`aqe/performance/bottlenecks/${testId}`, {
|
|
569
|
+
bottlenecks,
|
|
570
|
+
analyzedAt: new Date(),
|
|
571
|
+
testId
|
|
572
|
+
});
|
|
573
|
+
// Emit bottleneck detected events
|
|
574
|
+
for (const bottleneck of bottlenecks) {
|
|
575
|
+
if (bottleneck.severity === 'CRITICAL' || bottleneck.severity === 'HIGH') {
|
|
576
|
+
this.emitEvent('performance.bottleneck.detected', {
|
|
577
|
+
type: bottleneck.type,
|
|
578
|
+
severity: bottleneck.severity,
|
|
579
|
+
metrics: bottleneck.metrics
|
|
580
|
+
}, bottleneck.severity === 'CRITICAL' ? 'critical' : 'high');
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
return bottlenecks;
|
|
584
|
+
}
|
|
585
|
+
async analyzeBottlenecks(metrics) {
|
|
586
|
+
return await this.detectBottlenecks({ metrics, testId: 'current' });
|
|
587
|
+
}
|
|
588
|
+
identifyLatencyBottleneck(metrics) {
|
|
589
|
+
// Heuristic to identify latency source
|
|
590
|
+
if (metrics.resources.cpu.peak > 80)
|
|
591
|
+
return 'CPU';
|
|
592
|
+
if (metrics.resources.memory.peak > 80)
|
|
593
|
+
return 'MEMORY';
|
|
594
|
+
if (metrics.latency.p99 > metrics.latency.p95 * 2)
|
|
595
|
+
return 'DATABASE';
|
|
596
|
+
return 'NETWORK';
|
|
597
|
+
}
|
|
598
|
+
calculateSeverity(current, threshold) {
|
|
599
|
+
const ratio = current / threshold;
|
|
600
|
+
if (ratio > 1.5)
|
|
601
|
+
return 'CRITICAL';
|
|
602
|
+
if (ratio > 1.25)
|
|
603
|
+
return 'HIGH';
|
|
604
|
+
if (ratio > 1.1)
|
|
605
|
+
return 'MEDIUM';
|
|
606
|
+
return 'LOW';
|
|
607
|
+
}
|
|
608
|
+
// ============================================================================
|
|
609
|
+
// SLA Validation
|
|
610
|
+
// ============================================================================
|
|
611
|
+
async validateSLA(metadata) {
|
|
612
|
+
const { metrics, thresholds } = metadata;
|
|
613
|
+
console.log('Validating SLA thresholds');
|
|
614
|
+
const violations = [];
|
|
615
|
+
// Check P95 latency
|
|
616
|
+
if (metrics.latency.p95 > thresholds.maxLatencyP95) {
|
|
617
|
+
violations.push({
|
|
618
|
+
metric: 'latency_p95',
|
|
619
|
+
threshold: thresholds.maxLatencyP95,
|
|
620
|
+
actual: metrics.latency.p95,
|
|
621
|
+
violation: ((metrics.latency.p95 - thresholds.maxLatencyP95) / thresholds.maxLatencyP95) * 100,
|
|
622
|
+
severity: this.calculateViolationSeverity(metrics.latency.p95, thresholds.maxLatencyP95),
|
|
623
|
+
duration: 0 // Would be calculated from monitoring data
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
// Check P99 latency
|
|
627
|
+
if (metrics.latency.p99 > thresholds.maxLatencyP99) {
|
|
628
|
+
violations.push({
|
|
629
|
+
metric: 'latency_p99',
|
|
630
|
+
threshold: thresholds.maxLatencyP99,
|
|
631
|
+
actual: metrics.latency.p99,
|
|
632
|
+
violation: ((metrics.latency.p99 - thresholds.maxLatencyP99) / thresholds.maxLatencyP99) * 100,
|
|
633
|
+
severity: this.calculateViolationSeverity(metrics.latency.p99, thresholds.maxLatencyP99),
|
|
634
|
+
duration: 0
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
// Check throughput
|
|
638
|
+
if (metrics.throughput.requestsPerSecond < thresholds.minThroughput) {
|
|
639
|
+
violations.push({
|
|
640
|
+
metric: 'throughput',
|
|
641
|
+
threshold: thresholds.minThroughput,
|
|
642
|
+
actual: metrics.throughput.requestsPerSecond,
|
|
643
|
+
violation: ((thresholds.minThroughput - metrics.throughput.requestsPerSecond) / thresholds.minThroughput) * 100,
|
|
644
|
+
severity: 'HIGH',
|
|
645
|
+
duration: 0
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
// Check error rate
|
|
649
|
+
if (metrics.requests.errorRate > thresholds.maxErrorRate * 100) {
|
|
650
|
+
violations.push({
|
|
651
|
+
metric: 'error_rate',
|
|
652
|
+
threshold: thresholds.maxErrorRate * 100,
|
|
653
|
+
actual: metrics.requests.errorRate,
|
|
654
|
+
violation: ((metrics.requests.errorRate - thresholds.maxErrorRate * 100) / (thresholds.maxErrorRate * 100)) * 100,
|
|
655
|
+
severity: 'CRITICAL',
|
|
656
|
+
duration: 0
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
// Emit SLA violation events
|
|
660
|
+
if (violations.length > 0) {
|
|
661
|
+
this.emitEvent('performance.sla.violated', {
|
|
662
|
+
violationCount: violations.length,
|
|
663
|
+
violations
|
|
664
|
+
}, 'critical');
|
|
665
|
+
}
|
|
666
|
+
return {
|
|
667
|
+
passed: violations.length === 0,
|
|
668
|
+
violations
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
async checkSLAViolationsAsync(metrics, thresholds) {
|
|
672
|
+
const result = await this.validateSLA({ metrics, thresholds });
|
|
673
|
+
return result.violations;
|
|
674
|
+
}
|
|
675
|
+
checkSLAViolations(metrics, thresholds) {
|
|
676
|
+
// Synchronous version for internal use
|
|
677
|
+
const violations = [];
|
|
678
|
+
// Check P95 latency
|
|
679
|
+
if (metrics.latency.p95 > thresholds.maxLatencyP95) {
|
|
680
|
+
violations.push({
|
|
681
|
+
metric: 'latency_p95',
|
|
682
|
+
threshold: thresholds.maxLatencyP95,
|
|
683
|
+
actual: metrics.latency.p95,
|
|
684
|
+
violation: ((metrics.latency.p95 - thresholds.maxLatencyP95) / thresholds.maxLatencyP95) * 100,
|
|
685
|
+
severity: this.calculateViolationSeverity(metrics.latency.p95, thresholds.maxLatencyP95),
|
|
686
|
+
duration: 0
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
// Check P99 latency
|
|
690
|
+
if (metrics.latency.p99 > thresholds.maxLatencyP99) {
|
|
691
|
+
violations.push({
|
|
692
|
+
metric: 'latency_p99',
|
|
693
|
+
threshold: thresholds.maxLatencyP99,
|
|
694
|
+
actual: metrics.latency.p99,
|
|
695
|
+
violation: ((metrics.latency.p99 - thresholds.maxLatencyP99) / thresholds.maxLatencyP99) * 100,
|
|
696
|
+
severity: this.calculateViolationSeverity(metrics.latency.p99, thresholds.maxLatencyP99),
|
|
697
|
+
duration: 0
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
// Check throughput
|
|
701
|
+
if (metrics.throughput.requestsPerSecond < thresholds.minThroughput) {
|
|
702
|
+
violations.push({
|
|
703
|
+
metric: 'throughput',
|
|
704
|
+
threshold: thresholds.minThroughput,
|
|
705
|
+
actual: metrics.throughput.requestsPerSecond,
|
|
706
|
+
violation: ((thresholds.minThroughput - metrics.throughput.requestsPerSecond) / thresholds.minThroughput) * 100,
|
|
707
|
+
severity: 'HIGH',
|
|
708
|
+
duration: 0
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
// Check error rate
|
|
712
|
+
if (metrics.requests.errorRate > thresholds.maxErrorRate * 100) {
|
|
713
|
+
violations.push({
|
|
714
|
+
metric: 'error_rate',
|
|
715
|
+
threshold: thresholds.maxErrorRate * 100,
|
|
716
|
+
actual: metrics.requests.errorRate,
|
|
717
|
+
violation: ((metrics.requests.errorRate - thresholds.maxErrorRate * 100) / (thresholds.maxErrorRate * 100)) * 100,
|
|
718
|
+
severity: 'CRITICAL',
|
|
719
|
+
duration: 0
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
return violations;
|
|
723
|
+
}
|
|
724
|
+
calculateViolationSeverity(actual, threshold) {
|
|
725
|
+
return this.calculateSeverity(actual, threshold);
|
|
726
|
+
}
|
|
727
|
+
// ============================================================================
|
|
728
|
+
// Performance Regression Detection
|
|
729
|
+
// ============================================================================
|
|
730
|
+
async detectRegressions(metadata) {
|
|
731
|
+
const { currentMetrics, baselineId } = metadata;
|
|
732
|
+
console.log(`Detecting performance regressions against baseline ${baselineId}`);
|
|
733
|
+
// Retrieve baseline
|
|
734
|
+
const baseline = this.baselines.get(baselineId);
|
|
735
|
+
if (!baseline) {
|
|
736
|
+
throw new Error(`Baseline ${baselineId} not found`);
|
|
737
|
+
}
|
|
738
|
+
const regressions = [];
|
|
739
|
+
const improvements = [];
|
|
740
|
+
// Compare latency
|
|
741
|
+
const latencyDelta = ((currentMetrics.latency.p95 - baseline.metrics.latency.p95) / baseline.metrics.latency.p95);
|
|
742
|
+
if (latencyDelta > 0.1) { // 10% degradation threshold
|
|
743
|
+
regressions.push({
|
|
744
|
+
metric: 'latency_p95',
|
|
745
|
+
baseline: baseline.metrics.latency.p95,
|
|
746
|
+
current: currentMetrics.latency.p95,
|
|
747
|
+
degradation: latencyDelta * 100,
|
|
748
|
+
severity: this.calculateRegressionSeverity(latencyDelta)
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
else if (latencyDelta < -0.1) { // 10% improvement
|
|
752
|
+
improvements.push({
|
|
753
|
+
metric: 'latency_p95',
|
|
754
|
+
baseline: baseline.metrics.latency.p95,
|
|
755
|
+
current: currentMetrics.latency.p95,
|
|
756
|
+
improvement: Math.abs(latencyDelta) * 100
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
// Compare throughput
|
|
760
|
+
const throughputDelta = ((currentMetrics.throughput.requestsPerSecond - baseline.metrics.throughput.requestsPerSecond) / baseline.metrics.throughput.requestsPerSecond);
|
|
761
|
+
if (throughputDelta < -0.1) { // 10% degradation
|
|
762
|
+
regressions.push({
|
|
763
|
+
metric: 'throughput',
|
|
764
|
+
baseline: baseline.metrics.throughput.requestsPerSecond,
|
|
765
|
+
current: currentMetrics.throughput.requestsPerSecond,
|
|
766
|
+
degradation: Math.abs(throughputDelta) * 100,
|
|
767
|
+
severity: this.calculateRegressionSeverity(Math.abs(throughputDelta))
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
else if (throughputDelta > 0.1) { // 10% improvement
|
|
771
|
+
improvements.push({
|
|
772
|
+
metric: 'throughput',
|
|
773
|
+
baseline: baseline.metrics.throughput.requestsPerSecond,
|
|
774
|
+
current: currentMetrics.throughput.requestsPerSecond,
|
|
775
|
+
improvement: throughputDelta * 100
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
// Compare error rate
|
|
779
|
+
const errorRateDelta = ((currentMetrics.requests.errorRate - baseline.metrics.requests.errorRate) / baseline.metrics.requests.errorRate);
|
|
780
|
+
if (errorRateDelta > 0.2) { // 20% increase in errors
|
|
781
|
+
regressions.push({
|
|
782
|
+
metric: 'error_rate',
|
|
783
|
+
baseline: baseline.metrics.requests.errorRate,
|
|
784
|
+
current: currentMetrics.requests.errorRate,
|
|
785
|
+
degradation: errorRateDelta * 100,
|
|
786
|
+
severity: 'CRITICAL'
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
const verdict = regressions.length === 0 ? 'PASS' :
|
|
790
|
+
regressions.some(r => r.severity === 'CRITICAL') ? 'FAIL' : 'WARNING';
|
|
791
|
+
// Store regression analysis
|
|
792
|
+
await this.memoryStore.store('aqe/performance/regressions/latest', {
|
|
793
|
+
current: currentMetrics,
|
|
794
|
+
baseline: baseline.metrics,
|
|
795
|
+
regressions,
|
|
796
|
+
improvements,
|
|
797
|
+
verdict,
|
|
798
|
+
analyzedAt: new Date()
|
|
799
|
+
});
|
|
800
|
+
// Emit regression detected events
|
|
801
|
+
if (regressions.length > 0) {
|
|
802
|
+
this.emitEvent('performance.regression.detected', {
|
|
803
|
+
count: regressions.length,
|
|
804
|
+
severity: verdict,
|
|
805
|
+
regressions
|
|
806
|
+
}, verdict === 'FAIL' ? 'critical' : 'high');
|
|
807
|
+
}
|
|
808
|
+
return {
|
|
809
|
+
current: currentMetrics,
|
|
810
|
+
baseline: baseline.metrics,
|
|
811
|
+
regressions,
|
|
812
|
+
improvements,
|
|
813
|
+
verdict
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
calculateRegressionSeverity(degradation) {
|
|
817
|
+
if (degradation > 0.5)
|
|
818
|
+
return 'CRITICAL'; // 50% degradation
|
|
819
|
+
if (degradation > 0.3)
|
|
820
|
+
return 'HIGH'; // 30% degradation
|
|
821
|
+
if (degradation > 0.15)
|
|
822
|
+
return 'MEDIUM'; // 15% degradation
|
|
823
|
+
return 'LOW';
|
|
824
|
+
}
|
|
825
|
+
// ============================================================================
|
|
826
|
+
// Baseline Management
|
|
827
|
+
// ============================================================================
|
|
828
|
+
async establishBaseline(metadata) {
|
|
829
|
+
const { metrics, version, environment } = metadata;
|
|
830
|
+
const baseline = {
|
|
831
|
+
timestamp: new Date(),
|
|
832
|
+
metrics,
|
|
833
|
+
loadProfile: this.config.loadProfile,
|
|
834
|
+
version,
|
|
835
|
+
environment
|
|
836
|
+
};
|
|
837
|
+
const baselineId = `${version}-${environment}`;
|
|
838
|
+
this.baselines.set(baselineId, baseline);
|
|
839
|
+
// Store baseline
|
|
840
|
+
await this.memoryStore.store(`aqe/performance/baselines/${baselineId}`, baseline);
|
|
841
|
+
console.log(`Established performance baseline ${baselineId}`);
|
|
842
|
+
return baseline;
|
|
843
|
+
}
|
|
844
|
+
async loadBaselines() {
|
|
845
|
+
try {
|
|
846
|
+
// Load baselines from memory
|
|
847
|
+
const storedBaselines = await this.memoryStore.retrieve('aqe/performance/baselines');
|
|
848
|
+
if (storedBaselines) {
|
|
849
|
+
for (const [id, baseline] of Object.entries(storedBaselines)) {
|
|
850
|
+
this.baselines.set(id, baseline);
|
|
851
|
+
}
|
|
852
|
+
console.log(`Loaded ${this.baselines.size} performance baselines`);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
catch (error) {
|
|
856
|
+
console.warn('Could not load baselines:', error);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
// ============================================================================
|
|
860
|
+
// Load Pattern Generation
|
|
861
|
+
// ============================================================================
|
|
862
|
+
async generateLoadPattern(metadata) {
|
|
863
|
+
const { pattern, virtualUsers, duration } = metadata;
|
|
864
|
+
const loadProfile = {
|
|
865
|
+
virtualUsers: virtualUsers || this.config.loadProfile.virtualUsers,
|
|
866
|
+
duration: duration || this.config.loadProfile.duration,
|
|
867
|
+
rampUpTime: Math.floor((duration || this.config.loadProfile.duration) * 0.1),
|
|
868
|
+
pattern: pattern || this.config.loadProfile.pattern
|
|
869
|
+
};
|
|
870
|
+
console.log(`Generated ${pattern} load pattern with ${virtualUsers} VUs`);
|
|
871
|
+
return loadProfile;
|
|
872
|
+
}
|
|
873
|
+
// ============================================================================
|
|
874
|
+
// Helper Methods
|
|
875
|
+
// ============================================================================
|
|
876
|
+
async initializeLoadTestingClient() {
|
|
877
|
+
const tool = this.config.tools.loadTesting;
|
|
878
|
+
console.log(`Initializing ${tool} load testing client`);
|
|
879
|
+
// In real implementation, initialize actual client
|
|
880
|
+
this.loadTestingClient = { tool, initialized: true };
|
|
881
|
+
}
|
|
882
|
+
async initializeMonitoringClient() {
|
|
883
|
+
const monitoring = this.config.tools.monitoring;
|
|
884
|
+
console.log(`Initializing monitoring clients: ${monitoring.join(', ')}`);
|
|
885
|
+
// In real implementation, initialize actual monitoring clients
|
|
886
|
+
this.monitoringClient = { platforms: monitoring, initialized: true };
|
|
887
|
+
}
|
|
888
|
+
registerPerformanceEventHandlers() {
|
|
889
|
+
// Listen for test execution requests from other agents
|
|
890
|
+
this.registerEventHandler({
|
|
891
|
+
eventType: 'test.execution.complete',
|
|
892
|
+
handler: async (event) => {
|
|
893
|
+
// Automatically run performance tests after functional tests
|
|
894
|
+
console.log('Functional tests completed, considering performance test run');
|
|
895
|
+
}
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
parseTestConfig(metadata) {
|
|
899
|
+
return {
|
|
900
|
+
targetUrl: metadata.targetUrl || 'http://localhost:3000',
|
|
901
|
+
loadProfile: metadata.loadProfile || this.config.loadProfile,
|
|
902
|
+
thresholds: metadata.thresholds || this.config.thresholds,
|
|
903
|
+
monitoring: metadata.monitoring
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
async storeTestResults(testId, result) {
|
|
907
|
+
// Store in active tests
|
|
908
|
+
this.activeTests.set(testId, result);
|
|
909
|
+
// Store in memory for other agents
|
|
910
|
+
await this.memoryStore.store(`aqe/performance/results/${testId}`, result);
|
|
911
|
+
// Store in shared memory
|
|
912
|
+
await this.storeSharedMemory('latest-test', {
|
|
913
|
+
testId,
|
|
914
|
+
timestamp: new Date(),
|
|
915
|
+
passed: result.slaViolations.length === 0,
|
|
916
|
+
metrics: result.metrics
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
generateRecommendations(metrics, bottlenecks, violations) {
|
|
920
|
+
const recommendations = [];
|
|
921
|
+
// Recommendations based on bottlenecks
|
|
922
|
+
for (const bottleneck of bottlenecks) {
|
|
923
|
+
recommendations.push(...bottleneck.remediation);
|
|
924
|
+
}
|
|
925
|
+
// Recommendations based on SLA violations
|
|
926
|
+
if (violations.length > 0) {
|
|
927
|
+
recommendations.push('Review and optimize critical user paths');
|
|
928
|
+
recommendations.push('Consider infrastructure scaling');
|
|
929
|
+
}
|
|
930
|
+
// General recommendations based on metrics
|
|
931
|
+
if (metrics.requests.errorRate > 1) {
|
|
932
|
+
recommendations.push('Investigate and fix error sources to reduce error rate');
|
|
933
|
+
}
|
|
934
|
+
if (metrics.latency.p99 > metrics.latency.p95 * 2) {
|
|
935
|
+
recommendations.push('Large P99 tail latency detected - investigate outliers');
|
|
936
|
+
}
|
|
937
|
+
// Deduplicate recommendations
|
|
938
|
+
return Array.from(new Set(recommendations));
|
|
939
|
+
}
|
|
940
|
+
async analyzePerformance(metadata) {
|
|
941
|
+
const { testId } = metadata;
|
|
942
|
+
// Retrieve test results
|
|
943
|
+
const result = this.activeTests.get(testId) || await this.memoryStore.retrieve(`aqe/performance/results/${testId}`);
|
|
944
|
+
if (!result) {
|
|
945
|
+
throw new Error(`Test results not found for ${testId}`);
|
|
946
|
+
}
|
|
947
|
+
return {
|
|
948
|
+
summary: {
|
|
949
|
+
passed: result.slaViolations.length === 0,
|
|
950
|
+
duration: result.duration,
|
|
951
|
+
totalRequests: result.metrics.requests.total,
|
|
952
|
+
errorRate: result.metrics.requests.errorRate,
|
|
953
|
+
p95Latency: result.metrics.latency.p95
|
|
954
|
+
},
|
|
955
|
+
bottlenecks: result.bottlenecks,
|
|
956
|
+
violations: result.slaViolations,
|
|
957
|
+
recommendations: result.recommendations
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
getDefaultThresholds() {
|
|
961
|
+
return {
|
|
962
|
+
maxLatencyP95: 500,
|
|
963
|
+
maxLatencyP99: 1000,
|
|
964
|
+
minThroughput: 1000,
|
|
965
|
+
maxErrorRate: 0.01,
|
|
966
|
+
maxCpuUsage: 80,
|
|
967
|
+
maxMemoryUsage: 85
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
exports.PerformanceTesterAgent = PerformanceTesterAgent;
|
|
972
|
+
//# sourceMappingURL=PerformanceTesterAgent.js.map
|