Files
git.stella-ops.org/ops/devops/vuln/k6-vuln-explorer.js
StellaOps Bot 2d08f52715 feat(zastava): add evidence locker plan and schema examples
- Introduced README.md for Zastava Evidence Locker Plan detailing artifacts to sign and post-signing steps.
- Added example JSON schemas for observer events and webhook admissions.
- Updated implementor guidelines with checklist for CI linting, determinism, secrets management, and schema control.
- Created alert rules for Vuln Explorer to monitor API latency and projection errors.
- Developed analytics ingestion plan for Vuln Explorer, focusing on telemetry and PII guardrails.
- Implemented Grafana dashboard configuration for Vuln Explorer metrics visualization.
- Added expected projection SHA256 for vulnerability events.
- Created k6 load testing script for Vuln Explorer API.
- Added sample projection and replay event data for testing.
- Implemented ReplayInputsLock for deterministic replay inputs management.
- Developed tests for ReplayInputsLock to ensure stable hash computation.
- Created SurfaceManifestDeterminismVerifier to validate manifest determinism and integrity.
- Added unit tests for SurfaceManifestDeterminismVerifier to ensure correct functionality.
- Implemented Angular tests for VulnerabilityHttpClient and VulnerabilityDetailComponent to verify API interactions and UI rendering.
2025-12-02 09:27:31 +02:00

48 lines
1.5 KiB
JavaScript

import http from 'k6/http';
import { check, sleep } from 'k6';
import { Trend, Rate } from 'k6/metrics';
const latency = new Trend('vuln_api_latency');
const errors = new Rate('vuln_api_errors');
const BASE = __ENV.VULN_BASE || 'http://localhost:8449';
const TENANT = __ENV.VULN_TENANT || 'alpha';
const TOKEN = __ENV.VULN_TOKEN || '';
const HEADERS = TOKEN ? { 'Authorization': `Bearer ${TOKEN}`, 'X-StellaOps-Tenant': TENANT } : { 'X-StellaOps-Tenant': TENANT };
export const options = {
scenarios: {
ramp: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '5m', target: 200 },
{ duration: '10m', target: 200 },
{ duration: '2m', target: 0 },
],
gracefulRampDown: '30s',
},
},
thresholds: {
vuln_api_latency: ['p(95)<250'],
vuln_api_errors: ['rate<0.005'],
},
};
function req(path, params = {}) {
const res = http.get(`${BASE}${path}`, { headers: HEADERS, tags: params.tags });
latency.add(res.timings.duration, params.tags);
errors.add(res.status >= 400, params.tags);
check(res, {
'status is 2xx': (r) => r.status >= 200 && r.status < 300,
});
return res;
}
export default function () {
req(`/findings?tenant=${TENANT}&page=1&pageSize=50`, { tags: { endpoint: 'list' } });
req(`/findings?tenant=${TENANT}&status=open&page=1&pageSize=50`, { tags: { endpoint: 'filter_open' } });
req(`/findings/stats?tenant=${TENANT}`, { tags: { endpoint: 'stats' } });
sleep(1);
}