...

Source file src/github.com/opentracing/opentracing-go/mocktracer/mocktracer_test.go

Documentation: github.com/opentracing/opentracing-go/mocktracer

     1  package mocktracer
     2  
     3  import (
     4  	"net/http"
     5  	"reflect"
     6  	"sync"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/opentracing/opentracing-go"
    14  	"github.com/opentracing/opentracing-go/ext"
    15  	"github.com/opentracing/opentracing-go/log"
    16  )
    17  
    18  func TestMockTracer_StartSpan(t *testing.T) {
    19  	tracer := New()
    20  	span1 := tracer.StartSpan(
    21  		"a",
    22  		opentracing.Tags(map[string]interface{}{"x": "y"}))
    23  
    24  	span2 := span1.Tracer().StartSpan(
    25  		"", opentracing.ChildOf(span1.Context()))
    26  	span2.Finish()
    27  	span1.Finish()
    28  	finishedSpans := tracer.FinishedSpans()
    29  	unfinishedSpans := tracer.UnfinishedSpans()
    30  	assert.Equal(t, 2, len(finishedSpans))
    31  	assert.Equal(t, 0, len(unfinishedSpans))
    32  
    33  	parent := finishedSpans[1]
    34  	child := finishedSpans[0]
    35  	assert.Equal(t, map[string]interface{}{"x": "y"}, parent.Tags())
    36  	assert.Equal(t, child.ParentID, parent.Context().(MockSpanContext).SpanID)
    37  }
    38  
    39  func TestMockSpan_SetOperationName(t *testing.T) {
    40  	tracer := New()
    41  	span := tracer.StartSpan("")
    42  	span.SetOperationName("x")
    43  	assert.Equal(t, "x", span.(*MockSpan).OperationName)
    44  }
    45  
    46  func TestMockSpanContext_Baggage(t *testing.T) {
    47  	tracer := New()
    48  	span := tracer.StartSpan("x")
    49  	span.SetBaggageItem("x", "y")
    50  	assert.Equal(t, "y", span.BaggageItem("x"))
    51  	assert.Equal(t, map[string]string{"x": "y"}, span.Context().(MockSpanContext).Baggage)
    52  
    53  	baggage := make(map[string]string)
    54  	span.Context().ForeachBaggageItem(func(k, v string) bool {
    55  		baggage[k] = v
    56  		return true
    57  	})
    58  	assert.Equal(t, map[string]string{"x": "y"}, baggage)
    59  
    60  	span.SetBaggageItem("a", "b")
    61  	baggage = make(map[string]string)
    62  	span.Context().ForeachBaggageItem(func(k, v string) bool {
    63  		baggage[k] = v
    64  		return false // exit early
    65  	})
    66  	assert.Equal(t, 2, len(span.Context().(MockSpanContext).Baggage))
    67  	assert.Equal(t, 1, len(baggage))
    68  }
    69  
    70  func TestMockSpan_Tag(t *testing.T) {
    71  	tracer := New()
    72  	span := tracer.StartSpan("x")
    73  	span.SetTag("x", "y")
    74  	assert.Equal(t, "y", span.(*MockSpan).Tag("x"))
    75  }
    76  
    77  func TestMockSpan_Tags(t *testing.T) {
    78  	tracer := New()
    79  	span := tracer.StartSpan("x")
    80  	span.SetTag("x", "y")
    81  	assert.Equal(t, map[string]interface{}{"x": "y"}, span.(*MockSpan).Tags())
    82  }
    83  
    84  func TestMockTracer_FinishedSpans_and_Reset(t *testing.T) {
    85  	tracer := New()
    86  	span := tracer.StartSpan("x")
    87  	span.SetTag("x", "y")
    88  	assert.Len(t, tracer.UnfinishedSpans(), 1)
    89  	span.Finish()
    90  	spans := tracer.FinishedSpans()
    91  	assert.Len(t, spans, 1)
    92  	assert.Len(t, tracer.UnfinishedSpans(), 0)
    93  	assert.Equal(t, map[string]interface{}{"x": "y"}, spans[0].Tags())
    94  
    95  	tracer.StartSpan("z")
    96  	tracer.Reset()
    97  	spans = tracer.FinishedSpans()
    98  	assert.Len(t, spans, 0)
    99  	assert.Len(t, tracer.UnfinishedSpans(), 0)
   100  }
   101  
   102  func zeroOutTimestamps(recs []MockLogRecord) {
   103  	for i := range recs {
   104  		recs[i].Timestamp = time.Time{}
   105  	}
   106  }
   107  
   108  func TestMockSpan_LogKV(t *testing.T) {
   109  	tracer := New()
   110  	span := tracer.StartSpan("s")
   111  	span.LogKV("key0", "string0")
   112  	span.LogKV("key1", "string1", "key2", uint32(42))
   113  	span.Finish()
   114  	spans := tracer.FinishedSpans()
   115  	assert.Equal(t, 1, len(spans))
   116  	actual := spans[0].Logs()
   117  	zeroOutTimestamps(actual)
   118  	assert.Equal(t, []MockLogRecord{
   119  		MockLogRecord{
   120  			Fields: []MockKeyValue{
   121  				MockKeyValue{Key: "key0", ValueKind: reflect.String, ValueString: "string0"},
   122  			},
   123  		},
   124  		MockLogRecord{
   125  			Fields: []MockKeyValue{
   126  				MockKeyValue{Key: "key1", ValueKind: reflect.String, ValueString: "string1"},
   127  				MockKeyValue{Key: "key2", ValueKind: reflect.Uint32, ValueString: "42"},
   128  			},
   129  		},
   130  	}, actual)
   131  }
   132  
   133  func TestMockSpan_LogFields(t *testing.T) {
   134  	tracer := New()
   135  	span := tracer.StartSpan("s")
   136  	span.LogFields(log.String("key0", "string0"))
   137  	span.LogFields(log.String("key1", "string1"), log.Uint32("key2", uint32(42)))
   138  	span.LogFields(log.Lazy(func(fv log.Encoder) {
   139  		fv.EmitInt("key_lazy", 12)
   140  	}))
   141  	span.FinishWithOptions(opentracing.FinishOptions{
   142  		LogRecords: []opentracing.LogRecord{
   143  			{Timestamp: time.Now(), Fields: []log.Field{log.String("key9", "finish")}},
   144  		}})
   145  	spans := tracer.FinishedSpans()
   146  	assert.Equal(t, 1, len(spans))
   147  	actual := spans[0].Logs()
   148  	zeroOutTimestamps(actual)
   149  	assert.Equal(t, []MockLogRecord{
   150  		MockLogRecord{
   151  			Fields: []MockKeyValue{
   152  				MockKeyValue{Key: "key0", ValueKind: reflect.String, ValueString: "string0"},
   153  			},
   154  		},
   155  		MockLogRecord{
   156  			Fields: []MockKeyValue{
   157  				MockKeyValue{Key: "key1", ValueKind: reflect.String, ValueString: "string1"},
   158  				MockKeyValue{Key: "key2", ValueKind: reflect.Uint32, ValueString: "42"},
   159  			},
   160  		},
   161  		MockLogRecord{
   162  			Fields: []MockKeyValue{
   163  				// Note that the LazyLogger gets to control the key as well as the value.
   164  				MockKeyValue{Key: "key_lazy", ValueKind: reflect.Int, ValueString: "12"},
   165  			},
   166  		},
   167  		MockLogRecord{
   168  			Fields: []MockKeyValue{
   169  				MockKeyValue{Key: "key9", ValueKind: reflect.String, ValueString: "finish"},
   170  			},
   171  		},
   172  	}, actual)
   173  }
   174  
   175  func TestMockSpan_DeprecatedLogs(t *testing.T) {
   176  	tracer := New()
   177  	span := tracer.StartSpan("x")
   178  	span.LogEvent("x")
   179  	span.LogEventWithPayload("y", "z")
   180  	span.LogEvent("a")
   181  	span.FinishWithOptions(opentracing.FinishOptions{
   182  		BulkLogData: []opentracing.LogData{{Event: "f"}}})
   183  	spans := tracer.FinishedSpans()
   184  	assert.Equal(t, 1, len(spans))
   185  	actual := spans[0].Logs()
   186  	zeroOutTimestamps(actual)
   187  	assert.Equal(t, []MockLogRecord{
   188  		MockLogRecord{
   189  			Fields: []MockKeyValue{
   190  				MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "x"},
   191  			},
   192  		},
   193  		MockLogRecord{
   194  			Fields: []MockKeyValue{
   195  				MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "y"},
   196  				MockKeyValue{Key: "payload", ValueKind: reflect.String, ValueString: "z"},
   197  			},
   198  		},
   199  		MockLogRecord{
   200  			Fields: []MockKeyValue{
   201  				MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "a"},
   202  			},
   203  		},
   204  		MockLogRecord{
   205  			Fields: []MockKeyValue{
   206  				MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "f"},
   207  			},
   208  		},
   209  	}, actual)
   210  }
   211  
   212  func TestMockTracer_Propagation(t *testing.T) {
   213  	textCarrier := func() interface{} {
   214  		return opentracing.TextMapCarrier(make(map[string]string))
   215  	}
   216  	textLen := func(c interface{}) int {
   217  		return len(c.(opentracing.TextMapCarrier))
   218  	}
   219  
   220  	httpCarrier := func() interface{} {
   221  		httpHeaders := http.Header(make(map[string][]string))
   222  		return opentracing.HTTPHeadersCarrier(httpHeaders)
   223  	}
   224  	httpLen := func(c interface{}) int {
   225  		return len(c.(opentracing.HTTPHeadersCarrier))
   226  	}
   227  
   228  	tests := []struct {
   229  		sampled bool
   230  		format  opentracing.BuiltinFormat
   231  		carrier func() interface{}
   232  		len     func(interface{}) int
   233  	}{
   234  		{sampled: true, format: opentracing.TextMap, carrier: textCarrier, len: textLen},
   235  		{sampled: false, format: opentracing.TextMap, carrier: textCarrier, len: textLen},
   236  		{sampled: true, format: opentracing.HTTPHeaders, carrier: httpCarrier, len: httpLen},
   237  		{sampled: false, format: opentracing.HTTPHeaders, carrier: httpCarrier, len: httpLen},
   238  	}
   239  	for _, test := range tests {
   240  		tracer := New()
   241  		span := tracer.StartSpan("x")
   242  		span.SetBaggageItem("x", "y:z") // colon should be URL encoded as %3A
   243  		if !test.sampled {
   244  			ext.SamplingPriority.Set(span, 0)
   245  		}
   246  		mSpan := span.(*MockSpan)
   247  
   248  		assert.Equal(t, opentracing.ErrUnsupportedFormat,
   249  			tracer.Inject(span.Context(), opentracing.Binary, nil))
   250  		assert.Equal(t, opentracing.ErrInvalidCarrier,
   251  			tracer.Inject(span.Context(), opentracing.TextMap, span))
   252  
   253  		carrier := test.carrier()
   254  
   255  		err := tracer.Inject(span.Context(), test.format, carrier)
   256  		require.NoError(t, err)
   257  		assert.Equal(t, 4, test.len(carrier), "expect baggage + 2 ids + sampled")
   258  		if test.format == opentracing.HTTPHeaders {
   259  			c := carrier.(opentracing.HTTPHeadersCarrier)
   260  			assert.Equal(t, "y%3Az", c["Mockpfx-Baggage-X"][0])
   261  		}
   262  
   263  		_, err = tracer.Extract(opentracing.Binary, nil)
   264  		assert.Equal(t, opentracing.ErrUnsupportedFormat, err)
   265  		_, err = tracer.Extract(opentracing.TextMap, tracer)
   266  		assert.Equal(t, opentracing.ErrInvalidCarrier, err)
   267  
   268  		extractedContext, err := tracer.Extract(test.format, carrier)
   269  		require.NoError(t, err)
   270  		assert.Equal(t, mSpan.SpanContext.TraceID, extractedContext.(MockSpanContext).TraceID)
   271  		assert.Equal(t, mSpan.SpanContext.SpanID, extractedContext.(MockSpanContext).SpanID)
   272  		assert.Equal(t, test.sampled, extractedContext.(MockSpanContext).Sampled)
   273  		assert.Equal(t, "y:z", extractedContext.(MockSpanContext).Baggage["x"])
   274  	}
   275  }
   276  
   277  func TestMockSpan_Races(t *testing.T) {
   278  	span := New().StartSpan("x")
   279  	var wg sync.WaitGroup
   280  	wg.Add(2)
   281  	go func() {
   282  		defer wg.Done()
   283  		span.SetBaggageItem("test_key", "test_value")
   284  	}()
   285  	go func() {
   286  		defer wg.Done()
   287  		span.Context()
   288  	}()
   289  	wg.Wait()
   290  }
   291  

View as plain text