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

Commit e2f5be5

Browse files
authored
Resource per metric (#224)
* add test for resource on per metric basis. * add test for built-in metrics. * add test for metric prefix. * add test for non-builtin prefix with domain. - also modify createFakeServer to return server and connectio * execute conn.Close() first.
1 parent 76f086b commit e2f5be5

4 files changed

Lines changed: 362 additions & 29 deletions

File tree

metrics_proto_api_test.go

Lines changed: 161 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -68,30 +68,114 @@ func TestVariousCasesFromFile(t *testing.T) {
6868
files := []string{
6969
"ExportLabels",
7070
"ExportMetricsOfAllTypes",
71+
"BuiltInMetrics",
7172
}
7273
for _, file := range files {
7374
tc := readTestCaseFromFiles(t, file)
74-
server, addr, doneFn := createFakeServer(t)
75+
server, conn, doneFn := createFakeServerConn(t)
7576
defer doneFn()
7677

77-
// Now create a gRPC connection to the agent.
78-
conn := createConn(t, addr)
79-
defer conn.Close()
80-
8178
// Finally create the OpenCensus stats exporter
8279
se := createExporter(t, conn, defaultOpts)
8380
executeTestCase(t, tc, se, server, nil)
8481

8582
}
8683
}
8784

88-
func TestMetricsWithResourcePerPushCall(t *testing.T) {
89-
server, addr, doneFn := createFakeServer(t)
85+
func TestMetricsWithPrefix(t *testing.T) {
86+
server, conn, doneFn := createFakeServerConn(t)
9087
defer doneFn()
9188

92-
// Now create a gRPC connection to the server.
93-
conn := createConn(t, addr)
94-
defer conn.Close()
89+
tc := readTestCaseFromFiles(t, "SingleMetric")
90+
91+
prefixes := []string{
92+
"example.com/",
93+
"example.com/foo/",
94+
}
95+
metricName := "ocagent.io"
96+
saveMetricType := tc.outTSR[0].TimeSeries[0].Metric.Type
97+
saveMDRName := tc.outMDR[0].MetricDescriptor.Name
98+
saveMDRDispName := tc.outMDR[0].MetricDescriptor.DisplayName
99+
100+
for _, prefix := range prefixes {
101+
opts := defaultOpts
102+
opts.MetricPrefix = prefix
103+
se := createExporter(t, conn, opts)
104+
105+
mt := strings.Replace(saveMetricType, metricName, (prefix + metricName), -1)
106+
tc.outMDR[0].MetricDescriptor.Name = strings.Replace(saveMDRName, metricName, (prefix + metricName), -1)
107+
tc.outMDR[0].MetricDescriptor.Type = mt
108+
tc.outMDR[0].MetricDescriptor.DisplayName = strings.Replace(saveMDRDispName, "OpenCensus/"+metricName, (prefix + metricName), -1)
109+
110+
tc.outTSR[0].TimeSeries[0].Metric.Type = mt
111+
112+
executeTestCase(t, tc, se, server, nil)
113+
}
114+
}
115+
116+
func TestMetricsWithPrefixWithDomain(t *testing.T) {
117+
server, conn, doneFn := createFakeServerConn(t)
118+
defer doneFn()
119+
120+
tc := readTestCaseFromFiles(t, "SingleMetric")
121+
122+
prefixes := []string{
123+
"custom.googleapis.com/prometheus/",
124+
"external.googleapis.com/prometheus/",
125+
}
126+
metricName := "ocagent.io"
127+
saveMetricType := strings.Replace(tc.outTSR[0].TimeSeries[0].Metric.Type, "custom.googleapis.com/opencensus/", "", -1)
128+
saveMDRName := strings.Replace(tc.outMDR[0].MetricDescriptor.Name, "custom.googleapis.com/opencensus/", "", -1)
129+
saveMDRDispName := tc.outMDR[0].MetricDescriptor.DisplayName
130+
131+
for _, prefix := range prefixes {
132+
opts := defaultOpts
133+
opts.MetricPrefix = prefix
134+
se := createExporter(t, conn, opts)
135+
136+
mt := strings.Replace(saveMetricType, metricName, (prefix + metricName), -1)
137+
tc.outMDR[0].MetricDescriptor.Name = strings.Replace(saveMDRName, metricName, (prefix + metricName), -1)
138+
tc.outMDR[0].MetricDescriptor.Type = mt
139+
tc.outMDR[0].MetricDescriptor.DisplayName = strings.Replace(saveMDRDispName, "OpenCensus/"+metricName, (prefix + metricName), -1)
140+
141+
tc.outTSR[0].TimeSeries[0].Metric.Type = mt
142+
143+
executeTestCase(t, tc, se, server, nil)
144+
}
145+
}
146+
147+
func TestBuiltInMetricsUsingPrefix(t *testing.T) {
148+
server, conn, doneFn := createFakeServerConn(t)
149+
defer doneFn()
150+
151+
tc := readTestCaseFromFiles(t, "SingleMetric")
152+
153+
prefixes := []string{
154+
"googleapis.com/",
155+
"kubernetes.io/",
156+
"istio.io/",
157+
}
158+
metricName := "ocagent.io"
159+
saveMetricType := tc.outTSR[0].TimeSeries[0].Metric.Type
160+
161+
for _, prefix := range prefixes {
162+
opts := defaultOpts
163+
opts.MetricPrefix = prefix
164+
se := createExporter(t, conn, opts)
165+
166+
// no CreateMetricDescriptorRequest expected.
167+
tc.outMDR = nil
168+
169+
mt := strings.Replace(saveMetricType, "custom.googleapis.com/opencensus/"+metricName, (prefix + metricName), -1)
170+
tc.outTSR[0].TimeSeries[0].Metric.Type = mt
171+
172+
executeTestCase(t, tc, se, server, nil)
173+
}
174+
}
175+
176+
func TestMetricsWithResourcePerPushCall(t *testing.T) {
177+
server, conn, doneFn := createFakeServerConn(t)
178+
defer doneFn()
95179

96180
inResources, outResources := readTestResourcesFiles(t, "Resources")
97181
inLen := len(inResources)
@@ -114,13 +198,64 @@ func TestMetricsWithResourcePerPushCall(t *testing.T) {
114198
}
115199
}
116200

117-
func TestMetricsWithResourceWithMissingFieldsPerPushCall(t *testing.T) {
118-
server, addr, doneFn := createFakeServer(t)
201+
func TestMetricsWithResourcePerMetric(t *testing.T) {
202+
server, conn, doneFn := createFakeServerConn(t)
203+
defer doneFn()
204+
205+
inResources, outResources := readTestResourcesFiles(t, "Resources")
206+
inLen := len(inResources)
207+
outLen := len(outResources)
208+
if inLen != outLen {
209+
t.Errorf("Data invalid: input Resource len (%d) != output Resource len (%d)\n", inLen, outLen)
210+
return
211+
}
212+
213+
tcSingleMetric := readTestCaseFromFiles(t, "SingleMetric")
214+
215+
for i, inRes := range inResources {
216+
se := createExporter(t, conn, defaultOpts)
217+
218+
tc := *tcSingleMetric
219+
tc.name = inRes.Type
220+
tc.inMetric[0].Resource = inResources[i]
221+
tc.outTSR[0].TimeSeries[0].Resource = outResources[i]
222+
223+
executeTestCase(t, &tc, se, server, nil)
224+
}
225+
}
226+
227+
func TestMetricsWithResourcePerMetricTakesPrecedence(t *testing.T) {
228+
server, conn, doneFn := createFakeServerConn(t)
119229
defer doneFn()
120230

121-
// Now create a gRPC connection to the server.
122-
conn := createConn(t, addr)
123-
defer conn.Close()
231+
inResources, outResources := readTestResourcesFiles(t, "Resources")
232+
inLen := len(inResources)
233+
outLen := len(outResources)
234+
if inLen != outLen {
235+
t.Errorf("Data invalid: input Resource len (%d) != output Resource len (%d)\n", inLen, outLen)
236+
return
237+
}
238+
239+
tcSingleMetric := readTestCaseFromFiles(t, "SingleMetric")
240+
241+
// use the same resource for push call. Resource per metric should take precedence.
242+
perPushRes := inResources[inLen-1]
243+
244+
for i, inRes := range inResources {
245+
se := createExporter(t, conn, defaultOpts)
246+
247+
tc := *tcSingleMetric
248+
tc.name = inRes.Type
249+
tc.inMetric[0].Resource = inResources[i]
250+
tc.outTSR[0].TimeSeries[0].Resource = outResources[i]
251+
252+
executeTestCase(t, &tc, se, server, perPushRes)
253+
}
254+
}
255+
256+
func TestMetricsWithResourceWithMissingFieldsPerPushCall(t *testing.T) {
257+
server, conn, doneFn := createFakeServerConn(t)
258+
defer doneFn()
124259

125260
inResources, outResources := readTestResourcesFiles(t, "ResourcesWithMissingFields")
126261
inLen := len(inResources)
@@ -144,13 +279,9 @@ func TestMetricsWithResourceWithMissingFieldsPerPushCall(t *testing.T) {
144279
}
145280

146281
func TestExportMaxTSPerRequest(t *testing.T) {
147-
server, addr, doneFn := createFakeServer(t)
282+
server, conn, doneFn := createFakeServerConn(t)
148283
defer doneFn()
149284

150-
// Now create a gRPC connection to the server.
151-
conn := createConn(t, addr)
152-
defer conn.Close()
153-
154285
// Finally create the OpenCensus stats exporter
155286
se := createExporter(t, conn, defaultOpts)
156287

@@ -187,13 +318,9 @@ func TestExportMaxTSPerRequest(t *testing.T) {
187318
}
188319

189320
func TestExportMaxTSPerRequestAcrossTwoMetrics(t *testing.T) {
190-
server, addr, doneFn := createFakeServer(t)
321+
server, conn, doneFn := createFakeServerConn(t)
191322
defer doneFn()
192323

193-
// Now create a gRPC connection to the server.
194-
conn := createConn(t, addr)
195-
defer conn.Close()
196-
197324
// Finally create the OpenCensus stats exporter
198325
se := createExporter(t, conn, defaultOpts)
199326

@@ -328,7 +455,9 @@ func readTestCaseFromFiles(t *testing.T, filename string) *testCases {
328455
if err != nil {
329456
t.Fatalf("error unmarshalling CreateMetricDescriptorRequest protos from file " + filename)
330457
}
331-
tc.outMDR = append(tc.outMDR, &outMDR)
458+
if outMDR.Name != "" {
459+
tc.outMDR = append(tc.outMDR, &outMDR)
460+
}
332461
}
333462

334463
// Read expected output CreateTimeSeriesRequest proto.
@@ -394,7 +523,7 @@ type fakeMetricsServer struct {
394523
stackdriverMetricDescriptors []*monitoringpb.CreateMetricDescriptorRequest
395524
}
396525

397-
func createFakeServer(t *testing.T) (*fakeMetricsServer, string, func()) {
526+
func createFakeServerConn(t *testing.T) (*fakeMetricsServer, *grpc.ClientConn, func()) {
398527
ln, err := net.Listen("tcp", "localhost:0")
399528
if err != nil {
400529
t.Fatalf("Failed to bind to an available address: %v", err)
@@ -405,12 +534,15 @@ func createFakeServer(t *testing.T) (*fakeMetricsServer, string, func()) {
405534
go func() {
406535
_ = srv.Serve(ln)
407536
}()
537+
_, serverPortStr, _ := net.SplitHostPort(ln.Addr().String())
538+
conn := createConn(t, "localhost:"+serverPortStr)
539+
408540
stop := func() {
541+
conn.Close()
409542
srv.Stop()
410543
_ = ln.Close()
411544
}
412-
_, serverPortStr, _ := net.SplitHostPort(ln.Addr().String())
413-
return server, "localhost:" + serverPortStr, stop
545+
return server, conn, stop
414546
}
415547

416548
func (server *fakeMetricsServer) forEachStackdriverTimeSeries(fn func(sdt *monitoringpb.CreateTimeSeriesRequest)) {
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
metric_descriptor: <
2+
name: "googleapis.com/calls"
3+
description: "Number of calls"
4+
unit: "1"
5+
type: CUMULATIVE_INT64
6+
label_keys: <
7+
key: "empty_key"
8+
>
9+
label_keys: <
10+
key: "operation_type"
11+
>
12+
>
13+
timeseries: <
14+
start_timestamp: <
15+
seconds: 1543160298
16+
nanos: 100000090
17+
>
18+
label_values: <
19+
has_value: true
20+
>
21+
label_values: <
22+
value: "value_0"
23+
has_value: true
24+
>
25+
points: <
26+
timestamp: <
27+
seconds: 1543160298
28+
nanos: 100000997
29+
>
30+
int64_value: 1
31+
>
32+
>
33+
---
34+
metric_descriptor: <
35+
name: "kubernetes.io/latency"
36+
description: "Description of latency"
37+
unit: "ms"
38+
type: CUMULATIVE_INT64
39+
label_keys: <
40+
key: "empty_key"
41+
>
42+
label_keys: <
43+
key: "operation_type"
44+
>
45+
>
46+
timeseries: <
47+
start_timestamp: <
48+
seconds: 1543160298
49+
nanos: 100000090
50+
>
51+
label_values: <
52+
has_value: true
53+
>
54+
label_values: <
55+
value: "value_0"
56+
has_value: true
57+
>
58+
points: <
59+
timestamp: <
60+
seconds: 1543160298
61+
nanos: 100000997
62+
>
63+
int64_value: 1
64+
>
65+
>
66+
---
67+
metric_descriptor: <
68+
name: "istio.io/latency"
69+
description: "Description of latency"
70+
unit: "ms"
71+
type: CUMULATIVE_INT64
72+
label_keys: <
73+
key: "empty_key"
74+
>
75+
label_keys: <
76+
key: "operation_type"
77+
>
78+
>
79+
timeseries: <
80+
start_timestamp: <
81+
seconds: 1543160298
82+
nanos: 100000090
83+
>
84+
label_values: <
85+
has_value: true
86+
>
87+
label_values: <
88+
value: "value_0"
89+
has_value: true
90+
>
91+
points: <
92+
timestamp: <
93+
seconds: 1543160298
94+
nanos: 100000997
95+
>
96+
int64_value: 1
97+
>
98+
>
99+

testdata/BuiltInMetrics/outMDR.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Empty file required to specify that no CreateMetricDescriptorRequest will be generated.
2+

0 commit comments

Comments
 (0)