Add runtime event telemetry and auth-mode config hardening
This commit is contained in:
94
tests/runtime-events.test.ts
Normal file
94
tests/runtime-events.test.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtemp, readFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { resolve } from "node:path";
|
||||
import {
|
||||
RuntimeEventPublisher,
|
||||
createDiscordWebhookRuntimeEventSink,
|
||||
createFileRuntimeEventSink,
|
||||
} from "../src/telemetry/index.js";
|
||||
|
||||
test("runtime event file sink writes ndjson events", async () => {
|
||||
const root = await mkdtemp(resolve(tmpdir(), "ai-ops-runtime-events-"));
|
||||
const logPath = resolve(root, "runtime-events.ndjson");
|
||||
const publisher = new RuntimeEventPublisher({
|
||||
sinks: [createFileRuntimeEventSink(logPath)],
|
||||
});
|
||||
|
||||
await publisher.publish({
|
||||
type: "session.started",
|
||||
severity: "info",
|
||||
sessionId: "session-1",
|
||||
message: "Session started.",
|
||||
metadata: {
|
||||
entryNodeId: "entry",
|
||||
},
|
||||
});
|
||||
|
||||
const lines = (await readFile(logPath, "utf8"))
|
||||
.trim()
|
||||
.split("\n")
|
||||
.filter((line) => line.length > 0);
|
||||
assert.equal(lines.length, 1);
|
||||
const parsed = JSON.parse(lines[0] ?? "{}") as Record<string, unknown>;
|
||||
assert.equal(parsed.type, "session.started");
|
||||
assert.equal(parsed.severity, "info");
|
||||
assert.equal(parsed.sessionId, "session-1");
|
||||
});
|
||||
|
||||
test("discord runtime sink supports severity threshold and always-notify types", async () => {
|
||||
const requests: Array<{
|
||||
url: string;
|
||||
body: Record<string, unknown>;
|
||||
}> = [];
|
||||
|
||||
const discordSink = createDiscordWebhookRuntimeEventSink({
|
||||
webhookUrl: "https://discord.example/webhook",
|
||||
minSeverity: "critical",
|
||||
alwaysNotifyTypes: ["session.started", "session.completed"],
|
||||
fetchFn: async (url, init) => {
|
||||
requests.push({
|
||||
url: String(url),
|
||||
body: JSON.parse(String(init?.body ?? "{}")) as Record<string, unknown>,
|
||||
});
|
||||
return new Response(null, { status: 204 });
|
||||
},
|
||||
});
|
||||
|
||||
const publisher = new RuntimeEventPublisher({
|
||||
sinks: [discordSink],
|
||||
});
|
||||
|
||||
await publisher.publish({
|
||||
type: "session.started",
|
||||
severity: "info",
|
||||
sessionId: "session-1",
|
||||
message: "Session started.",
|
||||
});
|
||||
await publisher.publish({
|
||||
type: "node.attempt.completed",
|
||||
severity: "warning",
|
||||
sessionId: "session-1",
|
||||
nodeId: "node-1",
|
||||
attempt: 1,
|
||||
message: "Validation failed.",
|
||||
});
|
||||
await publisher.publish({
|
||||
type: "session.failed",
|
||||
severity: "critical",
|
||||
sessionId: "session-1",
|
||||
message: "Session failed.",
|
||||
});
|
||||
|
||||
assert.equal(requests.length, 2);
|
||||
assert.equal(requests[0]?.url, "https://discord.example/webhook");
|
||||
const firstPayload = requests[0]?.body;
|
||||
assert.ok(firstPayload);
|
||||
const firstEmbeds = firstPayload.embeds as Array<Record<string, unknown>>;
|
||||
assert.equal(firstEmbeds[0]?.title, "session.started");
|
||||
const secondPayload = requests[1]?.body;
|
||||
assert.ok(secondPayload);
|
||||
const secondEmbeds = secondPayload.embeds as Array<Record<string, unknown>>;
|
||||
assert.equal(secondEmbeds[0]?.title, "session.failed");
|
||||
});
|
||||
Reference in New Issue
Block a user