148 lines
5.1 KiB
JavaScript
148 lines
5.1 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "vitest";
|
|
|
|
import { parseArgs, resolveConfig, runLoadTests } from "./run-load-tests.mjs";
|
|
|
|
function recordingSpawn(handlers) {
|
|
const calls = [];
|
|
function spawn(command, args, options) {
|
|
calls.push({ command, args, options });
|
|
const handler = handlers[command];
|
|
if (!handler) {
|
|
return { status: 1, stdout: "", stderr: "", error: new Error(`unexpected spawn for ${command}`) };
|
|
}
|
|
return handler({ args, options });
|
|
}
|
|
spawn.calls = calls;
|
|
return spawn;
|
|
}
|
|
|
|
function captureLines() {
|
|
const lines = [];
|
|
function write(line) {
|
|
lines.push(line);
|
|
}
|
|
write.lines = lines;
|
|
return write;
|
|
}
|
|
|
|
describe("run-load-tests", () => {
|
|
it("parses --target, --scenario, and --skip-reachability flags", () => {
|
|
const parsed = parseArgs([
|
|
"--target",
|
|
"http://staging.example.test",
|
|
"--scenario",
|
|
"tests/load/login.js",
|
|
"--skip-reachability",
|
|
]);
|
|
assert.equal(parsed.targetUrl, "http://staging.example.test");
|
|
assert.equal(parsed.scenarioPath, "tests/load/login.js");
|
|
assert.equal(parsed.skipReachability, true);
|
|
});
|
|
|
|
it("prefers --target argv over K6_TARGET_URL env var", () => {
|
|
const config = resolveConfig({
|
|
argv: ["--target", "http://argv.example.test"],
|
|
env: { K6_TARGET_URL: "http://env.example.test" },
|
|
});
|
|
assert.equal(config.targetUrl, "http://argv.example.test");
|
|
});
|
|
|
|
it("falls back to K6_TARGET_URL env var when no --target argv is given", () => {
|
|
const config = resolveConfig({
|
|
argv: [],
|
|
env: { K6_TARGET_URL: "http://env.example.test" },
|
|
});
|
|
assert.equal(config.targetUrl, "http://env.example.test");
|
|
});
|
|
|
|
it("uses the default URL when neither argv nor env provides one", () => {
|
|
const config = resolveConfig({ argv: [], env: {} });
|
|
assert.equal(config.targetUrl, "http://localhost:3000");
|
|
assert.equal(config.scenarioPath, "tests/load/scenarios.js");
|
|
assert.equal(config.skipReachability, false);
|
|
});
|
|
|
|
it("SKIPs with exit 0 when the k6 binary is missing", () => {
|
|
const spawn = recordingSpawn({
|
|
k6: () => ({ status: 127, stdout: "", stderr: "", error: new Error("ENOENT") }),
|
|
});
|
|
const stdout = captureLines();
|
|
const stderr = captureLines();
|
|
|
|
const outcome = runLoadTests({ argv: [], env: {}, spawn, stdout, stderr });
|
|
|
|
assert.equal(outcome.status, "skip");
|
|
assert.equal(outcome.reason, "binary-missing");
|
|
assert.equal(outcome.exitCode, 0);
|
|
assert.equal(stdout.lines.length, 1);
|
|
assert.match(stdout.lines[0], /^SKIP k6 binary not installed/);
|
|
assert.match(stdout.lines[0], /k6\.io\/docs\/getting-started\/installation/);
|
|
assert.equal(stderr.lines.length, 0);
|
|
// k6 was probed, curl was never reached.
|
|
assert.equal(spawn.calls.filter((call) => call.command === "curl").length, 0);
|
|
});
|
|
|
|
it("SKIPs with exit 0 when the target URL is unreachable", () => {
|
|
const spawn = recordingSpawn({
|
|
k6: () => ({ status: 0, stdout: "k6 v0.50.0", stderr: "" }),
|
|
curl: () => ({ status: 7, stdout: "", stderr: "Connection refused" }),
|
|
});
|
|
const stdout = captureLines();
|
|
const stderr = captureLines();
|
|
|
|
const outcome = runLoadTests({
|
|
argv: ["--target", "http://offline.example.test"],
|
|
env: {},
|
|
spawn,
|
|
stdout,
|
|
stderr,
|
|
});
|
|
|
|
assert.equal(outcome.status, "skip");
|
|
assert.equal(outcome.reason, "target-unreachable");
|
|
assert.equal(outcome.exitCode, 0);
|
|
assert.ok(
|
|
stdout.lines.some((line) => /^SKIP target http:\/\/offline\.example\.test not reachable$/.test(line)),
|
|
`expected SKIP line, got: ${stdout.lines.join(" | ")}`,
|
|
);
|
|
// k6 run was never invoked once the target was unreachable.
|
|
const k6RunCalls = spawn.calls.filter((call) => call.command === "k6" && call.args[0] === "run");
|
|
assert.equal(k6RunCalls.length, 0);
|
|
});
|
|
|
|
it("honours K6_TARGET_URL env override and forwards it into the k6 run env", () => {
|
|
const spawn = recordingSpawn({
|
|
k6: ({ args }) => {
|
|
if (args[0] === "version") {
|
|
return { status: 0, stdout: "k6 v0.50.0", stderr: "" };
|
|
}
|
|
// k6 run — succeed.
|
|
return { status: 0, stdout: "", stderr: "" };
|
|
},
|
|
curl: () => ({ status: 0, stdout: "200", stderr: "" }),
|
|
});
|
|
const stdout = captureLines();
|
|
const stderr = captureLines();
|
|
|
|
const outcome = runLoadTests({
|
|
argv: ["--skip-reachability"],
|
|
env: { K6_TARGET_URL: "http://override.example.test" },
|
|
spawn,
|
|
stdout,
|
|
stderr,
|
|
});
|
|
|
|
assert.equal(outcome.status, "pass");
|
|
assert.equal(outcome.exitCode, 0);
|
|
const k6RunCall = spawn.calls.find((call) => call.command === "k6" && call.args[0] === "run");
|
|
assert.ok(k6RunCall, "expected k6 run to be invoked");
|
|
assert.deepEqual(k6RunCall.args, ["run", "tests/load/scenarios.js"]);
|
|
assert.equal(k6RunCall.options.env.K6_TARGET_URL, "http://override.example.test");
|
|
assert.ok(
|
|
stdout.lines.some((line) => line.includes("http://override.example.test")),
|
|
`expected PASS line to mention override URL, got: ${stdout.lines.join(" | ")}`,
|
|
);
|
|
});
|
|
});
|