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  }