test: add remote runner vagrant scenario

This commit is contained in:
2026-04-30 07:13:20 +00:00
parent 0ca0d367d3
commit fc29bc9f7e
10 changed files with 387 additions and 1 deletions
@@ -0,0 +1,111 @@
import { assert, assertEquals } from "jsr:@std/assert@^1.0.0";
import { RunnerAdmin } from "../../../uptime.link/ts_api/classes/runner-admin.ts";
import { RunnerCoordinator } from "../../../uptime.link/ts_api/classes/runner-coordinator.ts";
import { createRunnerRequestHandler } from "../../../uptime.link/ts_api/classes/runner-request-handler.ts";
const scenarioName = "uptimerunner-vagrant";
const controllerHost = Deno.env.get("UPTIMELINK_CONTROLLER_HOST") ?? "0.0.0.0";
const controllerPort = Number(
Deno.env.get("UPTIMELINK_CONTROLLER_PORT") ?? "8080",
);
const runnerId = Deno.env.get("UPTIMELINK_RUNNER_ID") ?? "vagrant-runner-1";
const runnerToken = Deno.env.get("UPTIMELINK_RUNNER_TOKEN") ?? "vagrant-token";
const targetPort = Number(Deno.env.get("UPTIMELINK_TARGET_PORT") ?? "18081");
const timeoutMs = Number(
Deno.env.get("UPTIMELINK_VAGRANT_TIMEOUT_MS") ?? "120000",
);
const targetUrl = Deno.env.get("UPTIMELINK_RUNNER_TARGET_URL") ??
`http://127.0.0.1:${targetPort}/health`;
const main = async () => {
const coordinator = new RunnerCoordinator();
const admin = new RunnerAdmin(coordinator);
admin.registerRunner({
runnerId,
token: runnerToken,
labels: ["scenario:vagrant", "role:internal"],
});
coordinator.enqueueCheck({
id: "vagrant-runner-local-http",
type: "http",
url: targetUrl,
expectedStatusCodes: [200],
expectedBodyIncludes: "runner-local healthy",
timeoutMs: 5000,
metadata: {
monitorId: "vagrant-runner-local-http",
},
}, { runnerId });
const runnerRequestHandler = createRunnerRequestHandler(coordinator);
const server = Deno.serve(
{ hostname: controllerHost, port: controllerPort },
(request) => {
return runnerRequestHandler(request);
},
);
try {
console.log(
`[${scenarioName}] Controller listening on ${controllerHost}:${controllerPort}`,
);
console.log(`[${scenarioName}] Waiting for runner ${runnerId}`);
await waitFor(
() => coordinator.getRunner(runnerId)?.lastHeartbeat,
timeoutMs,
);
const result = await waitFor(
() =>
coordinator.listResults().find((candidate) => {
return candidate.checkId === "vagrant-runner-local-http";
}),
timeoutMs,
);
assert(result);
if (result.status !== "ok") {
console.error(JSON.stringify(result, null, 2));
}
assertEquals(result.runnerId, runnerId);
assertEquals(result.type, "http");
assertEquals(result.status, "ok");
assertEquals(result.statusCode, 200);
assert(result.responseTime !== undefined);
assertEquals(coordinator.getQueueLength(), 0);
console.log(`[${scenarioName}] Passed`);
} finally {
await server.shutdown();
}
};
async function waitFor<T>(
readArg: () => T | undefined,
timeoutMsArg: number,
): Promise<T> {
const started = Date.now();
while (Date.now() - started < timeoutMsArg) {
const value = readArg();
if (value) {
return value;
}
await new Promise((resolve) => setTimeout(resolve, 500));
}
throw new Error(`Timed out after ${timeoutMsArg}ms.`);
}
if (import.meta.main) {
try {
await main();
} catch (error) {
console.error(
`[${scenarioName}] Failed: ${
error instanceof Error ? error.stack : String(error)
}`,
);
Deno.exit(1);
}
}
+38
View File
@@ -0,0 +1,38 @@
# uptimerunner-vagrant
This scenario verifies a real remote runner shape with two Vagrant machines:
1. `controller` runs the uptime.link runner protocol handler.
2. `runner` compiles and installs `uptimerunner` as a systemd service.
3. `runner` also runs a local HTTP target on `127.0.0.1`.
4. The controller assigns a check for that runner-local target.
5. The remote runner heartbeats, executes the check from its own VM, and submits
the result back to the controller.
Run it with:
```bash
pnpm scenario:uptimerunner-vagrant
```
Override the default private-network addresses if they collide locally:
```bash
UPTIMELINK_VAGRANT_CONTROLLER_IP=192.168.60.10 \
UPTIMELINK_VAGRANT_RUNNER_IP=192.168.60.11 \
pnpm scenario:uptimerunner-vagrant
```
The scenario defaults to `UPTIMELINK_VAGRANT_PROVIDER=libvirt`. If this host
uses VirtualBox instead, run:
```bash
UPTIMELINK_VAGRANT_PROVIDER=virtualbox pnpm scenario:uptimerunner-vagrant
```
If the current shell has not picked up newly added `libvirt` group membership,
run:
```bash
sg libvirt -c 'pnpm scenario:uptimerunner-vagrant'
```