package checker import ( "encoding/json" "testing" "time" sdk "git.happydns.org/checker-sdk-go/checker" ) func TestExtractMetrics(t *testing.T) { key := "ex./A" soaKey := "ex./SOA" data := &ResolverPropagationData{ Zone: "ex.", Names: []string{"ex."}, Types: []string{"A", "SOA"}, RunDurationMs: 1234, DeclaredSerial: 100, Resolvers: map[string]*ResolverView{ "a": mkResolver("a", "eu", false, true, map[string]*RRProbe{ key: {Rcode: "NOERROR", Signature: "1.1.1.1", LatencyMs: 50, Transport: TransportUDP}, soaKey: {Rcode: "NOERROR", Records: []string{"ns.ex. hm.ex. 100 3600 600 86400 300"}, LatencyMs: 50, Transport: TransportUDP}, }), "b": mkResolver("b", "eu", false, false, map[string]*RRProbe{ key: {Error: "timeout", Transport: TransportUDP}, soaKey: {Rcode: "NOERROR", Records: []string{"ns.ex. hm.ex. 90 3600 600 86400 300"}, LatencyMs: 80, Transport: TransportUDP}, }), }, RRsets: map[string]*RRsetView{ key: {Name: "ex.", Type: "A"}, soaKey: {Name: "ex.", Type: "SOA"}, }, Stats: Stats{ TotalResolvers: 2, ReachableResolvers: 1, CountriesCovered: 1, }, } raw, err := json.Marshal(data) if err != nil { t.Fatalf("marshal: %v", err) } states := []sdk.CheckState{ {Status: sdk.StatusCrit, Code: "x"}, {Status: sdk.StatusWarn, Code: "y"}, {Status: sdk.StatusInfo, Code: "z"}, {Status: sdk.StatusInfo, Code: "z2"}, } ctx := sdk.NewReportContext(raw, nil, states) prov := &resolverPropagationProvider{} metrics, err := prov.ExtractMetrics(ctx, time.Unix(0, 0)) if err != nil { t.Fatalf("ExtractMetrics: %v", err) } want := map[string]float64{ "resolver_propagation_resolvers_total": 2, "resolver_propagation_resolvers_reachable": 1, "resolver_propagation_run_duration_ms": 1234, "resolver_propagation_declared_serial": 100, "resolver_propagation_serial_drift_resolvers": 1, } got := map[string]float64{} for _, m := range metrics { // Keep the first sample per name (most are zone-only labels). if _, ok := got[m.Name]; !ok { got[m.Name] = m.Value } } for name, v := range want { if got[name] != v { t.Errorf("metric %s = %v, want %v", name, got[name], v) } } // resolver_up should appear once per resolver. var ups int for _, m := range metrics { if m.Name == "resolver_propagation_resolver_up" { ups++ } } if ups != 2 { t.Errorf("resolver_up samples = %d, want 2", ups) } } func TestExtractMetrics_BadPayload(t *testing.T) { ctx := sdk.StaticReportContext(json.RawMessage(`not-json`)) prov := &resolverPropagationProvider{} if _, err := prov.ExtractMetrics(ctx, time.Now()); err == nil { t.Errorf("want decode error") } }