micro-meter-victoriametrics/victoriametrics_test.go
Vasiliy Tolstov 1154db66d0 wrapper/monitoring/victoriametrics: align with prometheus metrics
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-01-19 16:29:14 +03:00

147 lines
3.3 KiB
Go

package victoriametrics
import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"strings"
"testing"
metrics "github.com/VictoriaMetrics/metrics"
"github.com/micro/go-micro/v2/client"
"github.com/micro/go-micro/v2/client/selector"
"github.com/micro/go-micro/v2/registry/memory"
"github.com/micro/go-micro/v2/server"
"github.com/stretchr/testify/assert"
)
type Test interface {
Method(ctx context.Context, in *TestRequest, opts ...client.CallOption) (*TestResponse, error)
}
type TestRequest struct {
IsError bool
}
type TestResponse struct{}
type testHandler struct{}
func (t *testHandler) Method(ctx context.Context, req *TestRequest, rsp *TestResponse) error {
if req.IsError {
return fmt.Errorf("test error")
}
return nil
}
func TestVictoriametrics(t *testing.T) {
// setup
registry := memory.NewRegistry()
sel := selector.NewSelector(selector.Registry(registry))
name := "test"
id := "id-1234567890"
version := "1.2.3.4"
c := client.NewClient(client.Selector(sel))
s := server.NewServer(
server.Name(name),
server.Version(version),
server.Id(id),
server.Registry(registry),
server.WrapHandler(
NewHandlerWrapper(
ServiceName(name),
ServiceVersion(version),
ServiceID(id),
),
),
)
defer s.Stop()
type Test struct {
*testHandler
}
s.Handle(
s.NewHandler(&Test{new(testHandler)}),
)
if err := s.Start(); err != nil {
t.Fatalf("Unexpected error starting server: %v", err)
}
req := c.NewRequest(name, "Test.Method", &TestRequest{IsError: false}, client.WithContentType("application/json"))
rsp := TestResponse{}
assert.NoError(t, c.Call(context.TODO(), req, &rsp))
req = c.NewRequest(name, "Test.Method", &TestRequest{IsError: true}, client.WithContentType("application/json"))
assert.Error(t, c.Call(context.TODO(), req, &rsp))
buf := bytes.NewBuffer(nil)
metrics.WritePrometheus(buf, false)
metric, err := findMetricByName(buf, "sum", "micro_request_total")
if err != nil {
t.Fatal(err)
}
labels := metric[0]["labels"].(map[string]string)
for k, v := range labels {
switch k {
case "micro_version":
assert.Equal(t, version, v)
case "micro_id":
assert.Equal(t, id, v)
case "micro_name":
assert.Equal(t, name, v)
case "micro_endpoint":
assert.Equal(t, "Test.Method", v)
case "micro_status":
continue
default:
t.Fatalf("unknown %v with %v", k, v)
}
}
}
func findMetricByName(buf io.Reader, tp string, name string) ([]map[string]interface{}, error) {
var metrics []map[string]interface{}
scanner := bufio.NewScanner(buf)
for scanner.Scan() {
txt := scanner.Text()
if strings.HasPrefix(txt, name) {
mt := make(map[string]interface{})
v := txt[strings.LastIndex(txt, " "):]
k := ""
if idx := strings.Index(txt, "{"); idx > 0 {
labels := make(map[string]string)
lb := strings.Split(txt[idx+1:strings.Index(txt, "}")], ",")
for _, l := range lb {
p := strings.Split(l, "=")
labels[strings.Trim(p[0], `"`)] = strings.Trim(p[1], `"`)
}
mt["labels"] = labels
k = txt[:idx]
} else {
k = txt[:strings.Index(txt, " ")]
}
mt["name"] = k
mt["value"] = v
metrics = append(metrics, mt)
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
if len(metrics) == 0 {
return nil, fmt.Errorf("%s %s not found", tp, name)
}
return metrics, nil
}