tsweb: add VarzHandler tests

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2021-08-10 13:38:12 -07:00 committed by Brad Fitzpatrick
parent a4e19f2233
commit 5f45d8f8e6
2 changed files with 108 additions and 1 deletions

View File

@ -424,11 +424,13 @@ funcRet = fmt.Sprintf(" returning %T", v)
}) })
} }
} }
expvar.Do(func(kv expvar.KeyValue) { expvarDo(func(kv expvar.KeyValue) {
dump("", kv) dump("", kv)
}) })
} }
var expvarDo = expvar.Do // pulled out for tests
func writeMemstats(w io.Writer, ms *runtime.MemStats) { func writeMemstats(w io.Writer, ms *runtime.MemStats) {
out := func(name, typ string, v uint64, help string) { out := func(name, typ string, v uint64, help string) {
if help != "" { if help != "" {

View File

@ -8,6 +8,7 @@
"bufio" "bufio"
"context" "context"
"errors" "errors"
"expvar"
"net" "net"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@ -15,6 +16,7 @@
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"tailscale.com/metrics"
"tailscale.com/tstest" "tailscale.com/tstest"
) )
@ -300,3 +302,106 @@ func BenchmarkLog(b *testing.B) {
h.ServeHTTP(rw, req) h.ServeHTTP(rw, req)
} }
} }
func TestVarzHandler(t *testing.T) {
tests := []struct {
name string
k string // key name
v expvar.Var
want string
}{
{
"int",
"foo",
new(expvar.Int),
"# TYPE foo counter\nfoo 0\n",
},
{
"int_with_type_counter",
"counter_foo",
new(expvar.Int),
"# TYPE foo counter\nfoo 0\n",
},
{
"int_with_type_gauge",
"gauge_foo",
new(expvar.Int),
"# TYPE foo gauge\nfoo 0\n",
},
{
"metrics_set",
"s",
&metrics.Set{
Map: *(func() *expvar.Map {
m := new(expvar.Map)
m.Init()
m.Add("foo", 1)
m.Add("bar", 2)
return m
})(),
},
"# TYPE s_bar counter\ns_bar 2\n# TYPE s_foo counter\ns_foo 1\n",
},
{
"metrics_set_TODO_guage_type",
"gauge_s", // TODO(bradfitz): arguably a bug; should pass down type
&metrics.Set{
Map: *(func() *expvar.Map {
m := new(expvar.Map)
m.Init()
m.Add("foo", 1)
m.Add("bar", 2)
return m
})(),
},
"# TYPE s_bar counter\ns_bar 2\n# TYPE s_foo counter\ns_foo 1\n",
},
{
"func_float64",
"counter_x",
expvar.Func(func() interface{} { return float64(1.2) }),
"# TYPE x counter\nx 1.2\n",
},
{
"func_float64_gauge",
"gauge_x",
expvar.Func(func() interface{} { return float64(1.2) }),
"# TYPE x gauge\nx 1.2\n",
},
{
"func_float64_untyped",
"x",
expvar.Func(func() interface{} { return float64(1.2) }),
"# skipping expvar \"x\" (Go type expvar.Func returning float64) with undeclared Prometheus type\n",
},
{
"label_map",
"counter_m",
&metrics.LabelMap{
Label: "label",
Map: *(func() *expvar.Map {
m := new(expvar.Map)
m.Init()
m.Add("foo", 1)
m.Add("bar", 2)
return m
})(),
},
"# TYPE m counter\nm{label=\"bar\"} 2\nm{label=\"foo\"} 1\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() { expvarDo = expvar.Do }()
expvarDo = func(f func(expvar.KeyValue)) {
f(expvar.KeyValue{Key: tt.k, Value: tt.v})
}
rec := httptest.NewRecorder()
VarzHandler(rec, httptest.NewRequest("GET", "/", nil))
if got := rec.Body.Bytes(); string(got) != tt.want {
t.Errorf("mismatch\n got: %q\nwant: %q\n", got, tt.want)
}
})
}
}