package allocator import ( "net/http" "net/http/httptest" "strings" "testing" ) func TestMetricsExportsFixedRegionalCounters(t *testing.T) { metrics := NewMetrics() metrics.ObserveAttempt("EU") metrics.ObserveSuccess("EU") metrics.ObserveFailure("EU") metrics.ObserveDenied("EU") metrics.ObserveAttempt("APAC") var output strings.Builder if err := metrics.WritePrometheus(&output); err != nil { t.Fatal(err) } text := output.String() for _, fragment := range []string{ `cosmic_clash_allocator_allocation_attempts_total{region="EU"} 1`, `cosmic_clash_allocator_allocations_total{region="EU"} 1`, `cosmic_clash_allocator_allocation_failures_total{region="EU"} 1`, `cosmic_clash_allocator_quota_denials_total{region="EU"} 1`, `region="NA"`, } { if !strings.Contains(text, fragment) { t.Fatalf("metrics missing %q: %s", fragment, text) } } if strings.Contains(text, "APAC") { t.Fatal("unbounded region label escaped into metrics") } } func TestNilMetricsAreSafe(t *testing.T) { var metrics *Metrics metrics.ObserveAttempt("EU") if err := metrics.WritePrometheus(&strings.Builder{}); err != nil { t.Fatal(err) } } func TestMetricsHandlerIsReadOnlyAndScoped(t *testing.T) { metrics := NewMetrics() metrics.ObserveAttempt("NA") handler := MetricsHandler(metrics) get := httptest.NewRecorder() handler.ServeHTTP(get, httptest.NewRequest(http.MethodGet, "/metrics", nil)) if get.Code != http.StatusOK || !strings.Contains(get.Body.String(), `region="NA"`) { t.Fatalf("GET /metrics status=%d body=%s", get.Code, get.Body.String()) } post := httptest.NewRecorder() handler.ServeHTTP(post, httptest.NewRequest(http.MethodPost, "/metrics", nil)) if post.Code != http.StatusMethodNotAllowed { t.Fatalf("POST /metrics status=%d, want 405", post.Code) } }