This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package observability
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestRegistryUsesBoundedRouteAndStatusLabels(t *testing.T) {
|
||||
registry := NewRegistry(time.Unix(100, 0))
|
||||
registry.ObserveRequest(http.MethodGet, "/api/v1/entities/secret-id", http.StatusNotFound, 25*time.Millisecond)
|
||||
registry.ObserveRequest(http.MethodGet, "/api/v1/entities/another-id", http.StatusNotFound, 10*time.Millisecond)
|
||||
exposition := registry.Exposition(time.Unix(101, 0))
|
||||
if !strings.Contains(exposition, `route="api_other"`) {
|
||||
t.Fatalf("expected bounded api route labels, got %s", exposition)
|
||||
}
|
||||
if strings.Contains(exposition, "secret-id") || strings.Contains(exposition, "another-id") {
|
||||
t.Fatalf("request path leaked into metrics: %s", exposition)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricsHandlerIsBoundedAndDeterministic(t *testing.T) {
|
||||
registry := NewRegistry(time.Unix(100, 0))
|
||||
registry.SetGauge("pulse_database_ready", 1)
|
||||
registry.ObserveRequest(http.MethodGet, "/healthz", http.StatusOK, time.Second)
|
||||
handler := registry.Handler()
|
||||
request := httptest.NewRequest(http.MethodGet, "/api/v1/system/metrics", nil)
|
||||
first := httptest.NewRecorder()
|
||||
handler.ServeHTTP(first, request)
|
||||
if first.Code != http.StatusOK || first.Header().Get("Content-Type") == "" {
|
||||
t.Fatalf("unexpected metrics response: %d %s", first.Code, first.Body.String())
|
||||
}
|
||||
if !strings.Contains(first.Body.String(), "pulse_http_requests_total") || !strings.Contains(first.Body.String(), "pulse_database_ready 1") {
|
||||
t.Fatalf("missing expected metrics: %s", first.Body.String())
|
||||
}
|
||||
second := httptest.NewRecorder()
|
||||
handler.ServeHTTP(second, httptest.NewRequest(http.MethodGet, "/api/v1/system/metrics", nil))
|
||||
if first.Body.String() == second.Body.String() {
|
||||
t.Fatalf("scrape counter did not change between scrapes")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegistryCapsUnexpectedSeries(t *testing.T) {
|
||||
registry := NewRegistry(time.Unix(100, 0))
|
||||
methods := []string{http.MethodGet, http.MethodHead, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete, http.MethodOptions}
|
||||
paths := []string{"/healthz", "/readyz", "/auth/test-login", "/session/logout", "/api/v1/system/status", "/api/v1/system/metrics", "/api/v1/system/diagnostics", "/api/v1/metrics/query", "/api/v1/live"}
|
||||
for index := 0; index < 500; index++ {
|
||||
registry.ObserveRequest(methods[index%len(methods)], paths[index%len(paths)], 200+(index%5)*100, time.Millisecond)
|
||||
}
|
||||
if got := strings.Count(registry.Exposition(time.Unix(101, 0)), "pulse_http_requests_total{"); got > maxRequestSeries {
|
||||
t.Fatalf("request series = %d, want at most %d", got, maxRequestSeries)
|
||||
}
|
||||
}
|
||||
func TestMetricsMiddlewareRecordsImplicitStatus(t *testing.T) {
|
||||
registry := NewRegistry(time.Unix(100, 0))
|
||||
handler := Middleware(registry, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("ok")) }))
|
||||
handler.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/healthz", nil))
|
||||
if !strings.Contains(registry.Exposition(time.Unix(101, 0)), `status_class="2xx"`) {
|
||||
t.Fatal("implicit 200 response was not measured")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user