go.undefinedlabs.com/scopeagent@v0.4.2/tracer/propagation_test.go (about)

     1  package tracer_test
     2  
     3  import (
     4  	"bytes"
     5  	"net/http"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/davecgh/go-spew/spew"
    11  	"github.com/google/uuid"
    12  	opentracing "github.com/opentracing/opentracing-go"
    13  	"go.undefinedlabs.com/scopeagent/tracer"
    14  )
    15  
    16  type verbatimCarrier struct {
    17  	tracer.SpanContext
    18  	b map[string]string
    19  }
    20  
    21  var _ tracer.DelegatingCarrier = &verbatimCarrier{}
    22  
    23  func (vc *verbatimCarrier) SetBaggageItem(k, v string) {
    24  	vc.b[k] = v
    25  }
    26  
    27  func (vc *verbatimCarrier) GetBaggage(f func(string, string)) {
    28  	for k, v := range vc.b {
    29  		f(k, v)
    30  	}
    31  }
    32  
    33  func (vc *verbatimCarrier) SetState(tID uuid.UUID, sID uint64, sampled bool) {
    34  	vc.SpanContext = tracer.SpanContext{TraceID: tID, SpanID: sID, Sampled: sampled}
    35  }
    36  
    37  func (vc *verbatimCarrier) State() (traceID uuid.UUID, spanID uint64, sampled bool) {
    38  	return vc.SpanContext.TraceID, vc.SpanContext.SpanID, vc.SpanContext.Sampled
    39  }
    40  
    41  func TestSpanPropagator(t *testing.T) {
    42  	const op = "test"
    43  	recorder := tracer.NewInMemoryRecorder()
    44  	tr := tracer.New(recorder)
    45  
    46  	sp := tr.StartSpan(op)
    47  	sp.SetBaggageItem("foo", "bar")
    48  
    49  	tmc := opentracing.HTTPHeadersCarrier(http.Header{})
    50  	tests := []struct {
    51  		typ, carrier interface{}
    52  	}{
    53  		{tracer.Delegator, tracer.DelegatingCarrier(&verbatimCarrier{b: map[string]string{}})},
    54  		{opentracing.Binary, &bytes.Buffer{}},
    55  		{opentracing.HTTPHeaders, tmc},
    56  		{opentracing.TextMap, tmc},
    57  	}
    58  
    59  	for i, test := range tests {
    60  		if err := tr.Inject(sp.Context(), test.typ, test.carrier); err != nil {
    61  			t.Fatalf("%d: %v", i, err)
    62  		}
    63  		injectedContext, err := tr.Extract(test.typ, test.carrier)
    64  		if err != nil {
    65  			t.Fatalf("%d: %v", i, err)
    66  		}
    67  		child := tr.StartSpan(
    68  			op,
    69  			opentracing.ChildOf(injectedContext))
    70  		child.Finish()
    71  	}
    72  	sp.Finish()
    73  
    74  	spans := recorder.GetSpans()
    75  	if a, e := len(spans), len(tests)+1; a != e {
    76  		t.Fatalf("expected %d spans, got %d", e, a)
    77  	}
    78  
    79  	// The last span is the original one.
    80  	exp, spans := spans[len(spans)-1], spans[:len(spans)-1]
    81  	exp.Duration = time.Duration(123)
    82  	exp.Start = time.Time{}.Add(1)
    83  
    84  	for i, sp := range spans {
    85  		if a, e := sp.ParentSpanID, exp.Context.SpanID; a != e {
    86  			t.Fatalf("%d: ParentSpanID %d does not match expectation %d", i, a, e)
    87  		} else {
    88  			// Prepare for comparison.
    89  			sp.Context.SpanID, sp.ParentSpanID = exp.Context.SpanID, 0
    90  			sp.Duration, sp.Start = exp.Duration, exp.Start
    91  		}
    92  		if a, e := sp.Context.TraceID, exp.Context.TraceID; a != e {
    93  			t.Fatalf("%d: TraceID changed from %d to %d", i, e, a)
    94  		}
    95  		if !reflect.DeepEqual(exp, sp) {
    96  			t.Fatalf("%d: wanted %+v, got %+v", i, spew.Sdump(exp), spew.Sdump(sp))
    97  		}
    98  	}
    99  }