func testLabelsToSignature(t test.Tester) { var scenarios = []struct { in map[string]string out string }{ { in: map[string]string{}, out: "", }, {}, } for i, scenario := range scenarios { actual := LabelsToSignature(scenario.in) if actual != scenario.out { t.Errorf("%d. expected %s, got %s", i, scenario.out, actual) } } }
func testDumpToWriter(t test.Tester) { type input struct { metrics map[string]metrics.Metric } var scenarios = []struct { in input out []byte }{ { out: []byte("[]"), }, { in: input{ metrics: map[string]metrics.Metric{ "foo": metrics.NewCounter(), }, }, out: []byte("[{\"baseLabels\":{\"label_foo\":\"foo\",\"name\":\"foo\"},\"docstring\":\"metric foo\",\"metric\":{\"type\":\"counter\",\"value\":[]}}]"), }, { in: input{ metrics: map[string]metrics.Metric{ "foo": metrics.NewCounter(), "bar": metrics.NewCounter(), }, }, out: []byte("[{\"baseLabels\":{\"label_bar\":\"bar\",\"name\":\"bar\"},\"docstring\":\"metric bar\",\"metric\":{\"type\":\"counter\",\"value\":[]}},{\"baseLabels\":{\"label_foo\":\"foo\",\"name\":\"foo\"},\"docstring\":\"metric foo\",\"metric\":{\"type\":\"counter\",\"value\":[]}}]"), }, } for i, scenario := range scenarios { registry := NewRegistry() for name, metric := range scenario.in.metrics { err := registry.Register(name, fmt.Sprintf("metric %s", name), map[string]string{fmt.Sprintf("label_%s", name): name}, metric) if err != nil { t.Errorf("%d. encountered error while registering metric %s", i, err) } } actual := &bytes.Buffer{} err := registry.dumpToWriter(actual) if err != nil { t.Errorf("%d. encountered error while dumping %s", i, err) } if !bytes.Equal(scenario.out, actual.Bytes()) { t.Errorf("%d. expected %q for dumping, got %q", i, scenario.out, actual.Bytes()) } } }
func testDecorateWriter(t test.Tester) { type input struct { headers map[string]string body []byte } type output struct { headers map[string]string body []byte } var scenarios = []struct { in input out output }{ {}, { in: input{ headers: map[string]string{ "Accept-Encoding": "gzip,deflate,sdch", }, body: []byte("Hi, mom!"), }, out: output{ headers: map[string]string{ "Content-Encoding": "gzip", }, body: []byte("\x1f\x8b\b\x00\x00\tn\x88\x00\xff\xf2\xc8\xd4Q\xc8\xcd\xcfU\x04\x04\x00\x00\xff\xff9C&&\b\x00\x00\x00"), }, }, { in: input{ headers: map[string]string{ "Accept-Encoding": "foo", }, body: []byte("Hi, mom!"), }, out: output{ headers: map[string]string{}, body: []byte("Hi, mom!"), }, }, } for i, scenario := range scenarios { request, _ := http.NewRequest("GET", "/", nil) for key, value := range scenario.in.headers { request.Header.Add(key, value) } baseWriter := &fakeResponseWriter{ header: make(http.Header), } writer := decorateWriter(request, baseWriter) for key, value := range scenario.out.headers { if baseWriter.Header().Get(key) != value { t.Errorf("%d. expected %s for header %s, got %s", i, value, key, baseWriter.Header().Get(key)) } } writer.Write(scenario.in.body) if closer, ok := writer.(io.Closer); ok { closer.Close() } if !bytes.Equal(scenario.out.body, baseWriter.body.Bytes()) { t.Errorf("%d. expected %s for body, got %s", i, scenario.out.body, baseWriter.body.Bytes()) } } }
func testRegister(t test.Tester) { var oldState = struct { abortOnMisuse bool debugRegistration bool useAggressiveSanityChecks bool }{ abortOnMisuse: abortOnMisuse, debugRegistration: debugRegistration, useAggressiveSanityChecks: useAggressiveSanityChecks, } defer func() { abortOnMisuse = oldState.abortOnMisuse debugRegistration = oldState.debugRegistration useAggressiveSanityChecks = oldState.useAggressiveSanityChecks }() type input struct { name string baseLabels map[string]string } var scenarios = []struct { inputs []input outputs []bool }{ {}, { inputs: []input{ { name: "my_name_without_labels", }, }, outputs: []bool{ true, }, }, { inputs: []input{ { name: "my_name_without_labels", }, { name: "another_name_without_labels", }, }, outputs: []bool{ true, true, }, }, { inputs: []input{ { name: "", }, }, outputs: []bool{ false, }, }, { inputs: []input{ { name: "valid_name", baseLabels: map[string]string{"name": "illegal_duplicate_name"}, }, }, outputs: []bool{ false, }, }, { inputs: []input{ { name: "duplicate_names", }, { name: "duplicate_names", }, }, outputs: []bool{ true, false, }, }, { inputs: []input{ { name: "duplicate_names_with_identical_labels", baseLabels: map[string]string{"label": "value"}, }, { name: "duplicate_names_with_identical_labels", baseLabels: map[string]string{"label": "value"}, }, }, outputs: []bool{ true, false, }, }, { inputs: []input{ { name: "duplicate_names_with_dissimilar_labels", baseLabels: map[string]string{"label": "foo"}, }, { name: "duplicate_names_with_dissimilar_labels", baseLabels: map[string]string{"label": "bar"}, }, }, outputs: []bool{ true, false, }, }, } for i, scenario := range scenarios { if len(scenario.inputs) != len(scenario.outputs) { t.Fatalf("%d. len(scenario.inputs) != len(scenario.outputs)") } abortOnMisuse = false debugRegistration = false useAggressiveSanityChecks = true registry := NewRegistry() for j, input := range scenario.inputs { actual := registry.Register(input.name, "", input.baseLabels, nil) if scenario.outputs[j] != (actual == nil) { t.Errorf("%d.%d. expected %s, got %s", i, j, scenario.outputs[j], actual) } } } }
func testCounter(t test.Tester) { type input struct { steps []func(g Counter) } type output struct { value string } var scenarios = []struct { in input out output }{ { in: input{ steps: []func(g Counter){}, }, out: output{ value: "{\"type\":\"counter\",\"value\":[]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(nil, 1) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{},\"value\":1}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{}, 2) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{},\"value\":2}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{}, 3) }, func(g Counter) { g.Set(map[string]string{}, 5) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{},\"value\":5}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{"handler": "/foo"}, 13) }, func(g Counter) { g.Set(map[string]string{"handler": "/bar"}, 17) }, func(g Counter) { g.ResetAll() }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{"handler": "/foo"}, 19) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{\"handler\":\"/foo\"},\"value\":19}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{"handler": "/foo"}, 23) }, func(g Counter) { g.Increment(map[string]string{"handler": "/foo"}) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{\"handler\":\"/foo\"},\"value\":24}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Increment(map[string]string{"handler": "/foo"}) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{\"handler\":\"/foo\"},\"value\":1}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Decrement(map[string]string{"handler": "/foo"}) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{\"handler\":\"/foo\"},\"value\":-1}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{"handler": "/foo"}, 29) }, func(g Counter) { g.Decrement(map[string]string{"handler": "/foo"}) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{\"handler\":\"/foo\"},\"value\":28}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{"handler": "/foo"}, 31) }, func(g Counter) { g.IncrementBy(map[string]string{"handler": "/foo"}, 5) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{\"handler\":\"/foo\"},\"value\":36}]}", }, }, { in: input{ steps: []func(g Counter){ func(g Counter) { g.Set(map[string]string{"handler": "/foo"}, 37) }, func(g Counter) { g.DecrementBy(map[string]string{"handler": "/foo"}, 10) }, }, }, out: output{ value: "{\"type\":\"counter\",\"value\":[{\"labels\":{\"handler\":\"/foo\"},\"value\":27}]}", }, }, } for i, scenario := range scenarios { counter := NewCounter() for _, step := range scenario.in.steps { step(counter) } marshallable := counter.AsMarshallable() bytes, err := json.Marshal(marshallable) if err != nil { t.Errorf("%d. could not marshal into JSON %s", i, err) continue } asString := string(bytes) if scenario.out.value != asString { t.Errorf("%d. expected %q, got %q", i, scenario.out.value, asString) } } }