Repository: go-kratos/kratos
Pull request #2182 (2022-07-10 09:34:55)

test(contrib): add unit test for contrib/metrics/prometheus
Description (what this PR does / why we need it):
add unit test for contrib/metrics/prometheus

Which issue(s) this PR fixes (resolves / be part of):
part of #2135 

codecov-commenter: # [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2182?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
> Merging [#2182](https://codecov.io/gh/go-kratos/kratos/pull/2182?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (d8ca94f) into [main](https://codecov.io/gh/go-kratos/kratos/commit/102391165ea850064b7e9adf57192441686c2fad?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (1023911) will **decrease** coverage by `0.11%`.
> The diff coverage is `n/a`.

```diff
@@            Coverage Diff             @@
##             main    #2182      +/-   ##
==========================================
- Coverage   82.28%   82.17%   -0.12%     
==========================================
  Files          86       86              
  Lines        3743     3747       +4     
==========================================
- Hits         3080     3079       -1     
- Misses        477      482       +5     
  Partials      186      186              
```


| [Impacted Files](https://codecov.io/gh/go-kratos/kratos/pull/2182?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) | Coverage Δ | |
|---|---|---|
| [internal/context/context.go](https://codecov.io/gh/go-kratos/kratos/pull/2182/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-aW50ZXJuYWwvY29udGV4dC9jb250ZXh0Lmdv) | `97.01% <0.00%> (-2.99%)` | :arrow_down: |
| [transport/http/server.go](https://codecov.io/gh/go-kratos/kratos/pull/2182/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2h0dHAvc2VydmVyLmdv) | `76.98% <0.00%> (-1.25%)` | :arrow_down: |
| [transport/grpc/server.go](https://codecov.io/gh/go-kratos/kratos/pull/2182/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2dycGMvc2VydmVyLmdv) | `86.51% <0.00%> (-0.99%)` | :arrow_down: |
| [transport/grpc/interceptor.go](https://codecov.io/gh/go-kratos/kratos/pull/2182/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2dycGMvaW50ZXJjZXB0b3IuZ28=) | `53.19% <0.00%> (+1.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2182?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2182?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Last update [1023911...d8ca94f](https://codecov.io/gh/go-kratos/kratos/pull/2182?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).


Patch:
diff --git a/contrib/metrics/prometheus/go.mod b/contrib/metrics/prometheus/go.mod
index 8c6f24aa..fff4b0ab 100644
--- a/contrib/metrics/prometheus/go.mod
+++ b/contrib/metrics/prometheus/go.mod
@@ -5,6 +5,7 @@ go 1.16
 require (
 	github.com/go-kratos/kratos/v2 v2.3.1
 	github.com/prometheus/client_golang v1.12.2
+	github.com/prometheus/common v0.32.1
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../


Test patch:
diff --git a/contrib/metrics/prometheus/counter_test.go b/contrib/metrics/prometheus/counter_test.go
new file mode 100644
index 00000000..f84b5253
--- /dev/null
+++ b/contrib/metrics/prometheus/counter_test.go
@@ -0,0 +1,65 @@
+package prometheus
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+
+	"github.com/prometheus/client_golang/prometheus"
+	"github.com/prometheus/common/expfmt"
+)
+
+func gatherLatest(reg *prometheus.Registry) (result string, err error) {
+	mfs, err := reg.Gather()
+	if err != nil {
+		return "", err
+	}
+	buf := &bytes.Buffer{}
+
+	enc := expfmt.NewEncoder(buf, expfmt.FmtText)
+	for _, mf := range mfs {
+		if err = enc.Encode(mf); err != nil {
+			return "", err
+		}
+	}
+	return buf.String(), nil
+}
+
+func TestCounter(t *testing.T) {
+	expect := `# HELP test_request_test_metric test
+# TYPE test_request_test_metric counter
+test_request_test_metric{code="test",kind="test",operation="test",reason="test"} %d
+`
+
+	counterVec := prometheus.NewCounterVec(prometheus.CounterOpts{
+		Namespace: "test",
+		Name:      "test_metric",
+		Subsystem: "request",
+		Help:      "test",
+	}, []string{"kind", "operation", "code", "reason"})
+
+	counter := NewCounter(counterVec)
+	counter.With("test", "test", "test", "test").Inc()
+
+	reg := prometheus.NewRegistry()
+	reg.MustRegister(counterVec)
+
+	result, err := gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if result != fmt.Sprintf(expect, 1) {
+		t.Fatal("metrics error")
+	}
+
+	counter.With("test", "test", "test", "test").Add(10)
+	result, err = gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if result != fmt.Sprintf(expect, 11) {
+		t.Fatal("metrics error")
+	}
+}
diff --git a/contrib/metrics/prometheus/gauge_test.go b/contrib/metrics/prometheus/gauge_test.go
new file mode 100644
index 00000000..31744a5a
--- /dev/null
+++ b/contrib/metrics/prometheus/gauge_test.go
@@ -0,0 +1,55 @@
+package prometheus
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/prometheus/client_golang/prometheus"
+)
+
+func TestGuage(t *testing.T) {
+	expect := `# HELP test_request_test_guage_metric test
+# TYPE test_request_test_guage_metric gauge
+test_request_test_guage_metric{code="test",kind="test",operation="test",reason="test"} %d
+`
+
+	guageVec := prometheus.NewGaugeVec(prometheus.GaugeOpts{
+		Namespace: "test",
+		Name:      "test_guage_metric",
+		Subsystem: "request",
+		Help:      "test",
+	}, []string{"kind", "operation", "code", "reason"})
+
+	guage := NewGauge(guageVec)
+	guage.With("test", "test", "test", "test").Set(1)
+
+	reg := prometheus.NewRegistry()
+	reg.MustRegister(guageVec)
+
+	result, err := gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if result != fmt.Sprintf(expect, 1) {
+		t.Fatal("metrics error")
+	}
+
+	guage.With("test", "test", "test", "test").Add(1)
+	result, err = gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if result != fmt.Sprintf(expect, 2) {
+		t.Fatal("metrics error")
+	}
+
+	guage.With("test", "test", "test", "test").Sub(1)
+	result, err = gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if result != fmt.Sprintf(expect, 1) {
+		t.Fatal("metrics error")
+	}
+}
diff --git a/contrib/metrics/prometheus/histogram_test.go b/contrib/metrics/prometheus/histogram_test.go
new file mode 100644
index 00000000..7f2a511d
--- /dev/null
+++ b/contrib/metrics/prometheus/histogram_test.go
@@ -0,0 +1,77 @@
+package prometheus
+
+import (
+	"fmt"
+	"strconv"
+	"testing"
+
+	"github.com/prometheus/client_golang/prometheus"
+)
+
+func intToFloatString(in int) string {
+	return strconv.FormatFloat(float64(in), 'f', -1, 64)
+}
+
+func TestHistogram(t *testing.T) {
+	expect := `# HELP test_request_test_metrics test
+# TYPE test_request_test_metrics histogram
+test_request_test_metrics_bucket{code="test",kind="test",operation="test",reason="test",le="0.05"} %s
+test_request_test_metrics_bucket{code="test",kind="test",operation="test",reason="test",le="0.1"} %s
+test_request_test_metrics_bucket{code="test",kind="test",operation="test",reason="test",le="0.25"} %s
+test_request_test_metrics_bucket{code="test",kind="test",operation="test",reason="test",le="0.5"} %s
+test_request_test_metrics_bucket{code="test",kind="test",operation="test",reason="test",le="1"} %s
+test_request_test_metrics_bucket{code="test",kind="test",operation="test",reason="test",le="+Inf"} %s
+test_request_test_metrics_sum{code="test",kind="test",operation="test",reason="test"} %s
+test_request_test_metrics_count{code="test",kind="test",operation="test",reason="test"} %s
+`
+
+	histogramVec := prometheus.NewHistogramVec(prometheus.HistogramOpts{
+		Namespace: "test",
+		Name:      "test_metrics",
+		Subsystem: "request",
+		Help:      "test",
+		Buckets:   []float64{0.05, 0.1, 0.250, 0.5, 1},
+	}, []string{"kind", "operation", "code", "reason"})
+
+	histogram := NewHistogram(histogramVec)
+	histogram.With("test", "test", "test", "test").Observe(0.5)
+
+	reg := prometheus.NewRegistry()
+	reg.MustRegister(histogramVec)
+
+	result, err := gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if result != fmt.Sprintf(expect,
+		intToFloatString(0),
+		intToFloatString(0),
+		intToFloatString(0),
+		intToFloatString(1),
+		intToFloatString(1),
+		intToFloatString(1),
+		"0.5",
+		intToFloatString(1)) {
+		t.Fatal("metrics error")
+	}
+
+	histogram.With("test", "test", "test", "test").Observe(0.1)
+	result, err = gatherLatest(reg)
+
+	if err != nil {
+		t.Fatal(err)
+	}
+	if result != fmt.Sprintf(expect,
+		intToFloatString(0),
+		intToFloatString(1),
+		intToFloatString(1),
+		intToFloatString(2),
+		intToFloatString(2),
+		intToFloatString(2),
+		"0.6",
+		intToFloatString(2),
+	) {
+		t.Fatal("metrics error")
+	}
+}
diff --git a/contrib/metrics/prometheus/summary_test.go b/contrib/metrics/prometheus/summary_test.go
new file mode 100644
index 00000000..3c93ae94
--- /dev/null
+++ b/contrib/metrics/prometheus/summary_test.go
@@ -0,0 +1,47 @@
+package prometheus
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/prometheus/client_golang/prometheus"
+)
+
+func TestSummary(t *testing.T) {
+	expect := `# HELP test_request_test_metric test
+# TYPE test_request_test_metric summary
+test_request_test_metric_sum{code="test",kind="test",operation="test",reason="test"} %s
+test_request_test_metric_count{code="test",kind="test",operation="test",reason="test"} %s
+`
+
+	summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
+		Namespace: "test",
+		Name:      "test_metric",
+		Subsystem: "request",
+		Help:      "test",
+	}, []string{"kind", "operation", "code", "reason"})
+
+	summary := NewSummary(summaryVec)
+	summary.With("test", "test", "test", "test").Observe(1)
+
+	reg := prometheus.NewRegistry()
+	reg.MustRegister(summaryVec)
+	result, err := gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if result != fmt.Sprintf(expect, intToFloatString(1), intToFloatString(1)) {
+		t.Fatal("metrics error")
+	}
+	summary.With("test", "test", "test", "test").Observe(10)
+
+	result, err = gatherLatest(reg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if result != fmt.Sprintf(expect, intToFloatString(11), intToFloatString(2)) {
+		t.Fatal("metrics error")
+	}
+}