/** * AI Software Factory — CI threshold-breach demonstration (TASK-0135). * * The acceptance criteria require that the CI matrix "enforces: dev * report-only, staging hard … **demonstrated by a fixture run with a lowered * threshold that fails the pipeline step**." This is that fixture. * * It is a deliberately-impossible suite: it drives a REAL, light endpoint * (GET /api/v1/health, a few seconds) and asserts a threshold no real HTTP * round-trip can meet — `p(95) < 1 ms` (configurable via K6_P95_MS, default 1, * i.e. one millisecond; the 50-th percentile of a health ping is already far * above that). With K6_STRICT=1 (the default) the threshold is HARD, so the * breach makes `k6 run` exit non-zero (k6 exit code 99) and the CI step that * runs this suite goes RED — exactly the demonstration the spec calls for. * * It is DISTINCT and obviously-failing on purpose: * - a separate file (not one of the four DoD suites), named to say what it * is; * - an impossible budget (p95 < 1 ms) that cannot be met by configuration, * so the red result is a function of the threshold, not of the data; * - a trivially-light workload (a health ping) so the only reason it fails * is the lowered threshold — a clean isolation of "breach ⇒ red step". * * The report-only (K6_STRICT=0) counterpart: the SAME impossible threshold * downgraded to report-only would NOT fail the step (k6 prints the breach in * the summary but exits 0) — which is precisely the dev/PR tier's behaviour. * The two runs together demonstrate the report-only-vs-hard switch the matrix * enforces. * * Run (demonstrate the RED step — staging-hard): * pnpm --dir tests/performance threshold-breach-demo * # → "running… (100.00%)", then the p95<1 threshold ✗ and a non-zero exit. * Run (demonstrate the report-only GREEN-with-warning): * K6_STRICT=0 pnpm --dir tests/performance threshold-breach-demo * * Env: * K6_API_URL API base (default http://localhost:4000) * K6_P95_MS the (impossible) p95 budget in ms (default 1) * K6_STRICT "1" hard (default — the step FAILS) / "0" report-only (the * step passes with the breach printed) */ import http from "k6/http"; import { check } from "k6"; import { Trend } from "k6/metrics"; const healthMs = new Trend("health_ms", true); const API = __ENV.K6_API_URL || "http://localhost:4000"; const STRICT = (__ENV.K6_STRICT || "1") !== "0"; // The impossible budget. Default 1 ms — no real HTTP round-trip (DNS + TCP + // TLS + handler + response) can hold p95 under a millisecond, so the run is a // deterministic breach, independent of the actual server speed. const P95_BUDGET_MS = parseInt(__ENV.K6_P95_MS || "1", 10); export function setup() { // Fail loudly if the API is unreachable — the demonstration is about the // THRESHOLD breaching, not about a dead server (a dead server would also // trip http_req_failed, muddying the "lowered threshold ⇒ red" isolation). const res = http.get(`${API}/api/v1/health`, { timeout: "5s" }); if (res.status !== 200) { throw new Error(`api health unreachable (${res.status}) — is the API running on ${API}?`); } return { ok: true }; } export default function () { const res = http.get(`${API}/api/v1/health`); healthMs.add(res.timings.duration); check(res, { "[breach-demo] health 200": (r) => r.status === 200 }); } export const options = { vus: 10, duration: "8s", thresholds: STRICT ? { // The lowered (impossible) threshold — the demonstration of a breach // failing the step. p95 < 1 ms is not achievable for a real request. health_ms: [`p(95)<${P95_BUDGET_MS}`], } : { // Report-only tier: the same impossible budget, but k6 must not fail // the step. A trivially-true threshold (avg<1e15) keeps the run green // while the summary still prints the real (breaching) p95 — mirroring // how the dev/PR tier reports without blocking. health_ms: ["avg<1e15"], }, summaryTrendStats: ["avg", "min", "med", "p(90)", "p(95)", "p(99)", "max"], };