Files
Rendezvous/tests/Observability/observability-assets.test.mjs
KyuubiYoru 99885f8c8c
quality-gate / quality (push) Failing after 1m31s
quality-gate / container (push) Has been skipped
feat(observability): add diagnostic dashboards (#27)
2026-07-17 00:22:46 +02:00

90 lines
3.7 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import test from "node:test";
const root = new URL("../../", import.meta.url);
const dashboardPath = new URL(
"deploy/observability/grafana/dashboards/rendezvous-overview.json",
root,
);
test("dashboard is provisionable, broad, and uses privacy-safe bounded series", async () => {
const dashboard = JSON.parse(await readFile(dashboardPath, "utf8"));
assert.equal(dashboard.uid, "rendezvous-overview");
assert.equal(dashboard.editable, false);
assert.ok(dashboard.panels.length >= 20);
assert.equal(new Set(dashboard.panels.map((panel) => panel.id)).size, dashboard.panels.length);
assert.equal(new Set(dashboard.panels.map((panel) => panel.title)).size, dashboard.panels.length);
const expressions = dashboard.panels
.flatMap((panel) => panel.targets ?? [])
.map((target) => target.expr ?? "")
.join("\n");
for (const metric of [
"rendezvous_http_requests_total",
"rendezvous_http_duration_milliseconds_bucket",
"rendezvous_udp_results_total",
"rendezvous_udp_received_bytes_total",
"rendezvous_limiter_drops_total",
"rendezvous_connection_outcomes_total",
"rendezvous_browser_sse_subscribers",
"rendezvous_store_active_listings",
"rendezvous_store_active_attempts",
"rendezvous_signing_keys",
"process_resident_memory_bytes",
"process_open_file_descriptors",
"dotnet_gc_heap_size_bytes",
]) {
assert.match(expressions, new RegExp(`\\b${metric}\\b`));
}
assert.doesNotMatch(
expressions,
/listing_?id|session_?id|player|subject|token|capability|endpoint|address|metadata|credential/i,
);
for (const panel of dashboard.panels) {
assert.ok(panel.title?.trim());
assert.ok(panel.gridPos?.w > 0 && panel.gridPos?.h > 0);
for (const target of panel.targets ?? []) {
assert.equal(target.editorMode, "code");
assert.ok(target.expr?.trim());
}
}
});
test("Compose overlay pins hardened services and keeps telemetry private", async () => {
const compose = await readFile(new URL("deploy/observability/compose.yaml", root), "utf8");
assert.match(compose, /prom\/prometheus:v3\.13\.1@sha256:[a-f0-9]{64}/);
assert.match(compose, /grafana\/grafana:13\.1\.0@sha256:[a-f0-9]{64}/);
assert.match(compose, /Rendezvous__Metrics__Enabled: "true"/);
assert.match(compose, /rendezvous-metrics-token:\/run\/secrets\/rendezvous-metrics-token:ro/);
assert.match(compose, /GF_AUTH_ANONYMOUS_ENABLED: "false"/);
assert.match(compose, /GF_PLUGINS_PREINSTALL_DISABLED: "true"/);
assert.match(compose, /"127\.0\.0\.1:3000:3000\/tcp"/);
assert.doesNotMatch(compose, /9090:9090/);
assert.ok((compose.match(/read_only: true/g) ?? []).length >= 2);
assert.ok((compose.match(/no-new-privileges:true/g) ?? []).length >= 2);
});
test("Prometheus and Grafana provisioning use server-side authenticated access", async () => {
const prometheus = await readFile(
new URL("deploy/observability/prometheus/prometheus.yml", root),
"utf8",
);
const datasource = await readFile(
new URL("deploy/observability/grafana/provisioning/datasources/prometheus.yaml", root),
"utf8",
);
const provider = await readFile(
new URL("deploy/observability/grafana/provisioning/dashboards/rendezvous.yaml", root),
"utf8",
);
assert.match(prometheus, /bearer_token_file: \/run\/secrets\/rendezvous-metrics-token/);
assert.match(prometheus, /- rendezvous:8080/);
assert.match(datasource, /uid: rendezvous-prometheus/);
assert.match(datasource, /access: proxy/);
assert.match(datasource, /url: http:\/\/prometheus:9090/);
assert.match(provider, /allowUiUpdates: false/);
assert.match(provider, /path: \/var\/lib\/grafana\/dashboards/);
});