126 lines
3.4 KiB
JavaScript
126 lines
3.4 KiB
JavaScript
import { check, sleep } from "k6";
|
|
import http from "k6/http";
|
|
import exec from "k6/execution";
|
|
import { Trend } from "k6/metrics";
|
|
|
|
function required(name) {
|
|
const value = __ENV[name];
|
|
|
|
if (value === undefined || value === "") {
|
|
throw new Error(`${name} is required`);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
function positiveInteger(name) {
|
|
const value = Number(required(name));
|
|
|
|
if (!Number.isInteger(value) || value <= 0) {
|
|
throw new Error(`${name} must be a positive integer`);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
function nonNegativeNumber(name) {
|
|
const value = Number(required(name));
|
|
|
|
if (!Number.isFinite(value) || value < 0) {
|
|
throw new Error(`${name} must be a non-negative number`);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
const baseUrl = required("BASE_URL").replace(/\/+$/, "");
|
|
|
|
if (baseUrl !== "http://web:4000") {
|
|
throw new Error("The scale read-only profile is pinned to http://web:4000");
|
|
}
|
|
|
|
const sessionCookie = required("SESSION_COOKIE");
|
|
const vus = positiveInteger("VUS");
|
|
const duration = required("DURATION");
|
|
const thinkSeconds = nonNegativeNumber("THINK_SECONDS");
|
|
|
|
const viewports = [
|
|
{
|
|
path:
|
|
"/requests?west=22.096886&south=45.034261&east=38.949914&north=55.310025&zoom=5&width=767&height=734&view=split",
|
|
endpoint: "requests_europe",
|
|
heading: "Who needs help?",
|
|
},
|
|
{
|
|
path:
|
|
"/activities?west=22.096886&south=45.034261&east=38.949914&north=55.310025&zoom=5&width=767&height=734&view=split",
|
|
endpoint: "activities_europe",
|
|
heading: "Nearby activities",
|
|
},
|
|
{
|
|
path:
|
|
"/requests?west=-179.9&south=-80&east=179.9&north=80&zoom=1&width=1280&height=720&view=map",
|
|
endpoint: "requests_world",
|
|
heading: "Who needs help?",
|
|
},
|
|
{
|
|
path:
|
|
"/activities?west=-179.9&south=-80&east=179.9&north=80&zoom=1&width=1280&height=720&view=map",
|
|
endpoint: "activities_world",
|
|
heading: "Nearby activities",
|
|
},
|
|
];
|
|
|
|
const endpointDurations = {
|
|
requests_europe: new Trend("wnh_requests_europe_duration", true),
|
|
activities_europe: new Trend("wnh_activities_europe_duration", true),
|
|
requests_world: new Trend("wnh_requests_world_duration", true),
|
|
activities_world: new Trend("wnh_activities_world_duration", true),
|
|
};
|
|
|
|
export const options = {
|
|
scenarios: {
|
|
scale_readonly_http: {
|
|
executor: "constant-vus",
|
|
exec: "scaleReadonlyHttp",
|
|
vus,
|
|
duration,
|
|
},
|
|
},
|
|
thresholds: {
|
|
checks: [{ threshold: "rate==1", abortOnFail: true }],
|
|
http_req_failed: [{ threshold: "rate==0", abortOnFail: true }],
|
|
},
|
|
};
|
|
|
|
export function scaleReadonlyHttp() {
|
|
const viewport = viewports[exec.scenario.iterationInTest % viewports.length];
|
|
const response = http.get(`${baseUrl}${viewport.path}`, {
|
|
redirects: 0,
|
|
tags: {
|
|
endpoint: viewport.endpoint,
|
|
safety_scope: "persistent_local_scale_readonly",
|
|
},
|
|
headers: {
|
|
Cookie: sessionCookie,
|
|
Host: "scale.localhost",
|
|
"X-Forwarded-Host": "scale.localhost",
|
|
"X-Forwarded-Port": "4121",
|
|
"X-Forwarded-Proto": "https",
|
|
"User-Agent": "WhoNeedHelp-persistent-scale-readonly/1",
|
|
},
|
|
});
|
|
|
|
endpointDurations[viewport.endpoint].add(response.timings.duration);
|
|
|
|
check(response, {
|
|
[`GET ${viewport.endpoint} returned 200`]: (candidate) =>
|
|
candidate.status === 200,
|
|
[`GET ${viewport.endpoint} rendered its loading shell`]: (candidate) =>
|
|
candidate.body.includes(viewport.heading) &&
|
|
candidate.body.includes("Loading results"),
|
|
});
|
|
|
|
sleep(thinkSeconds);
|
|
}
|