@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 01:00 UTC

master
go 102 lines 2.79 KB
Raw
1 package tracing
2
3 import (
4 "errors"
5 "testing"
6
7 sdktrace "go.opentelemetry.io/otel/sdk/trace"
8 "go.uber.org/zap"
9 )
10
11 func noOpts() ([]sdktrace.TracerProviderOption, error) {
12 return nil, nil
13 }
14
15 func Test_tracersProvider_getTracerProvider(t *testing.T) {
16 tp := tracerProvider{}
17
18 _, _ = tp.getTracerProvider(noOpts)
19 _, _ = tp.getTracerProvider(noOpts)
20
21 if tp.tracerProvider == nil {
22 t.Errorf("There should be tracer provider")
23 }
24
25 if tp.tracerProvidersCounter != 2 {
26 t.Errorf("Tracer providers counter should equal to 2")
27 }
28 }
29
30 func Test_tracersProvider_cleanupTracerProvider(t *testing.T) {
31 tp := tracerProvider{}
32
33 _, _ = tp.getTracerProvider(noOpts)
34 _, _ = tp.getTracerProvider(noOpts)
35
36 err := tp.cleanupTracerProvider(zap.NewNop())
37 if err != nil {
38 t.Errorf("There should be no error: %v", err)
39 }
40
41 if tp.tracerProvider == nil {
42 t.Errorf("There should be tracer provider")
43 }
44
45 if tp.tracerProvidersCounter != 1 {
46 t.Errorf("Tracer providers counter should equal to 1")
47 }
48 }
49
50 // Test_tracersProvider_buildOptsOnlyOnCreate guards against a goroutine leak on
51 // config reload: buildOpts must be invoked only when a new provider is actually
52 // created, never on the reuse path. Some options (e.g. sdktrace.WithBatcher)
53 // eagerly start a BatchSpanProcessor goroutine when constructed, so calling
54 // buildOpts on every reload would leak one goroutine per reload.
55 func Test_tracersProvider_buildOptsOnlyOnCreate(t *testing.T) {
56 tp := tracerProvider{}
57
58 builds := 0
59 build := func() ([]sdktrace.TracerProviderOption, error) {
60 builds++
61 return nil, nil
62 }
63
64 // First call creates the provider and must build options.
65 _, _ = tp.getTracerProvider(build)
66 // Subsequent calls reuse the existing provider and must NOT build options again.
67 for i := 0; i < 5; i++ {
68 _, _ = tp.getTracerProvider(build)
69 }
70
71 if builds != 1 {
72 t.Errorf("buildOpts should be invoked exactly once (on create), got %d", builds)
73 }
74 if tp.tracerProvidersCounter != 6 {
75 t.Errorf("Tracer providers counter should equal to 6, got %d", tp.tracerProvidersCounter)
76 }
77 }
78
79 // Test_tracersProvider_buildOptsError verifies that an error from buildOpts is
80 // propagated and that no provider is created nor the counter incremented, so a
81 // failed build leaves the tracerProvider in its initial state.
82 func Test_tracersProvider_buildOptsError(t *testing.T) {
83 tp := tracerProvider{}
84
85 wantErr := errors.New("build failed")
86 build := func() ([]sdktrace.TracerProviderOption, error) {
87 return nil, wantErr
88 }
89
90 _, err := tp.getTracerProvider(build)
91 if !errors.Is(err, wantErr) {
92 t.Errorf("Expected error %v, got %v", wantErr, err)
93 }
94
95 if tp.tracerProvider != nil {
96 t.Errorf("There should be no tracer provider when buildOpts fails")
97 }
98
99 if tp.tracerProvidersCounter != 0 {
100 t.Errorf("Tracer providers counter should equal to 0, got %d", tp.tracerProvidersCounter)
101 }
102 }