From eeede3e6ac248f90b02155a7303f17e42e6f2103 Mon Sep 17 00:00:00 2001 From: Tommy Murphy Date: Mon, 23 Dec 2019 14:43:15 -0500 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=A7=B9=20cleanup=20rpc=20test=20with?= =?UTF-8?q?=20a=20custom=20message=20comparison=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stackdriver_test.go | 91 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/stackdriver_test.go b/stackdriver_test.go index c800c44..24c06f7 100644 --- a/stackdriver_test.go +++ b/stackdriver_test.go @@ -25,7 +25,11 @@ import ( monitoring "cloud.google.com/go/monitoring/apiv3" metrics "github.com/armon/go-metrics" emptypb "github.com/golang/protobuf/ptypes/empty" + "github.com/google/go-cmp/cmp" "google.golang.org/api/option" + distributionpb "google.golang.org/genproto/googleapis/api/distribution" + "google.golang.org/genproto/googleapis/api/metric" + metricpb "google.golang.org/genproto/googleapis/api/metric" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/test/bufconn" @@ -119,11 +123,33 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDistributionValue().BucketCounts[0] == 1 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar", + }, + MetricKind: metric.MetricDescriptor_CUMULATIVE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DistributionValue{ + DistributionValue: &distributionpb.Distribution{ + BucketCounts: []int64{1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + Count: 3, + }, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "bucket 0 count 1", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -363,7 +389,9 @@ func (s *mockMetricServer) CreateTimeSeries(ctx context.Context, req *monitoring // Skips defaults that are not appropriate for tests. func newTestSink(interval time.Duration, client *monitoring.MetricClient) *Sink { s := &Sink{} - s.taskInfo = &taskInfo{} + s.taskInfo = &taskInfo{ + ProjectID: "foo", + } s.interval = interval s.bucketer = DefaultBucketer s.extractor = DefaultLabelExtractor @@ -371,3 +399,56 @@ func newTestSink(interval time.Duration, client *monitoring.MetricClient) *Sink go s.flushMetrics(context.Background()) return s } + +func diffCreateMsg(want, got *monitoringpb.CreateTimeSeriesRequest) string { + out := "" + if want.GetName() != "" && (want.GetName() != got.GetName()) { + out += fmt.Sprintf("Unexpected Name, got: %s, want:%s\n", got.GetName(), want.GetName()) + } + + for i := range want.GetTimeSeries() { + w := want.GetTimeSeries()[i] + g := got.GetTimeSeries()[i] + + if w.GetMetricKind() != g.GetMetricKind() { + out += fmt.Sprintf("Unexpected MetricKind, got: %s, want:%s\n", g.GetMetricKind(), w.GetMetricKind()) + } + + if w.GetMetric().GetType() != g.GetMetric().GetType() { + out += fmt.Sprintf("Unexpected Metric Type, got: %s, want:%s\n", g.GetMetric().GetType(), w.GetMetric().GetType()) + } + + if len(w.GetMetric().GetLabels()) != 0 { + d := cmp.Diff(g.GetMetric().GetLabels(), w.GetMetric().GetLabels()) + if d != "" { + out += fmt.Sprintf("Unexpected metric labels diff:%s \n", d) + } + } + + for j := range w.GetPoints() { + wp := w.GetPoints()[j] + gp := g.GetPoints()[j] + + // TODO: support diffing the start/end times + + // gauge/count + if wp.GetValue().GetDoubleValue() != gp.GetValue().GetDoubleValue() { + out += fmt.Sprintf("Unexpected value (@point %d), got: %v, want:%v\n", j, gp.GetValue().GetDoubleValue(), wp.GetValue().GetDoubleValue()) + } + + // distribution + if wd := wp.GetValue().GetDistributionValue(); wd != nil { + gd := gp.GetValue().GetDistributionValue() + // TODO: support diffing custom buckets + d := cmp.Diff(gd.GetBucketCounts(), wd.GetBucketCounts()) + if d != "" { + out += fmt.Sprintf("Unexpected bucket counts diff (@point %d):%s \n", j, d) + } + if gd.GetCount() != wd.GetCount() { + out += fmt.Sprintf("Unexpected count (@point %d), got: %v, want: %v\n", j, gd.GetCount(), wd.GetCount()) + } + } + } + } + return out +} From 5238c44dde346a36c1d39311bc253a30f29f301c Mon Sep 17 00:00:00 2001 From: Tommy Murphy Date: Mon, 23 Dec 2019 14:45:36 -0500 Subject: [PATCH 2/5] coverage: addSample with a measurement in the largets bucket --- stackdriver_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stackdriver_test.go b/stackdriver_test.go index 24c06f7..c1703bd 100644 --- a/stackdriver_test.go +++ b/stackdriver_test.go @@ -120,6 +120,7 @@ func TestSample(t *testing.T) { ss.AddSample([]string{"foo", "bar"}, 5.0) ss.AddSample([]string{"foo", "bar"}, 100.0) ss.AddSample([]string{"foo", "bar"}, 500.0) + ss.AddSample([]string{"foo", "bar"}, 50000000.0) }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { @@ -136,8 +137,8 @@ func TestSample(t *testing.T) { Value: &monitoringpb.TypedValue{ Value: &monitoringpb.TypedValue_DistributionValue{ DistributionValue: &distributionpb.Distribution{ - BucketCounts: []int64{1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, - Count: 3, + BucketCounts: []int64{1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, + Count: 4, }, }, }, From 4b659b89e549a1ead9cdbdf1c40be82419d44e2b Mon Sep 17 00:00:00 2001 From: Tommy Murphy Date: Mon, 23 Dec 2019 14:57:19 -0500 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=A7=B9=20tests=20use=20the=20new=20co?= =?UTF-8?q?mparison=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stackdriver_test.go | 229 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 196 insertions(+), 33 deletions(-) diff --git a/stackdriver_test.go b/stackdriver_test.go index c1703bd..af3a52e 100644 --- a/stackdriver_test.go +++ b/stackdriver_test.go @@ -106,11 +106,33 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDistributionValue().BucketCounts[0] == 1 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar", + }, + MetricKind: metric.MetricDescriptor_CUMULATIVE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DistributionValue{ + DistributionValue: &distributionpb.Distribution{ + BucketCounts: []int64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Count: 1, + }, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "bucket 0 count 1", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -163,11 +185,33 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDistributionValue().BucketCounts[0] == 3 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar", + }, + MetricKind: metric.MetricDescriptor_CUMULATIVE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DistributionValue{ + DistributionValue: &distributionpb.Distribution{ + BucketCounts: []int64{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Count: 3, + }, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "bucket 0 count 3", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -178,11 +222,30 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDoubleValue() == 1.0 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar_counter", + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 1.0, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "value 1.0", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -195,11 +258,30 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDoubleValue() == 3.0 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar_counter", + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 3.0, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "value 3.0", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -210,11 +292,30 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDoubleValue() == 50.0 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar_gauge", + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 50.0, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "value 50.0", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -227,11 +328,30 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDoubleValue() == 50.0 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar_gauge", + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 50.0, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "value 50.0", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -244,11 +364,30 @@ func TestSample(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - if req.TimeSeries[0].Points[0].Value.GetDoubleValue() == 52.0 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar_gauge", + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 52.0, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "value 52.0", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, @@ -329,12 +468,36 @@ func TestExtract(t *testing.T) { }, createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { - metric := req.TimeSeries[0].GetMetric() - if metric.GetType() == "custom.googleapis.com/go-metrics/foo" && metric.GetLabels()["method"] == "bar" && req.TimeSeries[0].Points[0].Value.GetDistributionValue().BucketCounts[0] == 1 { - return &emptypb.Empty{}, nil + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo", + Labels: map[string]string{ + "method": "bar", + }, + }, + MetricKind: metric.MetricDescriptor_CUMULATIVE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DistributionValue{ + DistributionValue: &distributionpb.Distribution{ + BucketCounts: []int64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Count: 1, + }, + }, + }, + }, + }, + }, + }, } - t.Errorf("unexpected CreateTimeSeriesRequest\nwant: %s\ngot: %v", "bucket 0 count 1", req) - return nil, errors.New("unexpected CreateTimeSeriesRequest") + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil } }, }, From e36aa42a8f6d5900ccb663527cc80e5015bf57a2 Mon Sep 17 00:00:00 2001 From: Tommy Murphy Date: Mon, 23 Dec 2019 15:16:20 -0500 Subject: [PATCH 4/5] coverage: labels and custom label extraction --- stackdriver_test.go | 231 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) diff --git a/stackdriver_test.go b/stackdriver_test.go index af3a52e..894e2c9 100644 --- a/stackdriver_test.go +++ b/stackdriver_test.go @@ -136,6 +136,46 @@ func TestSample(t *testing.T) { } }, }, + { + name: "histogram with label", + collect: func() { + ss.AddSampleWithLabels([]string{"foo", "bar"}, 5.0, []metrics.Label{metrics.Label{Name: "env", Value: "dev"}}) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar", + Labels: map[string]string{ + "env": "dev", + }, + }, + MetricKind: metric.MetricDescriptor_CUMULATIVE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DistributionValue{ + DistributionValue: &distributionpb.Distribution{ + BucketCounts: []int64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Count: 1, + }, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, { name: "hisogram with samples in multiple buckets", collect: func() { @@ -249,6 +289,43 @@ func TestSample(t *testing.T) { } }, }, + { + name: "counter with label", + collect: func() { + ss.IncrCounterWithLabels([]string{"foo", "bar"}, 1.0, []metrics.Label{metrics.Label{Name: "env", Value: "dev"}}) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar_counter", + Labels: map[string]string{ + "env": "dev", + }, + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 1.0, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, { name: "multiple counts", collect: func() { @@ -319,6 +396,43 @@ func TestSample(t *testing.T) { } }, }, + { + name: "gauge with label", + collect: func() { + ss.SetGaugeWithLabels([]string{"foo", "bar"}, 1.0, []metrics.Label{metrics.Label{Name: "env", Value: "dev"}}) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo_bar_gauge", + Labels: map[string]string{ + "env": "dev", + }, + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 1.0, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, { name: "repeated gauge", collect: func() { @@ -501,6 +615,123 @@ func TestExtract(t *testing.T) { } }, }, + { + name: "histogram with label", + collect: func() { + ss.AddSampleWithLabels([]string{"foo", "bar"}, 5.0, []metrics.Label{metrics.Label{Name: "env", Value: "dev"}}) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo", + Labels: map[string]string{ + "env": "dev", + "method": "bar", + }, + }, + MetricKind: metric.MetricDescriptor_CUMULATIVE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DistributionValue{ + DistributionValue: &distributionpb.Distribution{ + BucketCounts: []int64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Count: 1, + }, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, + { + name: "counter with label", + collect: func() { + ss.IncrCounterWithLabels([]string{"foo", "bar"}, 1.0, []metrics.Label{metrics.Label{Name: "env", Value: "dev"}}) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo", + Labels: map[string]string{ + "env": "dev", + "method": "bar", + }, + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 1.0, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, + { + name: "gauge with label", + collect: func() { + ss.SetGaugeWithLabels([]string{"foo", "bar"}, 1.0, []metrics.Label{metrics.Label{Name: "env", Value: "dev"}}) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/foo", + Labels: map[string]string{ + "env": "dev", + "method": "bar", + }, + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 1.0, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, } for _, tc := range tests { From 3d5d4f313fd658ea366cd1161599720f1ca067bf Mon Sep 17 00:00:00 2001 From: Tommy Murphy Date: Mon, 23 Dec 2019 15:36:58 -0500 Subject: [PATCH 5/5] coverage: label extraction returns an error --- stackdriver_test.go | 156 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/stackdriver_test.go b/stackdriver_test.go index 894e2c9..73c1161 100644 --- a/stackdriver_test.go +++ b/stackdriver_test.go @@ -562,6 +562,9 @@ func TestSample(t *testing.T) { func TestExtract(t *testing.T) { ss := newTestSink(0*time.Second, nil) ss.extractor = func(key []string, kind string) ([]string, []metrics.Label, error) { + if len(key) < 2 { + return nil, nil, errors.New("bad extraction") + } return key[:1], []metrics.Label{ { Name: "method", @@ -732,6 +735,159 @@ func TestExtract(t *testing.T) { } }, }, + { + name: "histogram error, no requests", + collect: func() { + ss.AddSample([]string{"foo"}, 5.0) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + t.Errorf("unexpected CreateTimeSeriesRequest") + return &emptypb.Empty{}, nil + } + }, + }, + { + name: "histogram error, metric skipped", + collect: func() { + ss.AddSample([]string{"foo"}, 5.0) + ss.AddSample([]string{"bar", "baz"}, 5.0) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/bar", + Labels: map[string]string{ + "method": "baz", + }, + }, + MetricKind: metric.MetricDescriptor_CUMULATIVE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DistributionValue{ + DistributionValue: &distributionpb.Distribution{ + BucketCounts: []int64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Count: 1, + }, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, + { + name: "counter error, no requests", + collect: func() { + ss.IncrCounter([]string{"foo"}, 5.0) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + t.Errorf("unexpected CreateTimeSeriesRequest") + return &emptypb.Empty{}, nil + } + }, + }, + { + name: "counter error, metric skipped", + collect: func() { + ss.IncrCounter([]string{"foo"}, 5.0) + ss.IncrCounter([]string{"bar", "baz"}, 5.0) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/bar", + Labels: map[string]string{ + "method": "baz", + }, + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 5.0, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, + { + name: "gauge error, no requests", + collect: func() { + ss.SetGauge([]string{"foo"}, 5.0) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + t.Errorf("unexpected CreateTimeSeriesRequest") + return &emptypb.Empty{}, nil + } + }, + }, + { + name: "gauge error, metric skipped", + collect: func() { + ss.SetGauge([]string{"foo"}, 5.0) + ss.SetGauge([]string{"bar", "baz"}, 5.0) + }, + createFn: func(t *testing.T) func(context.Context, *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + return func(_ context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { + want := &monitoringpb.CreateTimeSeriesRequest{ + Name: "projects/foo", + TimeSeries: []*monitoringpb.TimeSeries{ + &monitoringpb.TimeSeries{ + Metric: &metricpb.Metric{ + Type: "custom.googleapis.com/go-metrics/bar", + Labels: map[string]string{ + "method": "baz", + }, + }, + MetricKind: metric.MetricDescriptor_GAUGE, + Points: []*monitoringpb.Point{ + &monitoringpb.Point{ + Value: &monitoringpb.TypedValue{ + Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: 5.0, + }, + }, + }, + }, + }, + }, + } + if diff := diffCreateMsg(want, req); diff != "" { + t.Errorf("unexpected CreateTimeSeriesRequest (-want +got):\n%s", diff) + } + return &emptypb.Empty{}, nil + } + }, + }, } for _, tc := range tests {