1// Code created by gotmpl. DO NOT MODIFY.
2// source: internal/shared/otlp/otlpmetric/oconf/options_test.go.tmpl
3
4// Copyright The OpenTelemetry Authors
5//
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18package oconf
19
20import (
21 "errors"
22 "testing"
23 "time"
24
25 "github.com/stretchr/testify/assert"
26
27 "{{ .envconfigImportPath }}"
28 "go.opentelemetry.io/otel/sdk/metric"
29 "go.opentelemetry.io/otel/sdk/metric/metricdata"
30)
31
32const (
33 WeakCertificate = `
34-----BEGIN CERTIFICATE-----
35MIIBhzCCASygAwIBAgIRANHpHgAWeTnLZpTSxCKs0ggwCgYIKoZIzj0EAwIwEjEQ
36MA4GA1UEChMHb3RlbC1nbzAeFw0yMTA0MDExMzU5MDNaFw0yMTA0MDExNDU5MDNa
37MBIxEDAOBgNVBAoTB290ZWwtZ28wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS9
38nWSkmPCxShxnp43F+PrOtbGV7sNfkbQ/kxzi9Ego0ZJdiXxkmv/C05QFddCW7Y0Z
39sJCLHGogQsYnWJBXUZOVo2MwYTAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
40KwYBBQUHAwEwDAYDVR0TAQH/BAIwADAsBgNVHREEJTAjgglsb2NhbGhvc3SHEAAA
41AAAAAAAAAAAAAAAAAAGHBH8AAAEwCgYIKoZIzj0EAwIDSQAwRgIhANwZVVKvfvQ/
421HXsTvgH+xTQswOwSSKYJ1cVHQhqK7ZbAiEAus8NxpTRnp5DiTMuyVmhVNPB+bVH
43Lhnm4N/QDk5rek0=
44-----END CERTIFICATE-----
45`
46 WeakPrivateKey = `
47-----BEGIN PRIVATE KEY-----
48MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgN8HEXiXhvByrJ1zK
49SFT6Y2l2KqDWwWzKf+t4CyWrNKehRANCAAS9nWSkmPCxShxnp43F+PrOtbGV7sNf
50kbQ/kxzi9Ego0ZJdiXxkmv/C05QFddCW7Y0ZsJCLHGogQsYnWJBXUZOV
51-----END PRIVATE KEY-----
52`
53)
54
55type env map[string]string
56
57func (e *env) getEnv(env string) string {
58 return (*e)[env]
59}
60
61type fileReader map[string][]byte
62
63func (f *fileReader) readFile(filename string) ([]byte, error) {
64 if b, ok := (*f)[filename]; ok {
65 return b, nil
66 }
67 return nil, errors.New("file not found")
68}
69
70func TestConfigs(t *testing.T) {
71 tlsCert, err := CreateTLSConfig([]byte(WeakCertificate))
72 assert.NoError(t, err)
73
74 tests := []struct {
75 name string
76 opts []GenericOption
77 env env
78 fileReader fileReader
79 asserts func(t *testing.T, c *Config, grpcOption bool)
80 }{
81 {
82 name: "Test default configs",
83 asserts: func(t *testing.T, c *Config, grpcOption bool) {
84 if grpcOption {
85 assert.Equal(t, "localhost:4317", c.Metrics.Endpoint)
86 } else {
87 assert.Equal(t, "localhost:4318", c.Metrics.Endpoint)
88 }
89 assert.Equal(t, NoCompression, c.Metrics.Compression)
90 assert.Equal(t, map[string]string(nil), c.Metrics.Headers)
91 assert.Equal(t, 10*time.Second, c.Metrics.Timeout)
92 },
93 },
94
95 // Endpoint Tests
96 {
97 name: "Test With Endpoint",
98 opts: []GenericOption{
99 WithEndpoint("someendpoint"),
100 },
101 asserts: func(t *testing.T, c *Config, grpcOption bool) {
102 assert.Equal(t, "someendpoint", c.Metrics.Endpoint)
103 },
104 },
105 {
106 name: "Test Environment Endpoint",
107 env: map[string]string{
108 "OTEL_EXPORTER_OTLP_ENDPOINT": "https://env.endpoint/prefix",
109 },
110 asserts: func(t *testing.T, c *Config, grpcOption bool) {
111 assert.False(t, c.Metrics.Insecure)
112 if grpcOption {
113 assert.Equal(t, "env.endpoint/prefix", c.Metrics.Endpoint)
114 } else {
115 assert.Equal(t, "env.endpoint", c.Metrics.Endpoint)
116 assert.Equal(t, "/prefix/v1/metrics", c.Metrics.URLPath)
117 }
118 },
119 },
120 {
121 name: "Test Environment Signal Specific Endpoint",
122 env: map[string]string{
123 "OTEL_EXPORTER_OTLP_ENDPOINT": "https://overrode.by.signal.specific/env/var",
124 "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT": "http://env.metrics.endpoint",
125 },
126 asserts: func(t *testing.T, c *Config, grpcOption bool) {
127 assert.True(t, c.Metrics.Insecure)
128 assert.Equal(t, "env.metrics.endpoint", c.Metrics.Endpoint)
129 if !grpcOption {
130 assert.Equal(t, "/", c.Metrics.URLPath)
131 }
132 },
133 },
134 {
135 name: "Test Mixed Environment and With Endpoint",
136 opts: []GenericOption{
137 WithEndpoint("metrics_endpoint"),
138 },
139 env: map[string]string{
140 "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint",
141 },
142 asserts: func(t *testing.T, c *Config, grpcOption bool) {
143 assert.Equal(t, "metrics_endpoint", c.Metrics.Endpoint)
144 },
145 },
146 {
147 name: "Test Environment Endpoint with HTTP scheme",
148 env: map[string]string{
149 "OTEL_EXPORTER_OTLP_ENDPOINT": "http://env_endpoint",
150 },
151 asserts: func(t *testing.T, c *Config, grpcOption bool) {
152 assert.Equal(t, "env_endpoint", c.Metrics.Endpoint)
153 assert.Equal(t, true, c.Metrics.Insecure)
154 },
155 },
156 {
157 name: "Test Environment Endpoint with HTTP scheme and leading & trailingspaces",
158 env: map[string]string{
159 "OTEL_EXPORTER_OTLP_ENDPOINT": " http://env_endpoint ",
160 },
161 asserts: func(t *testing.T, c *Config, grpcOption bool) {
162 assert.Equal(t, "env_endpoint", c.Metrics.Endpoint)
163 assert.Equal(t, true, c.Metrics.Insecure)
164 },
165 },
166 {
167 name: "Test Environment Endpoint with HTTPS scheme",
168 env: map[string]string{
169 "OTEL_EXPORTER_OTLP_ENDPOINT": "https://env_endpoint",
170 },
171 asserts: func(t *testing.T, c *Config, grpcOption bool) {
172 assert.Equal(t, "env_endpoint", c.Metrics.Endpoint)
173 assert.Equal(t, false, c.Metrics.Insecure)
174 },
175 },
176 {
177 name: "Test Environment Signal Specific Endpoint with uppercase scheme",
178 env: map[string]string{
179 "OTEL_EXPORTER_OTLP_ENDPOINT": "HTTPS://overrode_by_signal_specific",
180 "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT": "HtTp://env_metrics_endpoint",
181 },
182 asserts: func(t *testing.T, c *Config, grpcOption bool) {
183 assert.Equal(t, "env_metrics_endpoint", c.Metrics.Endpoint)
184 assert.Equal(t, true, c.Metrics.Insecure)
185 },
186 },
187
188 // Certificate tests
189 {
190 name: "Test Default Certificate",
191 asserts: func(t *testing.T, c *Config, grpcOption bool) {
192 if grpcOption {
193 assert.NotNil(t, c.Metrics.GRPCCredentials)
194 } else {
195 assert.Nil(t, c.Metrics.TLSCfg)
196 }
197 },
198 },
199 {
200 name: "Test With Certificate",
201 opts: []GenericOption{
202 WithTLSClientConfig(tlsCert),
203 },
204 asserts: func(t *testing.T, c *Config, grpcOption bool) {
205 if grpcOption {
206 // TODO: make sure gRPC's credentials actually works
207 assert.NotNil(t, c.Metrics.GRPCCredentials)
208 } else {
209 // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool.
210 assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Metrics.TLSCfg.RootCAs.Subjects())
211 }
212 },
213 },
214 {
215 name: "Test Environment Certificate",
216 env: map[string]string{
217 "OTEL_EXPORTER_OTLP_CERTIFICATE": "cert_path",
218 },
219 fileReader: fileReader{
220 "cert_path": []byte(WeakCertificate),
221 },
222 asserts: func(t *testing.T, c *Config, grpcOption bool) {
223 if grpcOption {
224 assert.NotNil(t, c.Metrics.GRPCCredentials)
225 } else {
226 // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool.
227 assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Metrics.TLSCfg.RootCAs.Subjects())
228 }
229 },
230 },
231 {
232 name: "Test Environment Signal Specific Certificate",
233 env: map[string]string{
234 "OTEL_EXPORTER_OTLP_CERTIFICATE": "overrode_by_signal_specific",
235 "OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE": "cert_path",
236 },
237 fileReader: fileReader{
238 "cert_path": []byte(WeakCertificate),
239 "invalid_cert": []byte("invalid certificate file."),
240 },
241 asserts: func(t *testing.T, c *Config, grpcOption bool) {
242 if grpcOption {
243 assert.NotNil(t, c.Metrics.GRPCCredentials)
244 } else {
245 // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool.
246 assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Metrics.TLSCfg.RootCAs.Subjects())
247 }
248 },
249 },
250 {
251 name: "Test Mixed Environment and With Certificate",
252 opts: []GenericOption{},
253 env: map[string]string{
254 "OTEL_EXPORTER_OTLP_CERTIFICATE": "cert_path",
255 },
256 fileReader: fileReader{
257 "cert_path": []byte(WeakCertificate),
258 },
259 asserts: func(t *testing.T, c *Config, grpcOption bool) {
260 if grpcOption {
261 assert.NotNil(t, c.Metrics.GRPCCredentials)
262 } else {
263 // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool.
264 assert.Equal(t, 1, len(c.Metrics.TLSCfg.RootCAs.Subjects()))
265 }
266 },
267 },
268
269 // Headers tests
270 {
271 name: "Test With Headers",
272 opts: []GenericOption{
273 WithHeaders(map[string]string{"h1": "v1"}),
274 },
275 asserts: func(t *testing.T, c *Config, grpcOption bool) {
276 assert.Equal(t, map[string]string{"h1": "v1"}, c.Metrics.Headers)
277 },
278 },
279 {
280 name: "Test Environment Headers",
281 env: map[string]string{"OTEL_EXPORTER_OTLP_HEADERS": "h1=v1,h2=v2"},
282 asserts: func(t *testing.T, c *Config, grpcOption bool) {
283 assert.Equal(t, map[string]string{"h1": "v1", "h2": "v2"}, c.Metrics.Headers)
284 },
285 },
286 {
287 name: "Test Environment Signal Specific Headers",
288 env: map[string]string{
289 "OTEL_EXPORTER_OTLP_HEADERS": "overrode_by_signal_specific",
290 "OTEL_EXPORTER_OTLP_METRICS_HEADERS": "h1=v1,h2=v2",
291 },
292 asserts: func(t *testing.T, c *Config, grpcOption bool) {
293 assert.Equal(t, map[string]string{"h1": "v1", "h2": "v2"}, c.Metrics.Headers)
294 },
295 },
296 {
297 name: "Test Mixed Environment and With Headers",
298 env: map[string]string{"OTEL_EXPORTER_OTLP_HEADERS": "h1=v1,h2=v2"},
299 opts: []GenericOption{
300 WithHeaders(map[string]string{"m1": "mv1"}),
301 },
302 asserts: func(t *testing.T, c *Config, grpcOption bool) {
303 assert.Equal(t, map[string]string{"m1": "mv1"}, c.Metrics.Headers)
304 },
305 },
306
307 // Compression Tests
308 {
309 name: "Test With Compression",
310 opts: []GenericOption{
311 WithCompression(GzipCompression),
312 },
313 asserts: func(t *testing.T, c *Config, grpcOption bool) {
314 assert.Equal(t, GzipCompression, c.Metrics.Compression)
315 },
316 },
317 {
318 name: "Test Environment Compression",
319 env: map[string]string{
320 "OTEL_EXPORTER_OTLP_COMPRESSION": "gzip",
321 },
322 asserts: func(t *testing.T, c *Config, grpcOption bool) {
323 assert.Equal(t, GzipCompression, c.Metrics.Compression)
324 },
325 },
326 {
327 name: "Test Environment Signal Specific Compression",
328 env: map[string]string{
329 "OTEL_EXPORTER_OTLP_METRICS_COMPRESSION": "gzip",
330 },
331 asserts: func(t *testing.T, c *Config, grpcOption bool) {
332 assert.Equal(t, GzipCompression, c.Metrics.Compression)
333 },
334 },
335 {
336 name: "Test Mixed Environment and With Compression",
337 opts: []GenericOption{
338 WithCompression(NoCompression),
339 },
340 env: map[string]string{
341 "OTEL_EXPORTER_OTLP_METRICS_COMPRESSION": "gzip",
342 },
343 asserts: func(t *testing.T, c *Config, grpcOption bool) {
344 assert.Equal(t, NoCompression, c.Metrics.Compression)
345 },
346 },
347
348 // Timeout Tests
349 {
350 name: "Test With Timeout",
351 opts: []GenericOption{
352 WithTimeout(time.Duration(5 * time.Second)),
353 },
354 asserts: func(t *testing.T, c *Config, grpcOption bool) {
355 assert.Equal(t, 5*time.Second, c.Metrics.Timeout)
356 },
357 },
358 {
359 name: "Test Environment Timeout",
360 env: map[string]string{
361 "OTEL_EXPORTER_OTLP_TIMEOUT": "15000",
362 },
363 asserts: func(t *testing.T, c *Config, grpcOption bool) {
364 assert.Equal(t, c.Metrics.Timeout, 15*time.Second)
365 },
366 },
367 {
368 name: "Test Environment Signal Specific Timeout",
369 env: map[string]string{
370 "OTEL_EXPORTER_OTLP_TIMEOUT": "15000",
371 "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT": "28000",
372 },
373 asserts: func(t *testing.T, c *Config, grpcOption bool) {
374 assert.Equal(t, c.Metrics.Timeout, 28*time.Second)
375 },
376 },
377 {
378 name: "Test Mixed Environment and With Timeout",
379 env: map[string]string{
380 "OTEL_EXPORTER_OTLP_TIMEOUT": "15000",
381 "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT": "28000",
382 },
383 opts: []GenericOption{
384 WithTimeout(5 * time.Second),
385 },
386 asserts: func(t *testing.T, c *Config, grpcOption bool) {
387 assert.Equal(t, c.Metrics.Timeout, 5*time.Second)
388 },
389 },
390
391 // Temporality Selector Tests
392 {
393 name: "WithTemporalitySelector",
394 opts: []GenericOption{
395 WithTemporalitySelector(deltaSelector),
396 },
397 asserts: func(t *testing.T, c *Config, grpcOption bool) {
398 // Function value comparisons are disallowed, test non-default
399 // behavior of a TemporalitySelector here to ensure our "catch
400 // all" was set.
401 var undefinedKind metric.InstrumentKind
402 got := c.Metrics.TemporalitySelector
403 assert.Equal(t, metricdata.DeltaTemporality, got(undefinedKind))
404 },
405 },
406
407 // Aggregation Selector Tests
408 {
409 name: "WithAggregationSelector",
410 opts: []GenericOption{
411 WithAggregationSelector(dropSelector),
412 },
413 asserts: func(t *testing.T, c *Config, grpcOption bool) {
414 // Function value comparisons are disallowed, test non-default
415 // behavior of a AggregationSelector here to ensure our "catch
416 // all" was set.
417 var undefinedKind metric.InstrumentKind
418 got := c.Metrics.AggregationSelector
419 assert.Equal(t, metric.AggregationDrop{}, got(undefinedKind))
420 },
421 },
422 }
423
424 for _, tt := range tests {
425 t.Run(tt.name, func(t *testing.T) {
426 origEOR := DefaultEnvOptionsReader
427 DefaultEnvOptionsReader = envconfig.EnvOptionsReader{
428 GetEnv: tt.env.getEnv,
429 ReadFile: tt.fileReader.readFile,
430 Namespace: "OTEL_EXPORTER_OTLP",
431 }
432 t.Cleanup(func() { DefaultEnvOptionsReader = origEOR })
433
434 // Tests Generic options as HTTP Options
435 cfg := NewHTTPConfig(asHTTPOptions(tt.opts)...)
436 tt.asserts(t, &cfg, false)
437
438 // Tests Generic options as gRPC Options
439 cfg = NewGRPCConfig(asGRPCOptions(tt.opts)...)
440 tt.asserts(t, &cfg, true)
441 })
442 }
443}
444
445func dropSelector(metric.InstrumentKind) metric.Aggregation {
446 return metric.AggregationDrop{}
447}
448
449func deltaSelector(metric.InstrumentKind) metricdata.Temporality {
450 return metricdata.DeltaTemporality
451}
452
453func asHTTPOptions(opts []GenericOption) []HTTPOption {
454 converted := make([]HTTPOption, len(opts))
455 for i, o := range opts {
456 converted[i] = NewHTTPOption(o.ApplyHTTPOption)
457 }
458 return converted
459}
460
461func asGRPCOptions(opts []GenericOption) []GRPCOption {
462 converted := make([]GRPCOption, len(opts))
463 for i, o := range opts {
464 converted[i] = NewGRPCOption(o.ApplyGRPCOption)
465 }
466 return converted
467}
468
469func TestCleanPath(t *testing.T) {
470 type args struct {
471 urlPath string
472 defaultPath string
473 }
474 tests := []struct {
475 name string
476 args args
477 want string
478 }{
479 {
480 name: "clean empty path",
481 args: args{
482 urlPath: "",
483 defaultPath: "DefaultPath",
484 },
485 want: "DefaultPath",
486 },
487 {
488 name: "clean metrics path",
489 args: args{
490 urlPath: "/prefix/v1/metrics",
491 defaultPath: "DefaultMetricsPath",
492 },
493 want: "/prefix/v1/metrics",
494 },
495 {
496 name: "clean traces path",
497 args: args{
498 urlPath: "https://env_endpoint",
499 defaultPath: "DefaultTracesPath",
500 },
501 want: "/https:/env_endpoint",
502 },
503 {
504 name: "spaces trimmed",
505 args: args{
506 urlPath: " /dir",
507 },
508 want: "/dir",
509 },
510 {
511 name: "clean path empty",
512 args: args{
513 urlPath: "dir/..",
514 defaultPath: "DefaultTracesPath",
515 },
516 want: "DefaultTracesPath",
517 },
518 {
519 name: "make absolute",
520 args: args{
521 urlPath: "dir/a",
522 },
523 want: "/dir/a",
524 },
525 }
526 for _, tt := range tests {
527 t.Run(tt.name, func(t *testing.T) {
528 if got := cleanPath(tt.args.urlPath, tt.args.defaultPath); got != tt.want {
529 t.Errorf("CleanPath() = %v, want %v", got, tt.want)
530 }
531 })
532 }
533}
View as plain text