Files
jbergner a6bc71fb3a
Some checks failed
release-tag / Resolve release metadata (push) Successful in 30s
release-tag / Build knowledge (push) Failing after 4m51s
release-tag / Build control (push) Failing after 5m0s
release-tag / Build agent (push) Failing after 5m0s
release-tag / Build agent-data-init (push) Failing after 5m5s
release-tag / Build neuroforge-worker (push) Failing after 5m7s
release-tag / Build neuroforge (push) Failing after 5m9s
Init
2026-08-26 18:34:41 +02:00

78 lines
2.3 KiB
Go

package httpapi
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"neuroforge/internal/brain"
"neuroforge/internal/cost"
"neuroforge/internal/provider"
"neuroforge/internal/store"
)
func newMetricsTestServer(t *testing.T) (*Server, string) {
t.Helper()
s, err := store.New(t.TempDir())
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = s.Close() })
r := provider.NewRouter(s)
c := cost.New(s)
b := brain.New(s, r, c)
return New(s, b, r, c), s.Secrets().MetricsToken
}
func TestMetricsEndpointRequiresBearerToken(t *testing.T) {
s, token := newMetricsTestServer(t)
if token == "" {
t.Fatal("metrics token was not generated")
}
req := httptest.NewRequest(http.MethodGet, "/metrics", nil)
rr := httptest.NewRecorder()
s.Handler().ServeHTTP(rr, req)
if rr.Code != http.StatusUnauthorized {
t.Fatalf("unauthorized status=%d body=%s", rr.Code, rr.Body.String())
}
}
func TestMetricsEndpointExportsNormalizedHTTPMetrics(t *testing.T) {
s, token := newMetricsTestServer(t)
// Generate one instrumented request before scraping.
health := httptest.NewRequest(http.MethodGet, "/healthz", nil)
healthRR := httptest.NewRecorder()
s.Handler().ServeHTTP(healthRR, health)
if healthRR.Code != http.StatusOK {
t.Fatalf("health status=%d", healthRR.Code)
}
req := httptest.NewRequest(http.MethodGet, "/metrics", nil)
req.Header.Set("Authorization", "Bearer "+token)
rr := httptest.NewRecorder()
s.Handler().ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("metrics status=%d body=%s", rr.Code, rr.Body.String())
}
if got := rr.Header().Get("Content-Type"); !strings.Contains(got, "text/plain") || !strings.Contains(got, "version=0.0.4") {
t.Fatalf("unexpected content type %q", got)
}
body := rr.Body.String()
for _, want := range []string{
"# TYPE neuroforge_memories gauge",
"neuroforge_up 1",
"neuroforge_http_requests_total{method=\"GET\",route=\"/healthz\",code=\"200\"} 1",
"neuroforge_http_request_duration_seconds_bucket{method=\"GET\",route=\"/healthz\",le=\"+Inf\"} 1",
"neuroforge_page_cache_hits_total",
"neuroforge_openai_budget_usd",
"neuroforge_vector_journal_compression_savings_percent",
"neuroforge_vector_journal_sqar_blocks",
} {
if !strings.Contains(body, want) {
t.Fatalf("metrics output missing %q\n%s", want, body)
}
}
}