mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 15:51:15 +00:00
First load script: healthz + meta/config + tenant availability/catalog, booking POST gated behind WRITE=1. Env-driven BASE_URL/VUS/DURATION so the same file runs locally (smoke) and from the Proxmox runner against a deployed target (load). 404 on unknown tenant slug counted as an expected response. Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
74 lines
2.7 KiB
JavaScript
74 lines
2.7 KiB
JavaScript
// k6 smoke/load test — Bookra public booking surface.
|
|
//
|
|
// Local smoke (script validation, not perf evidence — loopback latency is ~0ms):
|
|
// k6 run tests/load/bookings.js
|
|
// Load against a deployed target (run from the Proxmox host, not your box):
|
|
// BASE_URL=https://api.bookra.eu VUS=50 DURATION=3m k6 run tests/load/bookings.js
|
|
// Include a booking-creation pass (writes a real row — point at a test tenant):
|
|
// WRITE=1 TENANT_SLUG=test-tenant BASE_URL=... k6 run tests/load/bookings.js
|
|
//
|
|
// Endpoints exercised: /healthz, /v1/meta/config, public availability + catalog,
|
|
// and (WRITE=1) POST /v1/public/bookings — the money path, rate-limited.
|
|
import http from "k6/http";
|
|
import { check, sleep, group } from "k6";
|
|
|
|
const BASE_URL = (__ENV.BASE_URL || "http://localhost:8080").replace(/\/$/, "");
|
|
const TENANT = __ENV.TENANT_SLUG || "demo";
|
|
const WRITE = __ENV.WRITE === "1";
|
|
|
|
export const options = {
|
|
scenarios: {
|
|
booking_surface: {
|
|
executor: "constant-vus",
|
|
vus: Number(__ENV.VUS || 2),
|
|
duration: __ENV.DURATION || "30s",
|
|
},
|
|
},
|
|
thresholds: {
|
|
// 800ms covers a cold local dev server; tighten to 400 once aimed at prod.
|
|
http_req_duration: ["p(95)<800"],
|
|
http_req_failed: ["rate<0.01"],
|
|
"checks{check:public reads ok}": ["rate>0.99"],
|
|
},
|
|
};
|
|
|
|
export default function () {
|
|
group("public reads", () => {
|
|
// 404 on an unknown tenant slug is a correct answer, not a failure —
|
|
// mark it expected so http_req_failed stays meaningful.
|
|
const tenantOk = { responseCallback: http.expectedStatuses(200, 404) };
|
|
const hz = http.get(`${BASE_URL}/healthz`);
|
|
const cfg = http.get(`${BASE_URL}/v1/meta/config`);
|
|
const cat = http.get(`${BASE_URL}/v1/public/tenants/${TENANT}/catalog`, tenantOk);
|
|
const av = http.get(`${BASE_URL}/v1/public/tenants/${TENANT}/availability`, tenantOk);
|
|
|
|
check(null, {
|
|
"public reads ok":
|
|
hz.status === 200 &&
|
|
cfg.status === 200 &&
|
|
[200, 404].includes(cat.status) &&
|
|
[200, 404].includes(av.status),
|
|
});
|
|
});
|
|
|
|
if (WRITE) {
|
|
group("booking create", () => {
|
|
const res = http.post(
|
|
`${BASE_URL}/v1/public/bookings`,
|
|
JSON.stringify({
|
|
tenantSlug: TENANT,
|
|
serviceId: __ENV.SERVICE_ID || "svc_loadtest",
|
|
startsAt: new Date(Date.now() + 864e5).toISOString(),
|
|
customer: { name: "k6 loadtest", email: "[email protected]" },
|
|
}),
|
|
{ headers: { "Content-Type": "application/json" } },
|
|
);
|
|
// 201/200 created, 400/404 validation — all prove the handler runs;
|
|
// 5xx and 429-at-low-VUS are the failures that matter.
|
|
check(res, { "booking handler healthy": (r) => r.status < 500 });
|
|
});
|
|
}
|
|
|
|
sleep(0.5);
|
|
}
|