import http from 'k6/http'; import { check, group } from 'k6'; import { Trend, Counter } from 'k6/metrics'; import { randomIntBetween } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; // Custom metrics for benchmark tracking const apiBenchmarks = { health: new Trend('benchmark_health_ms'), auth: new Trend('benchmark_auth_ms'), scenariosList: new Trend('benchmark_scenarios_list_ms'), scenariosCreate: new Trend('benchmark_scenarios_create_ms'), metrics: new Trend('benchmark_metrics_ms'), ingest: new Trend('benchmark_ingest_ms'), reports: new Trend('benchmark_reports_ms'), }; const throughputCounter = new Counter('requests_total'); const memoryUsage = new Trend('memory_usage_mb'); // Benchmark configuration - run consistent load for baseline measurements export const options = { scenarios: { // Baseline benchmark - consistent 100 users for 10 minutes baseline: { executor: 'constant-vus', vus: 100, duration: '10m', tags: { test_type: 'benchmark_baseline' }, }, }, thresholds: { // Baseline performance targets 'benchmark_health_ms': ['p(50)<50', 'p(95)<100'], 'benchmark_auth_ms': ['p(50)<200', 'p(95)<400'], 'benchmark_scenarios_list_ms': ['p(50)<150', 'p(95)<300'], 'benchmark_ingest_ms': ['p(50)<50', 'p(95)<100'], }, summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(50)', 'p(95)', 'p(99)'], }; const BASE_URL = __ENV.BASE_URL || 'http://localhost:8000'; const API_V1 = `${BASE_URL}/api/v1`; export function setup() { console.log('Starting benchmark test...'); console.log('Collecting baseline performance metrics...'); // Warm up the system console.log('Warming up system (30 seconds)...'); for (let i = 0; i < 10; i++) { http.get(`${BASE_URL}/health`); } return { startTime: Date.now(), testId: `benchmark_${Date.now()}`, }; } export default function(data) { const params = { headers: { 'Content-Type': 'application/json', }, }; group('Benchmark - Health Endpoint', () => { const start = Date.now(); const res = http.get(`${BASE_URL}/health`); const duration = Date.now() - start; apiBenchmarks.health.add(duration); throughputCounter.add(1); check(res, { 'health responds successfully': (r) => r.status === 200, 'health response time acceptable': (r) => r.timings.duration < 200, }); }); group('Benchmark - Authentication', () => { const start = Date.now(); const res = http.post(`${API_V1}/auth/login`, JSON.stringify({ username: 'benchmark@test.com', password: 'benchmark123', }), params); const duration = Date.now() - start; apiBenchmarks.auth.add(duration); throughputCounter.add(1); // 401 is expected for invalid credentials, but we measure response time check(res, { 'auth endpoint responds': (r) => r.status !== 0, }); }); group('Benchmark - Scenarios List', () => { const start = Date.now(); const res = http.get(`${API_V1}/scenarios?page=1&page_size=20`, params); const duration = Date.now() - start; apiBenchmarks.scenariosList.add(duration); throughputCounter.add(1); check(res, { 'scenarios list responds': (r) => r.status === 200 || r.status === 401, 'scenarios list response time acceptable': (r) => r.timings.duration < 500, }); }); group('Benchmark - Scenarios Create', () => { const start = Date.now(); const res = http.post(`${API_V1}/scenarios`, JSON.stringify({ name: `Benchmark_${randomIntBetween(1, 100000)}`, description: 'Benchmark test scenario', region: 'us-east-1', }), params); const duration = Date.now() - start; apiBenchmarks.scenariosCreate.add(duration); throughputCounter.add(1); check(res, { 'scenarios create responds': (r) => r.status !== 0, }); }); group('Benchmark - Metrics', () => { const start = Date.now(); const res = http.get(`${API_V1}/metrics/dashboard`, params); const duration = Date.now() - start; apiBenchmarks.metrics.add(duration); throughputCounter.add(1); check(res, { 'metrics responds': (r) => r.status === 200 || r.status === 401, }); }); group('Benchmark - Ingest', () => { const start = Date.now(); const res = http.post(`${BASE_URL}/ingest`, JSON.stringify({ message: `Benchmark log entry ${randomIntBetween(1, 1000000)}`, source: 'benchmark', level: 'INFO', }), { ...params, headers: { ...params.headers, 'X-Scenario-ID': `benchmark_scenario_${randomIntBetween(1, 5)}`, }, }); const duration = Date.now() - start; apiBenchmarks.ingest.add(duration); throughputCounter.add(1); check(res, { 'ingest responds successfully': (r) => r.status === 200 || r.status === 202, 'ingest response time acceptable': (r) => r.timings.duration < 200, }); }); group('Benchmark - Reports', () => { const start = Date.now(); const res = http.get(`${API_V1}/reports?page=1&page_size=10`, params); const duration = Date.now() - start; apiBenchmarks.reports.add(duration); throughputCounter.add(1); check(res, { 'reports responds': (r) => r.status === 200 || r.status === 401, }); }); // Simulate memory usage tracking (if available) if (__ENV.K6_CLOUD_TOKEN) { memoryUsage.add(randomIntBetween(100, 500)); // Simulated memory usage } } export function handleSummary(data) { const benchmarkResults = { test_id: `benchmark_${Date.now()}`, timestamp: new Date().toISOString(), duration: data.state.testRunDuration, vus: data.metrics.vus ? data.metrics.vus.values.value : 100, // Response time benchmarks benchmarks: { health: { p50: data.metrics.benchmark_health_ms ? data.metrics.benchmark_health_ms.values['p(50)'] : null, p95: data.metrics.benchmark_health_ms ? data.metrics.benchmark_health_ms.values['p(95)'] : null, avg: data.metrics.benchmark_health_ms ? data.metrics.benchmark_health_ms.values.avg : null, }, auth: { p50: data.metrics.benchmark_auth_ms ? data.metrics.benchmark_auth_ms.values['p(50)'] : null, p95: data.metrics.benchmark_auth_ms ? data.metrics.benchmark_auth_ms.values['p(95)'] : null, avg: data.metrics.benchmark_auth_ms ? data.metrics.benchmark_auth_ms.values.avg : null, }, scenarios_list: { p50: data.metrics.benchmark_scenarios_list_ms ? data.metrics.benchmark_scenarios_list_ms.values['p(50)'] : null, p95: data.metrics.benchmark_scenarios_list_ms ? data.metrics.benchmark_scenarios_list_ms.values['p(95)'] : null, avg: data.metrics.benchmark_scenarios_list_ms ? data.metrics.benchmark_scenarios_list_ms.values.avg : null, }, ingest: { p50: data.metrics.benchmark_ingest_ms ? data.metrics.benchmark_ingest_ms.values['p(50)'] : null, p95: data.metrics.benchmark_ingest_ms ? data.metrics.benchmark_ingest_ms.values['p(95)'] : null, avg: data.metrics.benchmark_ingest_ms ? data.metrics.benchmark_ingest_ms.values.avg : null, }, }, // Throughput throughput: { total_requests: data.metrics.requests_total ? data.metrics.requests_total.values.count : 0, requests_per_second: data.metrics.requests_total ? (data.metrics.requests_total.values.count / (data.state.testRunDuration / 1000)).toFixed(2) : 0, }, // Error rates errors: { error_rate: data.metrics.http_req_failed ? data.metrics.http_req_failed.values.rate : 0, total_errors: data.metrics.http_req_failed ? data.metrics.http_req_failed.values.passes : 0, }, // Pass/fail status passed: data.root_group.checks && data.root_group.checks.every(check => check.passes > 0), }; return { 'reports/benchmark-results.json': JSON.stringify(benchmarkResults, null, 2), stdout: ` ======================================== MOCKUPAWS v1.0.0 BENCHMARK RESULTS ======================================== Test Duration: ${(data.state.testRunDuration / 1000 / 60).toFixed(2)} minutes Virtual Users: ${benchmarkResults.vus} RESPONSE TIME BASELINES: ------------------------ Health Check: - p50: ${benchmarkResults.benchmarks.health.p50 ? benchmarkResults.benchmarks.health.p50.toFixed(2) : 'N/A'}ms - p95: ${benchmarkResults.benchmarks.health.p95 ? benchmarkResults.benchmarks.health.p95.toFixed(2) : 'N/A'}ms - avg: ${benchmarkResults.benchmarks.health.avg ? benchmarkResults.benchmarks.health.avg.toFixed(2) : 'N/A'}ms Authentication: - p50: ${benchmarkResults.benchmarks.auth.p50 ? benchmarkResults.benchmarks.auth.p50.toFixed(2) : 'N/A'}ms - p95: ${benchmarkResults.benchmarks.auth.p95 ? benchmarkResults.benchmarks.auth.p95.toFixed(2) : 'N/A'}ms Scenarios List: - p50: ${benchmarkResults.benchmarks.scenarios_list.p50 ? benchmarkResults.benchmarks.scenarios_list.p50.toFixed(2) : 'N/A'}ms - p95: ${benchmarkResults.benchmarks.scenarios_list.p95 ? benchmarkResults.benchmarks.scenarios_list.p95.toFixed(2) : 'N/A'}ms Log Ingest: - p50: ${benchmarkResults.benchmarks.ingest.p50 ? benchmarkResults.benchmarks.ingest.p50.toFixed(2) : 'N/A'}ms - p95: ${benchmarkResults.benchmarks.ingest.p95 ? benchmarkResults.benchmarks.ingest.p95.toFixed(2) : 'N/A'}ms THROUGHPUT: ----------- Total Requests: ${benchmarkResults.throughput.total_requests} Requests/Second: ${benchmarkResults.throughput.requests_per_second} ERROR RATE: ----------- Total Errors: ${benchmarkResults.errors.total_errors} Error Rate: ${(benchmarkResults.errors.error_rate * 100).toFixed(2)}% TARGET COMPLIANCE: ------------------ p95 < 200ms: ${benchmarkResults.benchmarks.health.p95 && benchmarkResults.benchmarks.health.p95 < 200 ? '✓ PASS' : '✗ FAIL'} Error Rate < 1%: ${benchmarkResults.errors.error_rate < 0.01 ? '✓ PASS' : '✗ FAIL'} Overall Status: ${benchmarkResults.passed ? '✓ PASSED' : '✗ FAILED'} ======================================== `, }; }