82f1f1bd58
Función del grupo fleet-metrics que convierte la respuesta JSON del endpoint /healthz de un nodo unibus (membershipd) en series Prometheus (unibus_up, unibus_status_ok, unibus_posture_enforce/acl/tls/cluster, unibus_store_kv) con labels node/instance. Pura de transformación (impure solo por el error de unmarshal). La consume el daemon unibus_exporter del project fleet_monitoring. Con tests golden/edge/error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package infra
|
|
|
|
import "testing"
|
|
|
|
// golden: nodo seguro con la posture homogénea esperada en producción.
|
|
func TestParseUnibusHealthGolden(t *testing.T) {
|
|
body := []byte(`{"posture":{"enforce":true,"acl":true,"tls":true,"cluster":true,"store":"kv"},"status":"ok"}`)
|
|
got, err := ParseUnibusHealth("magnus", body)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
want := map[string]float64{
|
|
"unibus_up": 1,
|
|
"unibus_status_ok": 1,
|
|
"unibus_posture_enforce": 1,
|
|
"unibus_posture_acl": 1,
|
|
"unibus_posture_tls": 1,
|
|
"unibus_posture_cluster": 1,
|
|
"unibus_store_kv": 1,
|
|
}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("got %d samples, want %d", len(got), len(want))
|
|
}
|
|
for _, s := range got {
|
|
w, ok := want[s.Name]
|
|
if !ok {
|
|
t.Errorf("unexpected sample %q", s.Name)
|
|
continue
|
|
}
|
|
if s.Value != w {
|
|
t.Errorf("%s = %v, want %v", s.Name, s.Value, w)
|
|
}
|
|
if s.Labels["node"] != "magnus" || s.Labels["instance"] != "magnus" {
|
|
t.Errorf("%s labels = %v, want node=instance=magnus", s.Name, s.Labels)
|
|
}
|
|
}
|
|
}
|
|
|
|
// edge: nodo degradado (posture todo false, store distinto de kv, status != ok).
|
|
func TestParseUnibusHealthDegraded(t *testing.T) {
|
|
body := []byte(`{"posture":{"enforce":false,"acl":false,"tls":false,"cluster":false,"store":"sqlite"},"status":"degraded"}`)
|
|
got, err := ParseUnibusHealth("homer", body)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
want := map[string]float64{
|
|
"unibus_up": 1,
|
|
"unibus_status_ok": 0,
|
|
"unibus_posture_enforce": 0,
|
|
"unibus_posture_acl": 0,
|
|
"unibus_posture_tls": 0,
|
|
"unibus_posture_cluster": 0,
|
|
"unibus_store_kv": 0,
|
|
}
|
|
for _, s := range got {
|
|
if s.Value != want[s.Name] {
|
|
t.Errorf("%s = %v, want %v", s.Name, s.Value, want[s.Name])
|
|
}
|
|
}
|
|
}
|
|
|
|
// error path: body que no es JSON válido devuelve error, no panic.
|
|
func TestParseUnibusHealthInvalid(t *testing.T) {
|
|
if _, err := ParseUnibusHealth("datardos", []byte("not json at all")); err == nil {
|
|
t.Fatal("expected error for invalid body, got nil")
|
|
}
|
|
}
|