Add load testing job to GitHub Actions CI pipeline (FRE-4931)

- Add load-test job to ci.yml that runs after docker-build on push to main
- Create combined load test runner (scripts/load-test/run-all.sh) for all services
- Create k6 load test scripts for api, darkwatch, spamshield, and voiceprint
- Add shared k6 utilities (lib/common.js)
- Update load-test.yml to support all services and report artifacts
- Configure k6 cloud output and P99 threshold validation
- Generate load test report as CI artifact

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-05-09 09:16:36 -04:00
parent 98b01bf48f
commit a804cab431
8 changed files with 439 additions and 13 deletions

View File

@@ -0,0 +1,48 @@
import http from 'k6/http';
import { check, group } from 'k6';
import { Rate, Trend } from 'k6/metrics';
import { getBaseUrl, getTargetRps, getDuration, defaultThresholds, checkResponse, randomString } from '../lib/common.js';
const errorRate = new Rate('errors');
const classificationLatency = new Trend('classification_p99');
const engineLatency = new Trend('engine_p99');
export const options = {
thresholds: {
...defaultThresholds(200).thresholds,
classification_p99: ['p(99)<300'],
engine_p99: ['p(99)<250'],
},
};
const BASE_URL = getBaseUrl();
const AUTH_TOKEN = __ENV.API_TOKEN || 'test-token';
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${AUTH_TOKEN}`,
};
export default function () {
group('SMS Classification', function () {
const payload = JSON.stringify({
message: `Load test message ${randomString(8)} - please check if this is spam`,
from: `+1555${String(Math.floor(1000000 + Math.random() * 9000000))}`,
to: `+1555${String(Math.floor(1000000 + Math.random() * 9000000))}`,
});
const res = http.post(`${BASE_URL}/spamshield/classify`, payload, { headers });
checkResponse(res, 200);
classificationLatency.add(res.timings.duration);
});
group('Spam Engine Health', function () {
const res = http.get(`${BASE_URL}/spamshield/health`, { headers });
checkResponse(res, 200);
engineLatency.add(res.timings.duration);
});
group('Blocklist Check', function () {
const res = http.get(`${BASE_URL}/spamshield/blocklist/check?phone=+1555${String(Math.floor(1000000 + Math.random() * 9000000))}`, { headers });
checkResponse(res, 200);
});
}