/** * Load test: health, readyz, status * Usage: k6 run loadtests/backend/health.js */ import http from 'k6/http'; import { check, sleep } from 'k6'; import { Rate, Trend } from 'k6/metrics'; const errorRate = new Rate('errors'); const healthCheckDuration = new Trend('health_check_duration'); const readyzCheckDuration = new Trend('readyz_check_duration'); const BASE_URL = __ENV.BASE_URL || __ENV.API_ORIGIN || 'http://localhost:8080'; export const options = { stages: [ { duration: '30s', target: 10 }, { duration: '1m', target: 10 }, { duration: '30s', target: 0 }, ], thresholds: { http_req_duration: ['p(95)<500', 'p(99)<1000'], errors: ['rate<0.05'], health_check_duration: ['p(95)<100'], readyz_check_duration: ['p(95)<200'], }, }; export default function () { const healthRes = http.get(`${BASE_URL}/health`); const healthCheck = check(healthRes, { 'health status is 200': (r) => r.status === 200, 'health response has status': (r) => { try { const body = JSON.parse(r.body); return body.success === true && body.data && body.data.status; } catch (e) { return false; } }, }); errorRate.add(!healthCheck); healthCheckDuration.add(healthRes.timings.duration); sleep(0.5); const readyzRes = http.get(`${BASE_URL}/readyz`); const readyzCheck = check(readyzRes, { 'readyz status is 200': (r) => r.status === 200, 'readyz response has status': (r) => { try { const body = JSON.parse(r.body); return body.success === true && body.data && body.data.status; } catch (e) { return false; } }, }); errorRate.add(!readyzCheck); readyzCheckDuration.add(readyzRes.timings.duration); sleep(0.5); const statusRes = http.get(`${BASE_URL}/api/v1/status`); check(statusRes, { 'status returns 200 or 503': (r) => r.status === 200 || r.status === 503 }); sleep(1); }