package metrics import ( "testing" "time" "github.com/prometheus/client_golang/prometheus" outcomeDomain "proxy-pool/internal/domain/outcome" proxyDomain "proxy-pool/internal/domain/proxy" ) func TestGatewayCollectorRecordsOnlyFixedDimensions(t *testing.T) { registry := prometheus.NewRegistry() collector, err := NewGatewayCollector(registry) if err != nil { t.Fatalf("NewGatewayCollector() = %v", err) } collector.Observe(outcomeDomain.Event{Stage: outcomeDomain.StageDial, Success: true}) collector.Observe(outcomeDomain.Event{Stage: outcomeDomain.StageTunnel, Success: false}) collector.Observe(outcomeDomain.Event{Stage: outcomeDomain.StageUnspecified, Success: true}) collector.ObserveDropped() collector.ObserveCapacityInvariant(proxyDomain.CapacityInvariant{ Violation: proxyDomain.CapacityInvariantReleaseFinished, }) collector.ObserveCapacityInvariant(proxyDomain.CapacityInvariant{Violation: "unknown"}) collector.ObserveRequestStarted("HTTP") collector.ObserveRequestStarted("CONNECT") collector.ObserveRequestFinished("HTTP") collector.ObserveRequestFinished("CONNECT") collector.ObserveRequestDuration("HTTP", 25*time.Millisecond) collector.ObserveRequestDuration("CONNECT", 2*time.Second) collector.ObserveRequestDuration("unknown", time.Second) collector.ObserveTunnelOpened() collector.ObserveTunnelClosed() collector.ObserveRequestStarted("unknown") assertMetricValue(t, registry, "proxy_pool_gateway_outcomes_total", map[string]string{ "stage": "DIAL", "result": "success", }, 1) assertMetricValue(t, registry, "proxy_pool_gateway_outcomes_total", map[string]string{ "stage": "TUNNEL", "result": "failure", }, 1) assertMetricValue(t, registry, "proxy_pool_gateway_outcome_queue_dropped_total", nil, 1) assertMetricValue(t, registry, "proxy_pool_gateway_capacity_invariant_violations_total", map[string]string{ "operation": "release_finished", }, 1) assertMetricValue(t, registry, "proxy_pool_gateway_requests_total", map[string]string{ "protocol": "HTTP", }, 1) assertMetricValue(t, registry, "proxy_pool_gateway_requests_total", map[string]string{ "protocol": "CONNECT", }, 1) assertMetricValue(t, registry, "proxy_pool_gateway_requests_in_flight", map[string]string{ "protocol": "HTTP", }, 0) assertMetricValue(t, registry, "proxy_pool_gateway_requests_in_flight", map[string]string{ "protocol": "CONNECT", }, 0) assertMetricValue(t, registry, "proxy_pool_gateway_active_tunnels", nil, 0) assertHistogramSampleCount(t, registry, "proxy_pool_gateway_request_duration_seconds", map[string]string{"protocol": "HTTP"}, 1) assertHistogramSampleCount(t, registry, "proxy_pool_gateway_request_duration_seconds", map[string]string{"protocol": "CONNECT"}, 1) } func TestNewGatewayCollectorReusesRegisteredCollectors(t *testing.T) { registry := prometheus.NewRegistry() first, err := NewGatewayCollector(registry) if err != nil { t.Fatalf("first NewGatewayCollector() = %v", err) } second, err := NewGatewayCollector(registry) if err != nil { t.Fatalf("second NewGatewayCollector() = %v", err) } first.ObserveDropped() second.ObserveDropped() assertMetricValue(t, registry, "proxy_pool_gateway_outcome_queue_dropped_total", nil, 2) } func assertHistogramSampleCount(t *testing.T, registry *prometheus.Registry, name string, labels map[string]string, want uint64) { t.Helper() metrics, err := registry.Gather() if err != nil { t.Fatalf("Gather() = %v", err) } for _, family := range metrics { if family.GetName() != name { continue } for _, metric := range family.GetMetric() { if metricLabelsMatch(metric.GetLabel(), labels) && metric.GetHistogram().GetSampleCount() == want { return } } } t.Fatalf("histogram %s labels=%v count=%d was not found", name, labels, want) }