test: cover monitor status derivation

This commit is contained in:
2026-04-29 21:35:21 +00:00
parent 440660a000
commit 6ebc0d96bb
+74 -32
View File
@@ -2,13 +2,15 @@ import { assert, assertEquals, assertRejects } from "jsr:@std/assert@^1.0.0";
import { RunnerCoordinator } from "../../../uptime.link/ts_api/classes/runner-coordinator.ts";
import { RunnerFileStore } from "../../../uptime.link/ts_api/classes/runner-file-store.ts";
import {
createRunnerSchedulesFromMonitors,
type IRunnerMonitorDefinition,
} from "../../../uptime.link/ts_api/classes/runner-monitor-mapper.ts";
import { createRunnerRequestHandler } from "../../../uptime.link/ts_api/classes/runner-request-handler.ts";
import { RunnerResultIngestor } from "../../../uptime.link/ts_api/classes/runner-result-ingestor.ts";
import { RunnerScheduler } from "../../../uptime.link/ts_api/classes/runner-scheduler.ts";
import { UptimeRunner } from "../../../uptimerunner/ts/runner.ts";
import type {
IResultSubmitRequest,
TCheckJob,
} from "../../../uptimerunner/ts/interfaces.ts";
import type { IResultSubmitRequest } from "../../../uptimerunner/ts/interfaces.ts";
const scenarioName = "uptimerunner-basic";
const runnerId = `scenario-runner-${Date.now().toString(36)}`;
@@ -18,28 +20,47 @@ const main = async () => {
const targetServer = await startServer(() => new Response("healthy"));
const tcpServer = startTcpServer();
const resultSubmissions: IResultSubmitRequest[] = [];
const checkQueue: TCheckJob[] = [
const monitors: IRunnerMonitorDefinition[] = [
{
id: "local-http-health",
type: "http",
url: targetServer.url,
expectedStatusCodes: [200],
expectedBodyIncludes: "healthy",
metadata: {
scenario: scenarioName,
name: "Local HTTP Health",
intervalMs: 60000,
check: {
type: "http",
url: targetServer.url,
expectedStatusCodes: [200],
expectedBodyIncludes: "healthy",
},
},
{
id: "local-tcp-health",
type: "tcp",
host: "127.0.0.1",
port: tcpServer.port,
name: "Local TCP Health",
intervalMs: 60000,
check: {
type: "tcp",
host: "127.0.0.1",
port: tcpServer.port,
},
},
{
id: "manual-assumption",
type: "assumption",
assumedStatus: "ok",
message: "manual assumption is healthy",
name: "Manual Assumption",
intervalMs: 60000,
check: {
type: "assumption",
assumedStatus: "ok",
message: "manual assumption is healthy",
},
},
{
id: "manual-degraded",
name: "Manual Degraded",
intervalMs: 60000,
check: {
type: "assumption",
assumedStatus: "not ok",
message: "manual assumption is degraded",
},
},
];
@@ -48,14 +69,10 @@ const main = async () => {
});
const scheduler = new RunnerScheduler(coordinator, { now: () => 1000 });
const scheduleResult = scheduler.scheduleDueChecks(
checkQueue.map((check) => ({
monitorId: `monitor-${check.id}`,
check,
intervalMs: 60000,
})),
createRunnerSchedulesFromMonitors(monitors),
);
assertEquals(scheduleResult.scheduledChecks.length, 3);
assertEquals(coordinator.getQueueLength(), 3);
assertEquals(scheduleResult.scheduledChecks.length, 4);
assertEquals(coordinator.getQueueLength(), 4);
assertEquals(
scheduler.scheduleDueChecks(scheduleResult.schedules).scheduledChecks
.length,
@@ -84,20 +101,23 @@ const main = async () => {
console.log(`[${scenarioName}] Running single runner iteration`);
const result = await runner.runOnce();
assertEquals(result.checks.length, 3);
assertEquals(result.results.length, 3);
assertEquals(result.results[0].checkId, "local-http-health");
assertEquals(result.checks.length, 4);
assertEquals(result.results.length, 4);
assertEquals(result.results[0].checkId, "monitor-local-http-health");
assertEquals(result.results[0].status, "ok");
assertEquals(result.results[1].checkId, "local-tcp-health");
assertEquals(result.results[1].checkId, "monitor-local-tcp-health");
assertEquals(result.results[1].status, "ok");
assertEquals(result.results[2].checkId, "manual-assumption");
assertEquals(result.results[2].checkId, "monitor-manual-assumption");
assertEquals(result.results[2].status, "ok");
assertEquals(result.results[3].checkId, "monitor-manual-degraded");
assertEquals(result.results[3].status, "not ok");
assertEquals(resultSubmissions.length, 1);
assertEquals(resultSubmissions[0].runnerId, runnerId);
assertEquals(resultSubmissions[0].results[0].status, "ok");
assert(resultSubmissions[0].results[0].responseTime !== undefined);
assertEquals(coordinator.listResults().length, 3);
assertEquals(coordinator.listResults().length, 4);
assertEquals(coordinator.getQueueLength(), 0);
assertMonitorStatusDerivation(coordinator.listResults());
await assertSnapshotPersistence(coordinator, targetServer.url);
const emptyResult = await runner.runOnce();
@@ -170,6 +190,28 @@ function startTcpServer(): { port: number; close: () => void } {
};
}
function assertMonitorStatusDerivation(
results: IResultSubmitRequest["results"],
): void {
const ingestor = new RunnerResultIngestor();
const ingestion = ingestor.ingest(results);
assertEquals(ingestion.monitorStates.length, 4);
assertEquals(ingestion.ignoredResults.length, 0);
assertEquals(
ingestor.getMonitorState("local-http-health")?.status,
"operational",
);
assertEquals(
ingestor.getMonitorState("local-tcp-health")?.status,
"operational",
);
assertEquals(
ingestor.getMonitorState("manual-assumption")?.status,
"operational",
);
assertEquals(ingestor.getMonitorState("manual-degraded")?.status, "degraded");
}
async function assertSnapshotPersistence(
coordinatorArg: RunnerCoordinator,
targetUrlArg: string,
@@ -196,7 +238,7 @@ async function assertSnapshotPersistence(
const snapshot = await store.load();
assert(snapshot);
const restoredCoordinator = new RunnerCoordinator({ snapshot });
assertEquals(restoredCoordinator.listResults().length, 3);
assertEquals(restoredCoordinator.listResults().length, 4);
assertEquals(restoredCoordinator.listRunners().length, 1);
restoredCoordinator.enqueueCheck({
id: "post-restart-http-health",
@@ -218,7 +260,7 @@ async function assertSnapshotPersistence(
const restoredResult = await restoredRunner.runOnce();
assertEquals(restoredResult.results.length, 1);
assertEquals(restoredResult.results[0].status, "ok");
assertEquals(restoredCoordinator.listResults().length, 4);
assertEquals(restoredCoordinator.listResults().length, 5);
} finally {
await restoredServer.server.shutdown();
}