Public source validation / validate (push) Failing after 3m8s
64 lines
3.0 KiB
Go
64 lines
3.0 KiB
Go
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")
|
|
}
|
|
}
|