mirror of
https://github.com/luxfi/metric.git
synced 2026-10-30 16:19:50 +00:00
Handler binds DefaultGatherer, which reads DefaultRegistry — the registry the package-level constructors (NewCounter, NewGaugeVec and their siblings) register into. A process that records through those helpers and serves Handler now scrapes back what it recorded, naming a registry at neither end, which is what the function's documentation describes. A caller keeping its own registry names it with HandlerFor. TestHandlerExposesWhatThePackageConstructorsRecord drives that zero-config path and reads the value back off the exposition bytes: an empty scrape is a well-formed 200, so nothing about the answer reveals which registry the handler holds and only the bytes can say.
53 lines
2.0 KiB
Go
53 lines
2.0 KiB
Go
// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package metric
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// [Handler] is the zero-configuration exposition: a caller records through the
|
|
// package-level constructors and serves it, naming a registry at neither end.
|
|
// That only works while the two ends name the SAME registry, and nothing about a
|
|
// handler's own answer reveals which one it holds — an empty scrape is a
|
|
// well-formed 200. So this records a value and reads it back off the bytes.
|
|
func TestHandlerExposesWhatThePackageConstructorsRecord(t *testing.T) {
|
|
const name = "handler_default_probe"
|
|
|
|
g := NewGaugeVec(GaugeOpts{Name: name, Help: "a value recorded through the package helpers"}, []string{"lane"})
|
|
g.WithLabelValues("one").Set(7)
|
|
|
|
rec := httptest.NewRecorder()
|
|
Handler().ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/metrics", nil))
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want 200", rec.Code)
|
|
}
|
|
body := rec.Body.String()
|
|
if body == "" {
|
|
t.Fatal("the exposition is empty; Handler is reading a registry nothing records into")
|
|
}
|
|
if !strings.Contains(body, name) {
|
|
t.Fatalf("the exposition does not carry %q; Handler and NewGaugeVec disagree about the registry.\n%s", name, body)
|
|
}
|
|
if !strings.Contains(body, name+`{lane="one"} 7`) {
|
|
t.Fatalf("%s is named but does not carry the value that was set.\n%s", name, body)
|
|
}
|
|
}
|
|
|
|
// The two names for the default registry are one registry. Holding them apart
|
|
// would let the constructors write where the exposition does not read, which is
|
|
// the whole failure above with nothing on the wire to show for it.
|
|
func TestTheDefaultGathererIsTheDefaultRegistry(t *testing.T) {
|
|
if DefaultGatherer != Gatherer(DefaultRegistry) {
|
|
t.Fatal("DefaultGatherer does not read DefaultRegistry")
|
|
}
|
|
if DefaultRegisterer != Registerer(DefaultRegistry) {
|
|
t.Fatal("DefaultRegisterer does not write DefaultRegistry")
|
|
}
|
|
}
|