diff --git a/scenarios/uptimerunner-basic/scenario.ts b/scenarios/uptimerunner-basic/scenario.ts index b3ea1a0..0609b7d 100644 --- a/scenarios/uptimerunner-basic/scenario.ts +++ b/scenarios/uptimerunner-basic/scenario.ts @@ -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(); }