Files
uptimerunner/test/test.ts
T

110 lines
3.2 KiB
TypeScript
Raw Normal View History

2026-04-29 19:48:14 +00:00
import { assert, assertEquals } from 'jsr:@std/assert@^1.0.0';
import { CheckExecutor } from '../ts/check-executor.ts';
import { UptimeRunner } from '../ts/runner.ts';
import type { TCheckJob } from '../ts/interfaces.ts';
Deno.test('CheckExecutor: executes successful HTTP check', async () => {
const { server, url } = await startServer(() => new Response('ok'));
try {
const executor = new CheckExecutor('test-runner');
const result = await executor.execute({
id: 'http-ok',
type: 'http',
url,
expectedStatusCodes: [200],
expectedBodyIncludes: 'ok',
});
assertEquals(result.status, 'ok');
assertEquals(result.statusCode, 200);
assert(result.responseTime !== undefined);
} finally {
await server.shutdown();
}
});
Deno.test('CheckExecutor: reports HTTP expectation mismatch', async () => {
const { server, url } = await startServer(() => new Response('not-ok', { status: 503 }));
try {
const executor = new CheckExecutor('test-runner');
const result = await executor.execute({
id: 'http-not-ok',
type: 'http',
url,
expectedStatusCodes: [200],
});
assertEquals(result.status, 'not ok');
assertEquals(result.statusCode, 503);
} finally {
await server.shutdown();
}
});
Deno.test('UptimeRunner: polls checks and submits results', async () => {
const targetServer = await startServer(() => new Response('healthy'));
const postedResults: unknown[] = [];
const checks: TCheckJob[] = [
{
id: 'target-health',
type: 'http',
url: targetServer.url,
expectedStatusCodes: [200],
expectedBodyIncludes: 'healthy',
},
];
const coordinatorServer = await startServer(async (request) => {
const url = new URL(request.url);
if (url.pathname === '/api/runner/v1/checks') {
assertEquals(request.headers.get('authorization'), 'Bearer test-token');
return Response.json({ checks });
}
if (url.pathname === '/api/runner/v1/results') {
postedResults.push(await request.json());
return Response.json({ ok: true });
}
if (url.pathname === '/api/runner/v1/heartbeat') {
return Response.json({ ok: true });
}
return new Response('not found', { status: 404 });
});
try {
const runner = new UptimeRunner({
instanceUrl: coordinatorServer.url,
runnerId: 'test-runner',
token: 'test-token',
});
const result = await runner.runOnce();
assertEquals(result.checks.length, 1);
assertEquals(result.results.length, 1);
assertEquals(result.results[0].status, 'ok');
assertEquals(postedResults.length, 1);
} finally {
await coordinatorServer.server.shutdown();
await targetServer.server.shutdown();
}
});
async function startServer(
handlerArg: Deno.ServeHandler,
): Promise<{ server: Deno.HttpServer; url: string }> {
let resolveListening: (addr: Deno.NetAddr) => void;
const listening = new Promise<Deno.NetAddr>((resolve) => {
resolveListening = resolve;
});
const server = Deno.serve({
hostname: '127.0.0.1',
port: 0,
onListen: (addr) => resolveListening(addr),
}, handlerArg);
const addr = await listening;
return {
server,
url: `http://${addr.hostname}:${addr.port}`,
};
}