1// Copyright (c) 2017 Uber Technologies, Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package zipkin 16 17import ( 18 "strconv" 19 "testing" 20 21 opentracing "github.com/opentracing/opentracing-go" 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 "github.com/uber/jaeger-client-go" 25) 26 27var ( 28 rootSampled = newSpanContext(1, 2, 0, true, map[string]string{"foo": "bar"}) 29 nonRootSampled = newSpanContext(1, 2, 1, true, nil) 30 nonRootNonSampled = newSpanContext(1, 2, 1, false, nil) 31) 32 33var ( 34 rootSampledHeader = opentracing.TextMapCarrier{ 35 "x-b3-traceid": "0000000000000001", 36 "x-b3-spanid": "2", 37 "x-b3-sampled": "1", 38 "baggage-foo": "bar", 39 } 40 nonRootSampledHeader = opentracing.TextMapCarrier{ 41 "x-b3-traceid": "0000000000000001", 42 "x-b3-spanid": "2", 43 "x-b3-parentspanid": "1", 44 "x-b3-sampled": "1", 45 } 46 nonRootNonSampledHeader = opentracing.TextMapCarrier{ 47 "x-b3-traceid": "0000000000000001", 48 "x-b3-spanid": "2", 49 "x-b3-parentspanid": "1", 50 "x-b3-sampled": "0", 51 } 52 rootSampledBooleanHeader = opentracing.TextMapCarrier{ 53 "x-b3-traceid": "0000000000000001", 54 "x-b3-spanid": "2", 55 "x-b3-sampled": "true", 56 "baggage-foo": "bar", 57 } 58 nonRootSampledBooleanHeader = opentracing.TextMapCarrier{ 59 "x-b3-traceid": "0000000000000001", 60 "x-b3-spanid": "2", 61 "x-b3-parentspanid": "1", 62 "x-b3-sampled": "true", 63 } 64 invalidHeader = opentracing.TextMapCarrier{ 65 "x-b3-traceid": "jdkafhsd", 66 "x-b3-spanid": "afsdfsdf", 67 "x-b3-parentspanid": "hiagggdf", 68 "x-b3-sampled": "sdfgsdfg", 69 } 70 sampled128bitTraceID = opentracing.TextMapCarrier{ 71 "x-b3-traceid": "463ac35c9f6413ad48485a3953bb6124", 72 "x-b3-spanid": "2", 73 "x-b3-sampled": "1", 74 } 75 invalidTraceID = opentracing.TextMapCarrier{ 76 "x-b3-traceid": "00000000000000000000000000000000", 77 "x-b3-spanid": "2", 78 "x-b3-sampled": "1", 79 } 80) 81 82var ( 83 propagator = NewZipkinB3HTTPHeaderPropagator() 84) 85 86func newSpanContext(traceID, spanID, parentID uint64, sampled bool, baggage map[string]string) jaeger.SpanContext { 87 return jaeger.NewSpanContext( 88 jaeger.TraceID{Low: traceID}, 89 jaeger.SpanID(spanID), 90 jaeger.SpanID(parentID), 91 sampled, 92 baggage, 93 ) 94} 95 96func TestExtractorInvalid(t *testing.T) { 97 _, err := propagator.Extract(invalidHeader) 98 assert.Error(t, err) 99} 100 101func TestExtractorRootSampled(t *testing.T) { 102 ctx, err := propagator.Extract(rootSampledHeader) 103 assert.Nil(t, err) 104 assert.EqualValues(t, rootSampled, ctx) 105} 106 107func TestExtractorNonRootSampled(t *testing.T) { 108 ctx, err := propagator.Extract(nonRootSampledHeader) 109 assert.Nil(t, err) 110 assert.EqualValues(t, nonRootSampled, ctx) 111} 112 113func TestExtractorNonRootNonSampled(t *testing.T) { 114 ctx, err := propagator.Extract(nonRootNonSampledHeader) 115 assert.Nil(t, err) 116 assert.EqualValues(t, nonRootNonSampled, ctx) 117} 118 119func TestExtractorRootSampledBoolean(t *testing.T) { 120 ctx, err := propagator.Extract(rootSampledBooleanHeader) 121 assert.Nil(t, err) 122 assert.EqualValues(t, rootSampled, ctx) 123} 124 125func TestExtractorNonRootSampledBoolean(t *testing.T) { 126 ctx, err := propagator.Extract(nonRootSampledBooleanHeader) 127 assert.Nil(t, err) 128 assert.EqualValues(t, nonRootSampled, ctx) 129} 130 131func TestInjectorRootSampled(t *testing.T) { 132 hdr := opentracing.TextMapCarrier{} 133 err := propagator.Inject(rootSampled, hdr) 134 assert.Nil(t, err) 135 assert.EqualValues(t, rootSampledHeader, hdr) 136} 137 138func TestInjectorNonRootSampled(t *testing.T) { 139 hdr := opentracing.TextMapCarrier{} 140 err := propagator.Inject(nonRootSampled, hdr) 141 assert.Nil(t, err) 142 assert.EqualValues(t, nonRootSampledHeader, hdr) 143} 144 145func TestInjectorNonRootNonSampled(t *testing.T) { 146 hdr := opentracing.TextMapCarrier{} 147 err := propagator.Inject(nonRootNonSampled, hdr) 148 assert.Nil(t, err) 149 assert.EqualValues(t, nonRootNonSampledHeader, hdr) 150} 151 152func TestCustomBaggagePrefix(t *testing.T) { 153 propag := NewZipkinB3HTTPHeaderPropagator(BaggagePrefix("emoji:)")) 154 hdr := opentracing.TextMapCarrier{} 155 sc := newSpanContext(1, 2, 0, true, map[string]string{"foo": "bar"}) 156 err := propag.Inject(sc, hdr) 157 assert.Nil(t, err) 158 m := opentracing.TextMapCarrier{ 159 "x-b3-traceid": "0000000000000001", 160 "x-b3-spanid": "2", 161 "x-b3-sampled": "1", 162 "emoji:)foo": "bar", 163 } 164 assert.EqualValues(t, m, hdr) 165 166 sc, err = propag.Extract(m) 167 require.NoError(t, err) 168 sc.ForeachBaggageItem(func(k, v string) bool { 169 assert.Equal(t, "foo", k) 170 assert.Equal(t, "bar", v) 171 return true 172 }) 173} 174 175func Test128bitTraceID(t *testing.T) { 176 spanCtx, err := propagator.Extract(sampled128bitTraceID) 177 assert.Nil(t, err) 178 179 high, _ := strconv.ParseUint("463ac35c9f6413ad", 16, 64) 180 low, _ := strconv.ParseUint("48485a3953bb6124", 16, 64) 181 assert.EqualValues(t, jaeger.TraceID{High: high, Low: low}, spanCtx.TraceID()) 182 183 hdr := opentracing.TextMapCarrier{} 184 err = propagator.Inject(spanCtx, hdr) 185 assert.Nil(t, err) 186 assert.EqualValues(t, sampled128bitTraceID["x-b3-traceid"], hdr["x-b3-traceid"]) 187} 188 189func TestInvalid128bitTraceID(t *testing.T) { 190 _, err := propagator.Extract(invalidTraceID) 191 assert.EqualError(t, err, opentracing.ErrSpanContextNotFound.Error()) 192} 193