package metrics import ( "net/http/httptest" "strings" "testing" "time" "github.com/prometheus/client_golang/prometheus/testutil" ) func TestMetricsRecord(t *testing.T) { m := New() m.ObserveCheck("drift", 100*time.Millisecond) m.ObserveCheck("in_sync", 50*time.Millisecond) m.IncNotification("telegram", "ok") m.SetDrift(3) if got := testutil.ToFloat64(m.ChecksTotal.WithLabelValues("drift")); got != 1 { t.Fatalf("checks drift = %v", got) } if got := testutil.ToFloat64(m.DriftDomains); got != 3 { t.Fatalf("drift gauge = %v", got) } if got := testutil.ToFloat64(m.NotificationsTotal.WithLabelValues("telegram", "ok")); got != 1 { t.Fatalf("notif = %v", got) } } func TestCheckDurationUsesNetworkCallBuckets(t *testing.T) { m := New() m.ObserveCheck("in_sync", 100*time.Millisecond) rec := httptest.NewRecorder() m.Handler().ServeHTTP(rec, httptest.NewRequest("GET", "/metrics", nil)) body := rec.Body.String() // DefBuckets (le="0.005", ...) is tuned for sub-10ms in-process calls; // dns_ar_check_duration_seconds is a network call to a DNS provider, so // it must use the wider explicit buckets instead. for _, want := range []string{`le="0.05"`, `le="1"`, `le="30"`} { if !strings.Contains(body, `dns_ar_check_duration_seconds_bucket{`+want) { t.Fatalf("expected bucket %s in exposed metrics:\n%s", want, body) } } if strings.Contains(body, `dns_ar_check_duration_seconds_bucket{le="0.005"`) { t.Fatalf("found default histogram bucket 0.005, expected custom buckets:\n%s", body) } } func TestHandlerExposesMetrics(t *testing.T) { m := New() m.ObserveCheck("in_sync", time.Millisecond) rec := httptest.NewRecorder() m.Handler().ServeHTTP(rec, httptest.NewRequest("GET", "/metrics", nil)) if rec.Code != 200 || !strings.Contains(rec.Body.String(), "dns_ar_checks_total") { t.Fatalf("metrics not exposed: %d", rec.Code) } }