Skip to content

Commit 021faad

Browse files
flc1125ndyakov
andauthored
test(redisotel): rename redisotel_test.go to tracing_test.go and add tracing hook tests (#3270)
Co-authored-by: Nedyalko Dyakov <[email protected]>
1 parent acbf4a6 commit 021faad

File tree

4 files changed

+244
-67
lines changed

4 files changed

+244
-67
lines changed

extra/redisotel/go.mod

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@ require (
1616
)
1717

1818
require (
19-
github.com/cespare/xxhash/v2 v2.2.0 // indirect
19+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2020
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
2121
github.com/go-logr/logr v1.4.1 // indirect
2222
github.com/go-logr/stdr v1.2.2 // indirect
2323
golang.org/x/sys v0.16.0 // indirect
2424
)
2525

26-
retract (
27-
v9.5.3 // This version was accidentally released.
28-
)
26+
retract v9.5.3 // This version was accidentally released.

extra/redisotel/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
22
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
3-
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
4-
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
3+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
4+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
55
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
66
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
77
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=

extra/redisotel/redisotel_test.go

Lines changed: 0 additions & 61 deletions
This file was deleted.

extra/redisotel/tracing_test.go

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
package redisotel
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net"
7+
"testing"
8+
9+
"go.opentelemetry.io/otel/attribute"
10+
"go.opentelemetry.io/otel/codes"
11+
"go.opentelemetry.io/otel/sdk/trace/tracetest"
12+
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
13+
14+
"go.opentelemetry.io/otel"
15+
sdktrace "go.opentelemetry.io/otel/sdk/trace"
16+
"go.opentelemetry.io/otel/trace"
17+
18+
"github.com/redis/go-redis/v9"
19+
)
20+
21+
type providerFunc func(name string, opts ...trace.TracerOption) trace.TracerProvider
22+
23+
func (fn providerFunc) TracerProvider(name string, opts ...trace.TracerOption) trace.TracerProvider {
24+
return fn(name, opts...)
25+
}
26+
27+
func TestNewWithTracerProvider(t *testing.T) {
28+
invoked := false
29+
30+
tp := providerFunc(func(name string, opts ...trace.TracerOption) trace.TracerProvider {
31+
invoked = true
32+
return otel.GetTracerProvider()
33+
})
34+
35+
_ = newTracingHook("redis-hook", WithTracerProvider(tp.TracerProvider("redis-test")))
36+
37+
if !invoked {
38+
t.Fatalf("did not call custom TraceProvider")
39+
}
40+
}
41+
42+
func TestWithDBStatement(t *testing.T) {
43+
provider := sdktrace.NewTracerProvider()
44+
hook := newTracingHook(
45+
"",
46+
WithTracerProvider(provider),
47+
WithDBStatement(false),
48+
)
49+
ctx, span := provider.Tracer("redis-test").Start(context.TODO(), "redis-test")
50+
cmd := redis.NewCmd(ctx, "ping")
51+
defer span.End()
52+
53+
processHook := hook.ProcessHook(func(ctx context.Context, cmd redis.Cmder) error {
54+
attrs := trace.SpanFromContext(ctx).(sdktrace.ReadOnlySpan).Attributes()
55+
for _, attr := range attrs {
56+
if attr.Key == semconv.DBStatementKey {
57+
t.Fatal("Attribute with db statement should not exist")
58+
}
59+
}
60+
return nil
61+
})
62+
err := processHook(ctx, cmd)
63+
if err != nil {
64+
t.Fatal(err)
65+
}
66+
}
67+
68+
func TestTracingHook_DialHook(t *testing.T) {
69+
imsb := tracetest.NewInMemoryExporter()
70+
provider := sdktrace.NewTracerProvider(sdktrace.WithSyncer(imsb))
71+
hook := newTracingHook(
72+
"redis://localhost:6379",
73+
WithTracerProvider(provider),
74+
)
75+
76+
tests := []struct {
77+
name string
78+
errTest error
79+
}{
80+
{"nil error", nil},
81+
{"test error", fmt.Errorf("test error")},
82+
}
83+
84+
for _, tt := range tests {
85+
t.Run(tt.name, func(t *testing.T) {
86+
defer imsb.Reset()
87+
88+
dialHook := hook.DialHook(func(ctx context.Context, network, addr string) (conn net.Conn, err error) {
89+
return nil, tt.errTest
90+
})
91+
if _, err := dialHook(context.Background(), "tcp", "localhost:6379"); err != tt.errTest {
92+
t.Fatal(err)
93+
}
94+
95+
assertEqual(t, 1, len(imsb.GetSpans()))
96+
97+
spanData := imsb.GetSpans()[0]
98+
assertEqual(t, instrumName, spanData.InstrumentationLibrary.Name)
99+
assertEqual(t, "redis.dial", spanData.Name)
100+
assertEqual(t, trace.SpanKindClient, spanData.SpanKind)
101+
assertAttributeContains(t, spanData.Attributes, semconv.DBSystemRedis)
102+
assertAttributeContains(t, spanData.Attributes, semconv.DBConnectionStringKey.String("redis://localhost:6379"))
103+
104+
if tt.errTest == nil {
105+
assertEqual(t, 0, len(spanData.Events))
106+
assertEqual(t, codes.Unset, spanData.Status.Code)
107+
assertEqual(t, "", spanData.Status.Description)
108+
return
109+
}
110+
111+
assertEqual(t, 1, len(spanData.Events))
112+
assertAttributeContains(t, spanData.Events[0].Attributes, semconv.ExceptionTypeKey.String("*errors.errorString"))
113+
assertAttributeContains(t, spanData.Events[0].Attributes, semconv.ExceptionMessageKey.String(tt.errTest.Error()))
114+
assertEqual(t, codes.Error, spanData.Status.Code)
115+
assertEqual(t, tt.errTest.Error(), spanData.Status.Description)
116+
})
117+
}
118+
}
119+
120+
func TestTracingHook_ProcessHook(t *testing.T) {
121+
imsb := tracetest.NewInMemoryExporter()
122+
provider := sdktrace.NewTracerProvider(sdktrace.WithSyncer(imsb))
123+
hook := newTracingHook(
124+
"redis://localhost:6379",
125+
WithTracerProvider(provider),
126+
)
127+
128+
tests := []struct {
129+
name string
130+
errTest error
131+
}{
132+
{"nil error", nil},
133+
{"test error", fmt.Errorf("test error")},
134+
}
135+
136+
for _, tt := range tests {
137+
t.Run(tt.name, func(t *testing.T) {
138+
defer imsb.Reset()
139+
140+
cmd := redis.NewCmd(context.Background(), "ping")
141+
processHook := hook.ProcessHook(func(ctx context.Context, cmd redis.Cmder) error {
142+
return tt.errTest
143+
})
144+
assertEqual(t, tt.errTest, processHook(context.Background(), cmd))
145+
assertEqual(t, 1, len(imsb.GetSpans()))
146+
147+
spanData := imsb.GetSpans()[0]
148+
assertEqual(t, instrumName, spanData.InstrumentationLibrary.Name)
149+
assertEqual(t, "ping", spanData.Name)
150+
assertEqual(t, trace.SpanKindClient, spanData.SpanKind)
151+
assertAttributeContains(t, spanData.Attributes, semconv.DBSystemRedis)
152+
assertAttributeContains(t, spanData.Attributes, semconv.DBConnectionStringKey.String("redis://localhost:6379"))
153+
assertAttributeContains(t, spanData.Attributes, semconv.DBStatementKey.String("ping"))
154+
155+
if tt.errTest == nil {
156+
assertEqual(t, 0, len(spanData.Events))
157+
assertEqual(t, codes.Unset, spanData.Status.Code)
158+
assertEqual(t, "", spanData.Status.Description)
159+
return
160+
}
161+
162+
assertEqual(t, 1, len(spanData.Events))
163+
assertAttributeContains(t, spanData.Events[0].Attributes, semconv.ExceptionTypeKey.String("*errors.errorString"))
164+
assertAttributeContains(t, spanData.Events[0].Attributes, semconv.ExceptionMessageKey.String(tt.errTest.Error()))
165+
assertEqual(t, codes.Error, spanData.Status.Code)
166+
assertEqual(t, tt.errTest.Error(), spanData.Status.Description)
167+
})
168+
}
169+
}
170+
171+
func TestTracingHook_ProcessPipelineHook(t *testing.T) {
172+
imsb := tracetest.NewInMemoryExporter()
173+
provider := sdktrace.NewTracerProvider(sdktrace.WithSyncer(imsb))
174+
hook := newTracingHook(
175+
"redis://localhost:6379",
176+
WithTracerProvider(provider),
177+
)
178+
179+
tests := []struct {
180+
name string
181+
errTest error
182+
}{
183+
{"nil error", nil},
184+
{"test error", fmt.Errorf("test error")},
185+
}
186+
187+
for _, tt := range tests {
188+
t.Run(tt.name, func(t *testing.T) {
189+
defer imsb.Reset()
190+
191+
cmds := []redis.Cmder{
192+
redis.NewCmd(context.Background(), "ping"),
193+
redis.NewCmd(context.Background(), "ping"),
194+
}
195+
processHook := hook.ProcessPipelineHook(func(ctx context.Context, cmds []redis.Cmder) error {
196+
return tt.errTest
197+
})
198+
assertEqual(t, tt.errTest, processHook(context.Background(), cmds))
199+
assertEqual(t, 1, len(imsb.GetSpans()))
200+
201+
spanData := imsb.GetSpans()[0]
202+
assertEqual(t, instrumName, spanData.InstrumentationLibrary.Name)
203+
assertEqual(t, "redis.pipeline ping", spanData.Name)
204+
assertEqual(t, trace.SpanKindClient, spanData.SpanKind)
205+
assertAttributeContains(t, spanData.Attributes, semconv.DBSystemRedis)
206+
assertAttributeContains(t, spanData.Attributes, semconv.DBConnectionStringKey.String("redis://localhost:6379"))
207+
assertAttributeContains(t, spanData.Attributes, semconv.DBStatementKey.String("ping\nping"))
208+
209+
if tt.errTest == nil {
210+
assertEqual(t, 0, len(spanData.Events))
211+
assertEqual(t, codes.Unset, spanData.Status.Code)
212+
assertEqual(t, "", spanData.Status.Description)
213+
return
214+
}
215+
216+
assertEqual(t, 1, len(spanData.Events))
217+
assertAttributeContains(t, spanData.Events[0].Attributes, semconv.ExceptionTypeKey.String("*errors.errorString"))
218+
assertAttributeContains(t, spanData.Events[0].Attributes, semconv.ExceptionMessageKey.String(tt.errTest.Error()))
219+
assertEqual(t, codes.Error, spanData.Status.Code)
220+
assertEqual(t, tt.errTest.Error(), spanData.Status.Description)
221+
})
222+
}
223+
}
224+
225+
func assertEqual(t *testing.T, expected, actual interface{}) {
226+
t.Helper()
227+
if expected != actual {
228+
t.Fatalf("expected %v, got %v", expected, actual)
229+
}
230+
}
231+
232+
func assertAttributeContains(t *testing.T, attrs []attribute.KeyValue, attr attribute.KeyValue) {
233+
t.Helper()
234+
for _, a := range attrs {
235+
if a == attr {
236+
return
237+
}
238+
}
239+
t.Fatalf("attribute %v not found", attr)
240+
}

0 commit comments

Comments
 (0)