github.com/ethersphere/bee/v2@v2.2.0/pkg/tracing/tracing_test.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tracing_test 6 7 import ( 8 "bytes" 9 "context" 10 "encoding/json" 11 "fmt" 12 "testing" 13 14 "github.com/ethersphere/bee/v2/pkg/log" 15 "github.com/ethersphere/bee/v2/pkg/p2p" 16 "github.com/ethersphere/bee/v2/pkg/tracing" 17 "github.com/ethersphere/bee/v2/pkg/util/testutil" 18 "github.com/uber/jaeger-client-go" 19 ) 20 21 func TestSpanFromHeaders(t *testing.T) { 22 t.Parallel() 23 24 tracer := newTracer(t) 25 26 span, _, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation", nil) 27 defer span.Finish() 28 29 headers := make(p2p.Headers) 30 if err := tracer.AddContextHeader(ctx, headers); err != nil { 31 t.Fatal(err) 32 } 33 34 gotSpanContext, err := tracer.FromHeaders(headers) 35 if err != nil { 36 t.Fatal(err) 37 } 38 39 if fmt.Sprint(gotSpanContext) == "" { 40 t.Fatal("got empty span context") 41 } 42 43 wantSpanContext := span.Context() 44 if fmt.Sprint(wantSpanContext) == "" { 45 t.Fatal("got empty start span context") 46 } 47 48 if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) { 49 t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext) 50 } 51 } 52 53 func TestSpanWithContextFromHeaders(t *testing.T) { 54 t.Parallel() 55 56 tracer := newTracer(t) 57 58 span, _, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation", nil) 59 defer span.Finish() 60 61 headers := make(p2p.Headers) 62 if err := tracer.AddContextHeader(ctx, headers); err != nil { 63 t.Fatal(err) 64 } 65 66 ctx, err := tracer.WithContextFromHeaders(context.Background(), headers) 67 if err != nil { 68 t.Fatal(err) 69 } 70 71 gotSpanContext := tracing.FromContext(ctx) 72 if fmt.Sprint(gotSpanContext) == "" { 73 t.Fatal("got empty span context") 74 } 75 76 wantSpanContext := span.Context() 77 if fmt.Sprint(wantSpanContext) == "" { 78 t.Fatal("got empty start span context") 79 } 80 81 if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) { 82 t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext) 83 } 84 } 85 86 func TestFromContext(t *testing.T) { 87 t.Parallel() 88 89 tracer := newTracer(t) 90 91 span, _, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation", nil) 92 defer span.Finish() 93 94 wantSpanContext := span.Context() 95 if fmt.Sprint(wantSpanContext) == "" { 96 t.Fatal("got empty start span context") 97 } 98 99 gotSpanContext := tracing.FromContext(ctx) 100 if fmt.Sprint(gotSpanContext) == "" { 101 t.Fatal("got empty span context") 102 } 103 104 if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) { 105 t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext) 106 } 107 } 108 109 func TestWithContext(t *testing.T) { 110 t.Parallel() 111 112 tracer := newTracer(t) 113 114 span, _, _ := tracer.StartSpanFromContext(context.Background(), "some-operation", nil) 115 defer span.Finish() 116 117 wantSpanContext := span.Context() 118 if fmt.Sprint(wantSpanContext) == "" { 119 t.Fatal("got empty start span context") 120 } 121 122 ctx := tracing.WithContext(context.Background(), span.Context()) 123 124 gotSpanContext := tracing.FromContext(ctx) 125 if fmt.Sprint(gotSpanContext) == "" { 126 t.Fatal("got empty span context") 127 } 128 129 if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) { 130 t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext) 131 } 132 } 133 134 func TestStartSpanFromContext_logger(t *testing.T) { 135 t.Parallel() 136 137 tracer := newTracer(t) 138 139 buf := new(bytes.Buffer) 140 141 span, logger, _ := tracer.StartSpanFromContext(context.Background(), "some-operation", log.NewLogger("test", log.WithSink(buf), log.WithJSONOutput())) 142 defer span.Finish() 143 144 wantTraceID := span.Context().(jaeger.SpanContext).TraceID() 145 146 logger.Info("msg") 147 data := make(map[string]interface{}) 148 if err := json.Unmarshal(buf.Bytes(), &data); err != nil { 149 t.Fatalf("unexpected error: %v", err) 150 } 151 152 v, ok := data[tracing.LogField] 153 if !ok { 154 t.Fatalf("log field %q not found", tracing.LogField) 155 } 156 157 gotTraceID, ok := v.(string) 158 if !ok { 159 t.Fatalf("log field %q is not string", tracing.LogField) 160 } 161 162 if gotTraceID != wantTraceID.String() { 163 t.Errorf("got trace id %q, want %q", gotTraceID, wantTraceID.String()) 164 } 165 } 166 167 func TestStartSpanFromContext_nilLogger(t *testing.T) { 168 t.Parallel() 169 170 tracer := newTracer(t) 171 172 span, logger, _ := tracer.StartSpanFromContext(context.Background(), "some-operation", nil) 173 defer span.Finish() 174 175 if logger != nil { 176 t.Error("logger is not nil") 177 } 178 } 179 180 func TestNewLoggerWithTraceID(t *testing.T) { 181 t.Parallel() 182 183 tracer := newTracer(t) 184 185 span, _, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation", nil) 186 defer span.Finish() 187 188 buf := new(bytes.Buffer) 189 190 logger := tracing.NewLoggerWithTraceID(ctx, log.NewLogger("test", log.WithSink(buf), log.WithJSONOutput())) 191 192 wantTraceID := span.Context().(jaeger.SpanContext).TraceID() 193 194 logger.Info("msg") 195 data := make(map[string]interface{}) 196 if err := json.Unmarshal(buf.Bytes(), &data); err != nil { 197 t.Fatalf("unexpected error: %v", err) 198 } 199 200 v, ok := data[tracing.LogField] 201 if !ok { 202 t.Fatalf("log field %q not found", tracing.LogField) 203 } 204 205 gotTraceID, ok := v.(string) 206 if !ok { 207 t.Fatalf("log field %q is not string", tracing.LogField) 208 } 209 210 if gotTraceID != wantTraceID.String() { 211 t.Errorf("got trace id %q, want %q", gotTraceID, wantTraceID.String()) 212 } 213 } 214 215 func TestNewLoggerWithTraceID_nilLogger(t *testing.T) { 216 t.Parallel() 217 218 tracer := newTracer(t) 219 220 span, _, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation", nil) 221 defer span.Finish() 222 223 logger := tracing.NewLoggerWithTraceID(ctx, nil) 224 225 if logger != nil { 226 t.Error("logger is not nil") 227 } 228 } 229 230 func newTracer(t *testing.T) *tracing.Tracer { 231 t.Helper() 232 233 tracer, closer, err := tracing.NewTracer(&tracing.Options{ 234 Enabled: true, 235 ServiceName: "test", 236 }) 237 if err != nil { 238 t.Fatal(err) 239 } 240 testutil.CleanupCloser(t, closer) 241 242 return tracer 243 }