Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 2fdcf7b

Browse files
bogdandrutusongy23
authored andcommitted
Reproduce bug in stackdriver exporter. (#199)
* Reproduce bug in stackdriver exporter. * Update test. * Fix more tests, remove unnecessary time helper
1 parent b5c7a2c commit 2fdcf7b

6 files changed

+202
-23
lines changed

equivalence_test.go

-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ import (
3737
)
3838

3939
func TestStatsAndMetricsEquivalence(t *testing.T) {
40-
_, _, stop := createFakeServer(t)
41-
defer stop()
42-
4340
startTime := time.Unix(1000, 0)
4441
startTimePb := &timestamp.Timestamp{Seconds: 1000}
4542
md := metricdata.Descriptor{

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ require (
55
github.com/aws/aws-sdk-go v1.22.1
66
github.com/census-instrumentation/opencensus-proto v0.2.1
77
github.com/davecgh/go-spew v1.1.1 // indirect
8+
github.com/gogo/protobuf v1.3.0
89
github.com/golang/protobuf v1.3.2
910
github.com/google/addlicense v0.0.0-20190510175307-22550fa7c1b0 // indirect
1011
github.com/google/go-cmp v0.3.1

go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
1818
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1919
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2020
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
21+
github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
22+
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
2123
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
2224
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
2325
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -42,6 +44,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
4244
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
4345
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
4446
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
47+
github.com/google/protobuf v3.9.1+incompatible h1:8oCWqzcHmpI7oK4A2LT3qpYu6SEFRFDECpCtpCWumDU=
4548
github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc=
4649
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
4750
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
@@ -56,6 +59,8 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i
5659
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
5760
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc=
5861
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
62+
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
63+
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
5964
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6065
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6166
github.com/rakyll/embedmd v0.0.0-20171029212350-c8060a0752a2 h1:1jfy6i1g66ijpffgfaF/7pIFYZnSZzvo9P9DFkFmRIM=
@@ -126,6 +131,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
126131
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
127132
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
128133
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
134+
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
129135
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
130136
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
131137
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=

metrics_proto_test.go

+168
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,186 @@ import (
2222

2323
resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1"
2424
"github.com/golang/protobuf/ptypes/timestamp"
25+
"google.golang.org/api/option"
2526
distributionpb "google.golang.org/genproto/googleapis/api/distribution"
2627
labelpb "google.golang.org/genproto/googleapis/api/label"
2728
googlemetricpb "google.golang.org/genproto/googleapis/api/metric"
2829
monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
2930
monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
31+
"google.golang.org/grpc"
3032

3133
metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1"
3234
"github.com/golang/protobuf/ptypes/wrappers"
3335
"github.com/google/go-cmp/cmp"
3436
"go.opencensus.io/resource/resourcekeys"
3537
)
3638

39+
func TestExportTimeSeriesWithDifferentLabels(t *testing.T) {
40+
server, addr, doneFn := createFakeServer(t)
41+
defer doneFn()
42+
43+
// Now create a gRPC connection to the agent.
44+
conn, err := grpc.Dial(addr, grpc.WithInsecure())
45+
if err != nil {
46+
t.Fatalf("Failed to make a gRPC connection to the agent: %v", err)
47+
}
48+
defer conn.Close()
49+
50+
// Finally create the OpenCensus stats exporter
51+
exporterOptions := Options{
52+
ProjectID: "equivalence",
53+
MonitoringClientOptions: []option.ClientOption{option.WithGRPCConn(conn)},
54+
55+
// Set empty labels to avoid the opencensus-task
56+
DefaultMonitoringLabels: &Labels{},
57+
}
58+
se, err := NewExporter(exporterOptions)
59+
if err != nil {
60+
t.Fatalf("Failed to create the statsExporter: %v", err)
61+
}
62+
63+
startTimestamp := &timestamp.Timestamp{
64+
Seconds: 1543160298,
65+
Nanos: 100000090,
66+
}
67+
endTimestamp := &timestamp.Timestamp{
68+
Seconds: 1543160298,
69+
Nanos: 100000997,
70+
}
71+
72+
// Generate the proto Metrics.
73+
var metricPbs []*metricspb.Metric
74+
metricPbs = append(metricPbs,
75+
&metricspb.Metric{
76+
MetricDescriptor: &metricspb.MetricDescriptor{
77+
Name: "ocagent.io/calls",
78+
Description: "The number of the various calls",
79+
LabelKeys: []*metricspb.LabelKey{
80+
{
81+
Key: "empty_key",
82+
},
83+
{
84+
Key: "operation_type",
85+
},
86+
},
87+
Unit: "1",
88+
Type: metricspb.MetricDescriptor_CUMULATIVE_INT64,
89+
},
90+
Timeseries: []*metricspb.TimeSeries{
91+
{
92+
StartTimestamp: startTimestamp,
93+
LabelValues: []*metricspb.LabelValue{
94+
{
95+
Value: "",
96+
HasValue: true,
97+
},
98+
{
99+
Value: "test_1",
100+
HasValue: true,
101+
},
102+
},
103+
Points: []*metricspb.Point{
104+
{
105+
Timestamp: endTimestamp,
106+
Value: &metricspb.Point_Int64Value{Int64Value: int64(1)},
107+
},
108+
},
109+
},
110+
{
111+
StartTimestamp: startTimestamp,
112+
LabelValues: []*metricspb.LabelValue{
113+
{
114+
Value: "",
115+
HasValue: true,
116+
},
117+
{
118+
Value: "test_2",
119+
HasValue: true,
120+
},
121+
},
122+
Points: []*metricspb.Point{
123+
{
124+
Timestamp: endTimestamp,
125+
Value: &metricspb.Point_Int64Value{Int64Value: int64(1)},
126+
},
127+
},
128+
},
129+
},
130+
})
131+
132+
var wantTimeSeries []*monitoringpb.CreateTimeSeriesRequest
133+
wantTimeSeries = append(wantTimeSeries, &monitoringpb.CreateTimeSeriesRequest{
134+
Name: "projects/equivalence",
135+
TimeSeries: []*monitoringpb.TimeSeries{
136+
{
137+
Metric: &googlemetricpb.Metric{
138+
Type: "custom.googleapis.com/opencensus/ocagent.io/calls",
139+
Labels: map[string]string{
140+
"empty_key": "",
141+
"operation_type": "test_1",
142+
},
143+
},
144+
Resource: &monitoredrespb.MonitoredResource{
145+
Type: "global",
146+
},
147+
MetricKind: googlemetricpb.MetricDescriptor_CUMULATIVE,
148+
ValueType: googlemetricpb.MetricDescriptor_INT64,
149+
Points: []*monitoringpb.Point{
150+
{
151+
Interval: &monitoringpb.TimeInterval{
152+
StartTime: startTimestamp,
153+
EndTime: endTimestamp,
154+
},
155+
Value: &monitoringpb.TypedValue{
156+
Value: &monitoringpb.TypedValue_Int64Value{
157+
Int64Value: 1,
158+
},
159+
},
160+
},
161+
},
162+
},
163+
{
164+
Metric: &googlemetricpb.Metric{
165+
Type: "custom.googleapis.com/opencensus/ocagent.io/calls",
166+
Labels: map[string]string{
167+
"empty_key": "",
168+
"operation_type": "test_2",
169+
},
170+
},
171+
Resource: &monitoredrespb.MonitoredResource{
172+
Type: "global",
173+
},
174+
MetricKind: googlemetricpb.MetricDescriptor_CUMULATIVE,
175+
ValueType: googlemetricpb.MetricDescriptor_INT64,
176+
Points: []*monitoringpb.Point{
177+
{
178+
Interval: &monitoringpb.TimeInterval{
179+
StartTime: startTimestamp,
180+
EndTime: endTimestamp,
181+
},
182+
Value: &monitoringpb.TypedValue{
183+
Value: &monitoringpb.TypedValue_Int64Value{
184+
Int64Value: 1,
185+
},
186+
},
187+
},
188+
},
189+
},
190+
}, //<metric:<type:"custom.googleapis.com/opencensus/ocagent.io/calls" labels:<key:"opencensus_task" value:"[email protected]" > > resource:<type:"global" > metric_kind:CUMULATIVE value_type:INT64 points:<interval:<end_time:<seconds:1001 > start_time:<seconds:1000 > > value:<int64_value:8 > > > time_series:<metric:<type:"custom.googleapis.com/opencensus/ocagent.io/calls" labels:<key:"opencensus_task" value:"[email protected]" > > resource:<type:"global" > metric_kind:CUMULATIVE value_type:INT64 points:<interval:<end_time:<seconds:1001 > start_time:<seconds:1000 > > value:<int64_value:8 > > > `,
191+
})
192+
193+
// Export the proto Metrics to the Stackdriver backend.
194+
se.PushMetricsProto(context.Background(), nil, nil, metricPbs)
195+
se.Flush()
196+
197+
var gotTimeSeries []*monitoringpb.CreateTimeSeriesRequest
198+
server.forEachStackdriverTimeSeries(func(sdt *monitoringpb.CreateTimeSeriesRequest) {
199+
gotTimeSeries = append(gotTimeSeries, sdt)
200+
})
201+
202+
requireTimeSeriesRequestEqual(t, gotTimeSeries, wantTimeSeries)
203+
}
204+
37205
func TestProtoMetricToCreateTimeSeriesRequest(t *testing.T) {
38206
startTimestamp := &timestamp.Timestamp{
39207
Seconds: 1543160298,

metrics_test.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import (
1919
"fmt"
2020
"strings"
2121
"testing"
22-
"time"
2322

2423
"github.com/golang/protobuf/proto"
24+
"github.com/golang/protobuf/ptypes"
2525
"github.com/golang/protobuf/ptypes/any"
2626
"github.com/golang/protobuf/ptypes/timestamp"
2727

@@ -90,11 +90,12 @@ func TestMetricToCreateTimeSeriesRequest(t *testing.T) {
9090
Seconds: 1543160298,
9191
Nanos: 100000090,
9292
}
93-
startTime := time.Unix(1543160298, 100000090)
93+
startTime, _ := ptypes.Timestamp(startTimestamp)
9494
endTimestamp := &timestamp.Timestamp{
9595
Seconds: 1543160298,
9696
Nanos: 100000997,
9797
}
98+
endTime, _ := ptypes.Timestamp(endTimestamp)
9899

99100
// TODO:[rghetia] add test for built-in metrics.
100101
tests := []struct {
@@ -113,10 +114,10 @@ func TestMetricToCreateTimeSeriesRequest(t *testing.T) {
113114
Resource: nil,
114115
TimeSeries: []*metricdata.TimeSeries{
115116
{
116-
StartTime: timestampToTime(startTimestamp),
117+
StartTime: startTime,
117118
Points: []metricdata.Point{
118119
{
119-
Time: timestampToTime(endTimestamp),
120+
Time: endTime,
120121
Value: &metricdata.Distribution{
121122
Count: 1,
122123
Sum: 11.9,
@@ -201,10 +202,10 @@ func TestMetricToCreateTimeSeriesRequest(t *testing.T) {
201202
Resource: nil,
202203
TimeSeries: []*metricdata.TimeSeries{
203204
{
204-
StartTime: timestampToTime(startTimestamp),
205+
StartTime: startTime,
205206
Points: []metricdata.Point{
206207
{
207-
Time: timestampToTime(endTimestamp),
208+
Time: endTime,
208209
Value: &metricdata.Distribution{
209210
Count: 1,
210211
Sum: 11.9,
@@ -430,11 +431,12 @@ func TestMetricsToMonitoringMetrics_fromProtoPoint(t *testing.T) {
430431
Seconds: 1543160298,
431432
Nanos: 100000090,
432433
}
433-
startTime := time.Unix(1543160298, 100000090)
434+
startTime, _ := ptypes.Timestamp(startTimestamp)
434435
endTimestamp := &timestamp.Timestamp{
435436
Seconds: 1543160298,
436437
Nanos: 100000997,
437438
}
439+
endTime, _ := ptypes.Timestamp(endTimestamp)
438440

439441
traceID := trace.TraceID{1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 4, 8, 16, 32, 64, 128}
440442
spanID := trace.SpanID{1, 2, 4, 8, 16, 32, 64, 128}
@@ -452,7 +454,7 @@ func TestMetricsToMonitoringMetrics_fromProtoPoint(t *testing.T) {
452454
}{
453455
{
454456
in: &metricdata.Point{
455-
Time: timestampToTime(endTimestamp),
457+
Time: endTime,
456458
Value: &metricdata.Distribution{
457459
Count: 1,
458460
Sum: 11.9,
@@ -509,7 +511,7 @@ func TestMetricsToMonitoringMetrics_fromProtoPoint(t *testing.T) {
509511
},
510512
{
511513
in: &metricdata.Point{
512-
Time: timestampToTime(endTimestamp),
514+
Time: endTime,
513515
Value: float64(50.0),
514516
},
515517
want: &monitoringpb.Point{
@@ -524,7 +526,7 @@ func TestMetricsToMonitoringMetrics_fromProtoPoint(t *testing.T) {
524526
},
525527
{
526528
in: &metricdata.Point{
527-
Time: timestampToTime(endTimestamp),
529+
Time: endTime,
528530
Value: int64(17),
529531
},
530532
want: &monitoringpb.Point{

metrics_test_utils.go

+15-10
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,33 @@ Common test utilities for comparing Stackdriver metrics.
1919
*/
2020

2121
import (
22-
"github.com/golang/protobuf/ptypes/timestamp"
22+
"testing"
23+
24+
"github.com/golang/protobuf/proto"
2325
"github.com/google/go-cmp/cmp"
2426
"github.com/google/go-cmp/cmp/cmpopts"
2527

2628
googlemetricpb "google.golang.org/genproto/googleapis/api/metric"
2729
monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
2830
monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
29-
30-
"time"
3131
)
3232

33-
func timestampToTime(ts *timestamp.Timestamp) time.Time {
34-
if ts == nil {
35-
return time.Unix(0, 0).UTC()
36-
}
37-
return time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
38-
}
39-
4033
func cmpResource(got, want *monitoredrespb.MonitoredResource) string {
4134
return cmp.Diff(got, want, cmpopts.IgnoreUnexported(monitoredrespb.MonitoredResource{}))
4235
}
4336

37+
func requireTimeSeriesRequestEqual(t *testing.T, got, want []*monitoringpb.CreateTimeSeriesRequest) {
38+
if len(got) != len(want) {
39+
t.Fatalf("Unexpected slice len got: %d want: %d", len(got), len(want))
40+
}
41+
for i, g := range got {
42+
w := want[i]
43+
if !proto.Equal(g, w) {
44+
t.Fatalf("Unexpected proto difference got: %s want: %s", proto.MarshalTextString(g), proto.MarshalTextString(w))
45+
}
46+
}
47+
}
48+
4449
func cmpTSReqs(got, want []*monitoringpb.CreateTimeSeriesRequest) string {
4550
return cmp.Diff(got, want, cmpopts.IgnoreUnexported(monitoringpb.CreateTimeSeriesRequest{}), cmpopts.IgnoreTypes(googlemetricpb.MetricDescriptor_METRIC_KIND_UNSPECIFIED, googlemetricpb.MetricDescriptor_VALUE_TYPE_UNSPECIFIED))
4651
}

0 commit comments

Comments
 (0)