...

Source file src/github.com/opentracing/opentracing-go/testtracer_test.go

Documentation: github.com/opentracing/opentracing-go

     1  package opentracing
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/opentracing/opentracing-go/log"
     9  )
    10  
    11  const testHTTPHeaderPrefix = "testprefix-"
    12  
    13  // testTracer is a most-noop Tracer implementation that makes it possible for
    14  // unittests to verify whether certain methods were / were not called.
    15  type testTracer struct{}
    16  
    17  var fakeIDSource = 1
    18  
    19  func nextFakeID() int {
    20  	fakeIDSource++
    21  	return fakeIDSource
    22  }
    23  
    24  type testSpanContext struct {
    25  	HasParent bool
    26  	FakeID    int
    27  }
    28  
    29  func (n testSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
    30  
    31  type testSpan struct {
    32  	spanContext   testSpanContext
    33  	OperationName string
    34  	StartTime     time.Time
    35  	Tags          map[string]interface{}
    36  }
    37  
    38  func (n testSpan) Equal(os Span) bool {
    39  	other, ok := os.(testSpan)
    40  	if !ok {
    41  		return false
    42  	}
    43  	if n.spanContext != other.spanContext {
    44  		return false
    45  	}
    46  	if n.OperationName != other.OperationName {
    47  		return false
    48  	}
    49  	if !n.StartTime.Equal(other.StartTime) {
    50  		return false
    51  	}
    52  	if len(n.Tags) != len(other.Tags) {
    53  		return false
    54  	}
    55  
    56  	for k, v := range n.Tags {
    57  		if ov, ok := other.Tags[k]; !ok || ov != v {
    58  			return false
    59  		}
    60  	}
    61  
    62  	return true
    63  }
    64  
    65  // testSpan:
    66  func (n testSpan) Context() SpanContext                                  { return n.spanContext }
    67  func (n testSpan) SetTag(key string, value interface{}) Span             { return n }
    68  func (n testSpan) Finish()                                               {}
    69  func (n testSpan) FinishWithOptions(opts FinishOptions)                  {}
    70  func (n testSpan) LogFields(fields ...log.Field)                         {}
    71  func (n testSpan) LogKV(kvs ...interface{})                              {}
    72  func (n testSpan) SetOperationName(operationName string) Span            { return n }
    73  func (n testSpan) Tracer() Tracer                                        { return testTracer{} }
    74  func (n testSpan) SetBaggageItem(key, val string) Span                   { return n }
    75  func (n testSpan) BaggageItem(key string) string                         { return "" }
    76  func (n testSpan) LogEvent(event string)                                 {}
    77  func (n testSpan) LogEventWithPayload(event string, payload interface{}) {}
    78  func (n testSpan) Log(data LogData)                                      {}
    79  
    80  // StartSpan belongs to the Tracer interface.
    81  func (n testTracer) StartSpan(operationName string, opts ...StartSpanOption) Span {
    82  	sso := StartSpanOptions{}
    83  	for _, o := range opts {
    84  		o.Apply(&sso)
    85  	}
    86  	return n.startSpanWithOptions(operationName, sso)
    87  }
    88  
    89  func (n testTracer) startSpanWithOptions(name string, opts StartSpanOptions) Span {
    90  	fakeID := nextFakeID()
    91  	if len(opts.References) > 0 {
    92  		fakeID = opts.References[0].ReferencedContext.(testSpanContext).FakeID
    93  	}
    94  
    95  	return testSpan{
    96  		OperationName: name,
    97  		StartTime:     opts.StartTime,
    98  		Tags:          opts.Tags,
    99  		spanContext: testSpanContext{
   100  			HasParent: len(opts.References) > 0,
   101  			FakeID:    fakeID,
   102  		},
   103  	}
   104  }
   105  
   106  // Inject belongs to the Tracer interface.
   107  func (n testTracer) Inject(sp SpanContext, format interface{}, carrier interface{}) error {
   108  	spanContext := sp.(testSpanContext)
   109  	switch format {
   110  	case HTTPHeaders, TextMap:
   111  		carrier.(TextMapWriter).Set(testHTTPHeaderPrefix+"fakeid", strconv.Itoa(spanContext.FakeID))
   112  		return nil
   113  	}
   114  	return ErrUnsupportedFormat
   115  }
   116  
   117  // Extract belongs to the Tracer interface.
   118  func (n testTracer) Extract(format interface{}, carrier interface{}) (SpanContext, error) {
   119  	switch format {
   120  	case HTTPHeaders, TextMap:
   121  		// Just for testing purposes... generally not a worthwhile thing to
   122  		// propagate.
   123  		sm := testSpanContext{}
   124  		err := carrier.(TextMapReader).ForeachKey(func(key, val string) error {
   125  			switch strings.ToLower(key) {
   126  			case testHTTPHeaderPrefix + "fakeid":
   127  				i, err := strconv.Atoi(val)
   128  				if err != nil {
   129  					return err
   130  				}
   131  				sm.FakeID = i
   132  			}
   133  			return nil
   134  		})
   135  		return sm, err
   136  	}
   137  	return nil, ErrSpanContextNotFound
   138  }
   139  

View as plain text