github.com/mier85/go-sensor@v1.30.1-0.20220920111756-9bf41b3bc7e0/propagation_test.go (about)

     1  // (c) Copyright IBM Corp. 2021
     2  // (c) Copyright Instana Inc. 2016
     3  
     4  package instana_test
     5  
     6  import (
     7  	"net/http"
     8  	"testing"
     9  
    10  	"github.com/instana/testify/assert"
    11  	"github.com/instana/testify/require"
    12  	instana "github.com/mier85/go-sensor"
    13  	"github.com/mier85/go-sensor/w3ctrace"
    14  	ot "github.com/opentracing/opentracing-go"
    15  )
    16  
    17  func TestTracer_Inject_HTTPHeaders(t *testing.T) {
    18  	examples := map[string]struct {
    19  		SpanContext instana.SpanContext
    20  		Headers     http.Header
    21  		Expected    http.Header
    22  	}{
    23  		"no trace context": {
    24  			SpanContext: instana.SpanContext{
    25  				TraceIDHi: 0x1,
    26  				TraceID:   0x2435,
    27  				SpanID:    0x3546,
    28  				Baggage: map[string]string{
    29  					"foo": "bar",
    30  				},
    31  			},
    32  			Headers: http.Header{
    33  				"Authorization": {"Basic 123"},
    34  			},
    35  			Expected: http.Header{
    36  				"Authorization":   {"Basic 123"},
    37  				"X-Instana-T":     {"0000000000002435"},
    38  				"X-Instana-S":     {"0000000000003546"},
    39  				"X-Instana-L":     {"1"},
    40  				"X-Instana-B-Foo": {"bar"},
    41  				"Traceparent":     {"00-00000000000000010000000000002435-0000000000003546-01"},
    42  				"Tracestate":      {"in=0000000000002435;0000000000003546"},
    43  				"Server-Timing":   {"intid;desc=0000000000002435"},
    44  			},
    45  		},
    46  		"with instana trace": {
    47  			SpanContext: instana.SpanContext{
    48  				TraceIDHi: 0x1,
    49  				TraceID:   0x2435,
    50  				SpanID:    0x3546,
    51  				Baggage: map[string]string{
    52  					"foo": "bar",
    53  				},
    54  			},
    55  			Headers: http.Header{
    56  				"Authorization":   {"Basic 123"},
    57  				"x-instana-t":     {"0000000000001314"},
    58  				"X-INSTANA-S":     {"0000000000001314"},
    59  				"X-Instana-L":     {"1"},
    60  				"X-Instana-B-foo": {"hello"},
    61  			},
    62  			Expected: http.Header{
    63  				"Authorization":   {"Basic 123"},
    64  				"X-Instana-T":     {"0000000000002435"},
    65  				"X-Instana-S":     {"0000000000003546"},
    66  				"X-Instana-L":     {"1"},
    67  				"X-Instana-B-Foo": {"bar"},
    68  				"Traceparent":     {"00-00000000000000010000000000002435-0000000000003546-01"},
    69  				"Tracestate":      {"in=0000000000002435;0000000000003546"},
    70  				"Server-Timing":   {"intid;desc=0000000000002435"},
    71  			},
    72  		},
    73  		"with instana trace suppressed": {
    74  			SpanContext: instana.SpanContext{
    75  				TraceIDHi:  0x1,
    76  				TraceID:    0x2435,
    77  				SpanID:     0x3546,
    78  				Suppressed: true,
    79  			},
    80  			Headers: http.Header{
    81  				"Authorization": {"Basic 123"},
    82  			},
    83  			Expected: http.Header{
    84  				"Authorization": {"Basic 123"},
    85  				"X-Instana-L":   {"0"},
    86  				"Traceparent":   {"00-00000000000000010000000000002435-0000000000003546-00"},
    87  				"Server-Timing": {"intid;desc=0000000000002435"},
    88  			},
    89  		},
    90  	}
    91  
    92  	for name, example := range examples {
    93  		t.Run(name, func(t *testing.T) {
    94  			recorder := instana.NewTestRecorder()
    95  			tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
    96  
    97  			require.NoError(t, tracer.Inject(example.SpanContext, ot.HTTPHeaders, ot.HTTPHeadersCarrier(example.Headers)))
    98  			assert.Equal(t, example.Expected, example.Headers)
    99  		})
   100  	}
   101  }
   102  
   103  func TestTracer_Inject_HTTPHeaders_W3CTraceContext(t *testing.T) {
   104  	examples := map[string]struct {
   105  		SpanContext instana.SpanContext
   106  		Expected    http.Header
   107  	}{
   108  		"instana trace suppressed, no w3c trace": {
   109  			SpanContext: instana.SpanContext{
   110  				TraceIDHi:  0x01,
   111  				TraceID:    0x2435,
   112  				SpanID:     0x3546,
   113  				Suppressed: true,
   114  			},
   115  			Expected: http.Header{
   116  				"X-Instana-L":   {"0"},
   117  				"Traceparent":   {"00-00000000000000010000000000002435-0000000000003546-00"},
   118  				"Server-Timing": {"intid;desc=0000000000002435"},
   119  			},
   120  		},
   121  		"instana trace suppressed, w3c trace not sampled": {
   122  			SpanContext: instana.SpanContext{
   123  				TraceIDHi: 0x01,
   124  				TraceID:   0x2435,
   125  				SpanID:    0x3546,
   126  				W3CContext: w3ctrace.Context{
   127  					RawParent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
   128  					RawState:  "rojo=00f067aa0ba902b7",
   129  				},
   130  				Suppressed: true,
   131  			},
   132  			Expected: http.Header{
   133  				"X-Instana-L":   {"0"},
   134  				"Traceparent":   {"00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000003546-00"},
   135  				"Tracestate":    {"rojo=00f067aa0ba902b7"},
   136  				"Server-Timing": {"intid;desc=0000000000002435"},
   137  			},
   138  		},
   139  		"instana trace suppressed, w3c trace sampled": {
   140  			SpanContext: instana.SpanContext{
   141  				TraceIDHi: 0x01,
   142  				TraceID:   0x2435,
   143  				SpanID:    0x3546,
   144  				W3CContext: w3ctrace.Context{
   145  					RawParent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
   146  					RawState:  "rojo=00f067aa0ba902b7",
   147  				},
   148  				Suppressed: true,
   149  			},
   150  			Expected: http.Header{
   151  				"X-Instana-L":   {"0"},
   152  				"Traceparent":   {"00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000003546-00"},
   153  				"Tracestate":    {"rojo=00f067aa0ba902b7"},
   154  				"Server-Timing": {"intid;desc=0000000000002435"},
   155  			},
   156  		},
   157  		"instana trace, no w3c trace": {
   158  			SpanContext: instana.SpanContext{
   159  				TraceIDHi: 0x01,
   160  				TraceID:   0x2435,
   161  				SpanID:    0x3546,
   162  			},
   163  			Expected: http.Header{
   164  				"X-Instana-T":   {"0000000000002435"},
   165  				"X-Instana-S":   {"0000000000003546"},
   166  				"X-Instana-L":   {"1"},
   167  				"Traceparent":   {"00-00000000000000010000000000002435-0000000000003546-01"},
   168  				"Tracestate":    {"in=0000000000002435;0000000000003546"},
   169  				"Server-Timing": {"intid;desc=0000000000002435"},
   170  			},
   171  		},
   172  		"instana trace, w3c trace not sampled": {
   173  			SpanContext: instana.SpanContext{
   174  				TraceIDHi: 0x01,
   175  				TraceID:   0x2435,
   176  				SpanID:    0x3546,
   177  				W3CContext: w3ctrace.Context{
   178  					RawParent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
   179  					RawState:  "rojo=00f067aa0ba902b7",
   180  				},
   181  			},
   182  			Expected: http.Header{
   183  				"X-Instana-T":   {"0000000000002435"},
   184  				"X-Instana-S":   {"0000000000003546"},
   185  				"X-Instana-L":   {"1"},
   186  				"Traceparent":   {"00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000003546-01"},
   187  				"Tracestate":    {"in=0000000000002435;0000000000003546,rojo=00f067aa0ba902b7"},
   188  				"Server-Timing": {"intid;desc=0000000000002435"},
   189  			},
   190  		},
   191  		"instana trace, w3c trace": {
   192  			SpanContext: instana.SpanContext{
   193  				TraceIDHi: 0x01,
   194  				TraceID:   0x2435,
   195  				SpanID:    0x3546,
   196  				W3CContext: w3ctrace.Context{
   197  					RawParent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
   198  					RawState:  "rojo=00f067aa0ba902b7",
   199  				},
   200  			},
   201  			Expected: http.Header{
   202  				"X-Instana-T":   {"0000000000002435"},
   203  				"X-Instana-S":   {"0000000000003546"},
   204  				"X-Instana-L":   {"1"},
   205  				"Traceparent":   {"00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000003546-01"},
   206  				"Tracestate":    {"in=0000000000002435;0000000000003546,rojo=00f067aa0ba902b7"},
   207  				"Server-Timing": {"intid;desc=0000000000002435"},
   208  			},
   209  		},
   210  	}
   211  
   212  	for name, example := range examples {
   213  		t.Run(name, func(t *testing.T) {
   214  			recorder := instana.NewTestRecorder()
   215  			tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   216  			headers := http.Header{}
   217  
   218  			require.NoError(t, tracer.Inject(example.SpanContext, ot.HTTPHeaders, ot.HTTPHeadersCarrier(headers)))
   219  			assert.Equal(t, example.Expected, headers)
   220  		})
   221  	}
   222  }
   223  
   224  func TestTracer_Inject_HTTPHeaders_SuppressedTracing(t *testing.T) {
   225  	recorder := instana.NewTestRecorder()
   226  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   227  
   228  	headers := http.Header{
   229  		"Authorization": {"Basic 123"},
   230  		"x-instana-t":   {"0000000000001314"},
   231  		"X-INSTANA-S":   {"0000000000001314"},
   232  		"X-Instana-L":   {"1"},
   233  	}
   234  
   235  	sc := instana.SpanContext{
   236  		TraceIDHi:  0x1,
   237  		TraceID:    0x2435,
   238  		SpanID:     0x3546,
   239  		Suppressed: true,
   240  	}
   241  
   242  	require.NoError(t, tracer.Inject(sc, ot.HTTPHeaders, ot.HTTPHeadersCarrier(headers)))
   243  
   244  	assert.Empty(t, headers.Get("X-Instana-T"))
   245  	assert.Empty(t, headers.Get("X-Instana-S"))
   246  	assert.Equal(t, "0", headers.Get("X-Instana-L"))
   247  	assert.Equal(t, "Basic 123", headers.Get("Authorization"))
   248  	assert.Equal(t, "intid;desc=0000000000002435", headers.Get("Server-Timing"))
   249  }
   250  
   251  func TestTracer_Inject_HTTPHeaders_WithExistingServerTiming(t *testing.T) {
   252  	recorder := instana.NewTestRecorder()
   253  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   254  
   255  	headers := http.Header{
   256  		"x-instana-t":   {"0000000000001314"},
   257  		"X-INSTANA-S":   {"0000000000001314"},
   258  		"X-Instana-L":   {"1"},
   259  		"Server-Timing": {"db;dur=53, app;dur=47.2", `cache;desc="Cache Read";dur=23.2`},
   260  	}
   261  
   262  	sc := instana.SpanContext{
   263  		TraceID:    0x2435,
   264  		SpanID:     0x3546,
   265  		Suppressed: true,
   266  	}
   267  
   268  	require.NoError(t, tracer.Inject(sc, ot.HTTPHeaders, ot.HTTPHeadersCarrier(headers)))
   269  	assert.Equal(t, `db;dur=53, app;dur=47.2, cache;desc="Cache Read";dur=23.2, intid;desc=0000000000002435`, headers.Get("Server-Timing"))
   270  }
   271  
   272  func TestTracer_Extract_HTTPHeaders(t *testing.T) {
   273  	examples := map[string]struct {
   274  		Headers  map[string]string
   275  		Expected instana.SpanContext
   276  	}{
   277  		"tracing enabled": {
   278  			Headers: map[string]string{
   279  				"Authorization":   "Basic 123",
   280  				"x-instana-t":     "0000000000000000000000010000000000001314",
   281  				"X-INSTANA-S":     "0000000000002435",
   282  				"X-Instana-L":     "1",
   283  				"X-Instana-B-Foo": "bar",
   284  			},
   285  			Expected: instana.SpanContext{
   286  				TraceIDHi: 0x1,
   287  				TraceID:   0x1314,
   288  				SpanID:    0x2435,
   289  				Baggage: map[string]string{
   290  					"Foo": "bar",
   291  				},
   292  			},
   293  		},
   294  		"tracing disabled": {
   295  			Headers: map[string]string{
   296  				"Authorization": "Basic 123",
   297  				"x-instana-t":   "0000000000000000000000010000000000001314",
   298  				"X-INSTANA-S":   "0000000000002435",
   299  				"X-Instana-L":   "0",
   300  			},
   301  			Expected: instana.SpanContext{
   302  				TraceIDHi:  0x1,
   303  				TraceID:    0x1314,
   304  				SpanID:     0x2435,
   305  				Suppressed: true,
   306  				Baggage:    map[string]string{},
   307  			},
   308  		},
   309  		"tracing disabled, with correlation data": {
   310  			Headers: map[string]string{
   311  				"Authorization": "Basic 123",
   312  				"x-instana-t":   "10000000000001314",
   313  				"X-INSTANA-S":   "2435",
   314  				"X-Instana-L":   "0,correlationType=web;correlationId=1234",
   315  			},
   316  			Expected: instana.SpanContext{
   317  				TraceIDHi:  0x1,
   318  				TraceID:    0x1314,
   319  				SpanID:     0x2435,
   320  				Suppressed: true,
   321  				Baggage:    map[string]string{},
   322  			},
   323  		},
   324  		"tracing disabled, no trace context": {
   325  			Headers: map[string]string{
   326  				"Authorization": "Basic 123",
   327  				"X-Instana-L":   "0",
   328  			},
   329  			Expected: instana.SpanContext{
   330  				Suppressed: true,
   331  				Baggage:    map[string]string{},
   332  			},
   333  		},
   334  		"w3c trace context, with instana headers": {
   335  			Headers: map[string]string{
   336  				"x-instana-t": "10000000000001314",
   337  				"X-INSTANA-S": "2435",
   338  				"X-Instana-L": "1",
   339  				"traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
   340  				"tracestate":  "rojo=00f067aa0ba902b7",
   341  			},
   342  			Expected: instana.SpanContext{
   343  				TraceIDHi: 0x1,
   344  				TraceID:   0x1314,
   345  				SpanID:    0x2435,
   346  				Baggage:   map[string]string{},
   347  				W3CContext: w3ctrace.Context{
   348  					RawParent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
   349  					RawState:  "rojo=00f067aa0ba902b7",
   350  				},
   351  			},
   352  		},
   353  		"w3c trace context, no instana headers": {
   354  			Headers: map[string]string{
   355  				"traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
   356  				"tracestate":  "in=10000000000001314;2435,rojo=00f067aa0ba902b7",
   357  			},
   358  			Expected: instana.SpanContext{
   359  				Baggage: map[string]string{},
   360  				W3CContext: w3ctrace.Context{
   361  					RawParent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
   362  					RawState:  "in=10000000000001314;2435,rojo=00f067aa0ba902b7",
   363  				},
   364  			},
   365  		},
   366  	}
   367  
   368  	for name, example := range examples {
   369  		t.Run(name, func(t *testing.T) {
   370  			recorder := instana.NewTestRecorder()
   371  			tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   372  
   373  			headers := http.Header{}
   374  			for k, v := range example.Headers {
   375  				headers.Set(k, v)
   376  			}
   377  
   378  			sc, err := tracer.Extract(ot.HTTPHeaders, ot.HTTPHeadersCarrier(headers))
   379  			require.NoError(t, err)
   380  
   381  			assert.Equal(t, example.Expected, sc)
   382  		})
   383  	}
   384  }
   385  
   386  func TestTracer_Extract_HTTPHeaders_WithEUMCorrelation(t *testing.T) {
   387  	examples := map[string]struct {
   388  		Headers  map[string]string
   389  		Expected instana.SpanContext
   390  	}{
   391  		"tracing enabled, no instana headers": {
   392  			Headers: map[string]string{
   393  				"X-Instana-L": "1,correlationType=web;correlationId=1234",
   394  			},
   395  		},
   396  		"tracing enabled, with instana headers": {
   397  			Headers: map[string]string{
   398  				"X-Instana-T": "0000000000002435",
   399  				"X-Instana-S": "0000000000003546",
   400  				"X-Instana-L": "1,correlationType=web;correlationId=1234",
   401  			},
   402  		},
   403  	}
   404  
   405  	for name, example := range examples {
   406  		t.Run(name, func(t *testing.T) {
   407  			recorder := instana.NewTestRecorder()
   408  			tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   409  
   410  			headers := http.Header{}
   411  			for k, v := range example.Headers {
   412  				headers.Set(k, v)
   413  			}
   414  
   415  			sc, err := tracer.Extract(ot.HTTPHeaders, ot.HTTPHeadersCarrier(headers))
   416  			require.NoError(t, err)
   417  
   418  			spanContext := sc.(instana.SpanContext)
   419  
   420  			assert.EqualValues(t, 0, spanContext.TraceID)
   421  			assert.EqualValues(t, 0, spanContext.SpanID)
   422  			assert.Empty(t, spanContext.ParentID)
   423  			assert.Equal(t, instana.EUMCorrelationData{ID: "1234", Type: "web"}, spanContext.Correlation)
   424  		})
   425  	}
   426  }
   427  
   428  func TestTracer_Extract_HTTPHeaders_NoContext(t *testing.T) {
   429  	recorder := instana.NewTestRecorder()
   430  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   431  
   432  	headers := http.Header{
   433  		"Authorization": {"Basic 123"},
   434  	}
   435  
   436  	_, err := tracer.Extract(ot.HTTPHeaders, ot.HTTPHeadersCarrier(headers))
   437  	assert.Equal(t, ot.ErrSpanContextNotFound, err)
   438  }
   439  
   440  func TestTracer_Extract_HTTPHeaders_CorruptedContext(t *testing.T) {
   441  	examples := map[string]http.Header{
   442  		"missing trace id": {
   443  			"X-INSTANA-S": {"1314"},
   444  			"X-Instana-L": {"1"},
   445  		},
   446  		"missing span id": {
   447  			"x-instana-t": {"1314"},
   448  			"X-Instana-L": {"1"},
   449  		},
   450  		"malformed trace id": {
   451  			"x-instana-t": {"wrong"},
   452  			"X-INSTANA-S": {"1314"},
   453  			"X-Instana-L": {"1"},
   454  		},
   455  		"malformed span id": {
   456  			"x-instana-t": {"1314"},
   457  			"X-INSTANA-S": {"wrong"},
   458  			"X-Instana-L": {"1"},
   459  		},
   460  	}
   461  
   462  	for name, headers := range examples {
   463  		t.Run(name, func(t *testing.T) {
   464  			recorder := instana.NewTestRecorder()
   465  			tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   466  
   467  			_, err := tracer.Extract(ot.HTTPHeaders, ot.HTTPHeadersCarrier(headers))
   468  			assert.Equal(t, ot.ErrSpanContextCorrupted, err)
   469  		})
   470  	}
   471  }
   472  
   473  func TestTracer_Inject_TextMap_AddValues(t *testing.T) {
   474  	recorder := instana.NewTestRecorder()
   475  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   476  
   477  	sc := instana.SpanContext{
   478  		TraceIDHi: 0x1,
   479  		TraceID:   0x2435,
   480  		SpanID:    0x3546,
   481  		Baggage: map[string]string{
   482  			"foo": "bar",
   483  		},
   484  	}
   485  
   486  	carrier := map[string]string{
   487  		"key1": "value1",
   488  	}
   489  
   490  	require.NoError(t, tracer.Inject(sc, ot.TextMap, ot.TextMapCarrier(carrier)))
   491  
   492  	assert.Equal(t, map[string]string{
   493  		"x-instana-t":     "0000000000002435",
   494  		"x-instana-s":     "0000000000003546",
   495  		"x-instana-l":     "1",
   496  		"x-instana-b-foo": "bar",
   497  		"key1":            "value1",
   498  	}, carrier)
   499  }
   500  
   501  func TestTracer_Inject_TextMap_UpdateValues(t *testing.T) {
   502  	recorder := instana.NewTestRecorder()
   503  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   504  
   505  	sc := instana.SpanContext{
   506  		TraceIDHi: 0x1,
   507  		TraceID:   0x2435,
   508  		SpanID:    0x3546,
   509  		Baggage: map[string]string{
   510  			"foo": "bar",
   511  		},
   512  	}
   513  
   514  	carrier := map[string]string{
   515  		"key1":            "value1",
   516  		"x-instana-t":     "0000000000001314",
   517  		"X-INSTANA-S":     "0000000000001314",
   518  		"X-Instana-L":     "1",
   519  		"X-INSTANA-b-foo": "hello",
   520  	}
   521  
   522  	require.NoError(t, tracer.Inject(sc, ot.TextMap, ot.TextMapCarrier(carrier)))
   523  
   524  	assert.Equal(t, map[string]string{
   525  		"x-instana-t":     "0000000000002435",
   526  		"X-INSTANA-S":     "0000000000003546",
   527  		"X-Instana-L":     "1",
   528  		"X-INSTANA-b-foo": "bar",
   529  		"key1":            "value1",
   530  	}, carrier)
   531  }
   532  
   533  func TestTracer_Inject_TextMap_SuppressedTracing(t *testing.T) {
   534  	recorder := instana.NewTestRecorder()
   535  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   536  
   537  	sc := instana.SpanContext{
   538  		TraceIDHi:  0x1,
   539  		TraceID:    0x2435,
   540  		SpanID:     0x3546,
   541  		Suppressed: true,
   542  	}
   543  
   544  	carrier := map[string]string{
   545  		"key1":        "value1",
   546  		"x-instana-t": "0000000000001314",
   547  		"X-INSTANA-S": "0000000000001314",
   548  		"X-Instana-L": "1",
   549  	}
   550  
   551  	require.NoError(t, tracer.Inject(sc, ot.TextMap, ot.TextMapCarrier(carrier)))
   552  
   553  	assert.Equal(t, map[string]string{
   554  		"X-Instana-L": "0",
   555  		"key1":        "value1",
   556  	}, carrier)
   557  }
   558  
   559  func TestTracer_Extract_TextMap(t *testing.T) {
   560  	examples := map[string]struct {
   561  		Carrier  map[string]string
   562  		Expected instana.SpanContext
   563  	}{
   564  		"tracing enabled": {
   565  			Carrier: map[string]string{
   566  				"Authorization":   "Basic 123",
   567  				"x-instana-t":     "10000000000001314",
   568  				"X-INSTANA-S":     "2435",
   569  				"X-Instana-L":     "1",
   570  				"X-Instana-B-Foo": "bar",
   571  			},
   572  			Expected: instana.SpanContext{
   573  				TraceIDHi: 0x1,
   574  				TraceID:   0x1314,
   575  				SpanID:    0x2435,
   576  				Baggage: map[string]string{
   577  					"Foo": "bar",
   578  				},
   579  			},
   580  		},
   581  		"tracing disabled": {
   582  			Carrier: map[string]string{
   583  				"Authorization": "Basic 123",
   584  				"x-instana-t":   "10000000000001314",
   585  				"X-INSTANA-S":   "2435",
   586  				"X-Instana-L":   "0",
   587  			},
   588  			Expected: instana.SpanContext{
   589  				TraceIDHi:  0x1,
   590  				TraceID:    0x1314,
   591  				SpanID:     0x2435,
   592  				Suppressed: true,
   593  				Baggage:    map[string]string{},
   594  			},
   595  		},
   596  		"tracing disabled, no instana context": {
   597  			Carrier: map[string]string{
   598  				"Authorization": "Basic 123",
   599  				"X-Instana-L":   "0",
   600  			},
   601  			Expected: instana.SpanContext{
   602  				Suppressed: true,
   603  				Baggage:    map[string]string{},
   604  			},
   605  		},
   606  	}
   607  
   608  	for name, example := range examples {
   609  		t.Run(name, func(t *testing.T) {
   610  			recorder := instana.NewTestRecorder()
   611  			tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   612  
   613  			sc, err := tracer.Extract(ot.TextMap, ot.TextMapCarrier(example.Carrier))
   614  			require.NoError(t, err)
   615  
   616  			assert.Equal(t, example.Expected, sc)
   617  		})
   618  	}
   619  }
   620  
   621  func TestTracer_Extract_TextMap_NoContext(t *testing.T) {
   622  	recorder := instana.NewTestRecorder()
   623  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   624  
   625  	carrier := map[string]string{
   626  		"key": "value",
   627  	}
   628  
   629  	_, err := tracer.Extract(ot.TextMap, ot.TextMapCarrier(carrier))
   630  	assert.Equal(t, ot.ErrSpanContextNotFound, err)
   631  }
   632  
   633  func TestTracer_Extract_TextMap_CorruptedContext(t *testing.T) {
   634  	examples := map[string]map[string]string{
   635  		"missing trace id": {
   636  			"x-instana-s": "1314",
   637  			"x-instana-l": "1",
   638  		},
   639  		"missing span id": {
   640  			"x-instana-t": "1314",
   641  			"x-instana-l": "1",
   642  		},
   643  		"malformed trace id": {
   644  			"x-instana-t": "wrong",
   645  			"x-instana-s": "1314",
   646  			"x-instana-l": "1",
   647  		},
   648  		"malformed span id": {
   649  			"x-instana-t": "1314",
   650  			"x-instana-s": "wrong",
   651  			"x-instana-l": "1",
   652  		},
   653  	}
   654  
   655  	for name, carrier := range examples {
   656  		t.Run(name, func(t *testing.T) {
   657  			recorder := instana.NewTestRecorder()
   658  			tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   659  
   660  			_, err := tracer.Extract(ot.TextMap, ot.TextMapCarrier(carrier))
   661  			assert.Equal(t, ot.ErrSpanContextCorrupted, err)
   662  		})
   663  	}
   664  }
   665  
   666  type textMapWithRemoveAll struct {
   667  	ot.TextMapCarrier
   668  }
   669  
   670  func (c *textMapWithRemoveAll) RemoveAll() {
   671  	for k := range c.TextMapCarrier {
   672  		delete(c.TextMapCarrier, k)
   673  	}
   674  }
   675  
   676  func TestTracer_Inject_CarrierWithRemoveAll_SuppressedTrace(t *testing.T) {
   677  	recorder := instana.NewTestRecorder()
   678  	tracer := instana.NewTracerWithEverything(&instana.Options{}, recorder)
   679  
   680  	sc := instana.SpanContext{
   681  		TraceIDHi:  0x1,
   682  		TraceID:    0x2435,
   683  		SpanID:     0x3546,
   684  		Suppressed: true,
   685  	}
   686  
   687  	carrier := map[string]string{
   688  		"x-instana-t": "0000000000001314",
   689  		"X-INSTANA-S": "0000000000001314",
   690  		"X-Instana-L": "1",
   691  	}
   692  
   693  	require.NoError(t, tracer.Inject(sc, ot.TextMap, &textMapWithRemoveAll{carrier}))
   694  
   695  	assert.Equal(t, map[string]string{
   696  		"X-Instana-L": "0",
   697  	}, carrier)
   698  }