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 jaeger 16 17import ( 18 "math" 19 "testing" 20 21 "github.com/stretchr/testify/assert" 22 "github.com/stretchr/testify/require" 23) 24 25func TestContextFromString(t *testing.T) { 26 var err error 27 _, err = ContextFromString("") 28 assert.Error(t, err) 29 _, err = ContextFromString("abcd") 30 assert.Error(t, err) 31 _, err = ContextFromString("x:1:1:1") 32 assert.Error(t, err) 33 _, err = ContextFromString("1:x:1:1") 34 assert.Error(t, err) 35 _, err = ContextFromString("1:1:x:1") 36 assert.Error(t, err) 37 _, err = ContextFromString("1:1:1:x") 38 assert.Error(t, err) 39 _, err = ContextFromString("1:1:1:x") 40 assert.Error(t, err) 41 _, err = ContextFromString("01234567890123456789012345678901234:1:1:1") 42 assert.Error(t, err) 43 _, err = ContextFromString("01234567890123456789012345678901:1:1:1") 44 assert.NoError(t, err) 45 _, err = ContextFromString("01234_67890123456789012345678901:1:1:1") 46 assert.Error(t, err) 47 _, err = ContextFromString("0123456789012345678901_345678901:1:1:1") 48 assert.Error(t, err) 49 _, err = ContextFromString("1:0123456789012345:1:1") 50 assert.NoError(t, err) 51 _, err = ContextFromString("1:01234567890123456:1:1") 52 assert.Error(t, err) 53 ctx, err := ContextFromString("10000000000000001:1:1:1") 54 assert.NoError(t, err) 55 assert.EqualValues(t, TraceID{High: 1, Low: 1}, ctx.traceID) 56 ctx, err = ContextFromString("1:1:1:1") 57 assert.NoError(t, err) 58 assert.EqualValues(t, TraceID{Low: 1}, ctx.traceID) 59 assert.EqualValues(t, 1, ctx.spanID) 60 assert.EqualValues(t, 1, ctx.parentID) 61 assert.True(t, ctx.IsSampled()) 62 ctx = NewSpanContext(TraceID{Low: 1}, 1, 1, true, nil) 63 assert.EqualValues(t, TraceID{Low: 1}, ctx.traceID) 64 assert.EqualValues(t, 1, ctx.spanID) 65 assert.EqualValues(t, 1, ctx.parentID) 66 assert.True(t, ctx.IsSampled()) 67 assert.Equal(t, "00000000000000ff", SpanID(255).String()) 68 assert.Equal(t, "00000000000000ff", TraceID{Low: 255}.String()) 69 assert.Equal(t, "00000000000000ff00000000000000ff", TraceID{High: 255, Low: 255}.String()) 70 ctx = NewSpanContext(TraceID{High: 255, Low: 255}, SpanID(1), SpanID(1), false, nil) 71 assert.Equal(t, "00000000000000ff00000000000000ff:0000000000000001:0000000000000001:0", ctx.String()) 72} 73 74func TestSpanContext_WithBaggageItem(t *testing.T) { 75 var ctx SpanContext 76 ctx = ctx.WithBaggageItem("some-KEY", "Some-Value") 77 assert.Equal(t, map[string]string{"some-KEY": "Some-Value"}, ctx.baggage) 78 ctx = ctx.WithBaggageItem("some-KEY", "Some-Other-Value") 79 assert.Equal(t, map[string]string{"some-KEY": "Some-Other-Value"}, ctx.baggage) 80} 81 82func TestSpanContext_WithBaggageItem_Delete(t *testing.T) { 83 var ctx SpanContext 84 ctx = ctx.WithBaggageItem("some-KEY", "") 85 assert.Nil(t, ctx.baggage) 86 ctx = ctx.WithBaggageItem("some-KEY", "Some-Value") 87 assert.Equal(t, map[string]string{"some-KEY": "Some-Value"}, ctx.baggage) 88 ctx = ctx.WithBaggageItem("another-KEY", "") 89 assert.Equal(t, map[string]string{"some-KEY": "Some-Value"}, ctx.baggage) 90 ctx2 := ctx.WithBaggageItem("some-KEY", "") 91 assert.Equal(t, map[string]string{"some-KEY": "Some-Value"}, ctx.baggage, "parent unchanged") 92 assert.Equal(t, map[string]string{}, ctx2.baggage) 93} 94 95func TestSpanContext_Flags(t *testing.T) { 96 97 var tests = map[string]struct { 98 in string 99 sampledFlag bool 100 debugFlag bool 101 firehoseFlag bool 102 }{ 103 "None": { 104 in: "1:1:1:0", 105 sampledFlag: false, 106 debugFlag: false, 107 firehoseFlag: false, 108 }, 109 "Sampled Only": { 110 in: "1:1:1:1", 111 sampledFlag: true, 112 debugFlag: false, 113 firehoseFlag: false, 114 }, 115 116 "Debug Only": { 117 in: "1:1:1:2", 118 sampledFlag: false, 119 debugFlag: true, 120 firehoseFlag: false, 121 }, 122 123 "IsFirehose Only": { 124 in: "1:1:1:8", 125 sampledFlag: false, 126 debugFlag: false, 127 firehoseFlag: true, 128 }, 129 130 "Sampled And Debug": { 131 in: "1:1:1:3", 132 sampledFlag: true, 133 debugFlag: true, 134 firehoseFlag: false, 135 }, 136 137 "Sampled And Firehose": { 138 in: "1:1:1:9", 139 sampledFlag: true, 140 debugFlag: false, 141 firehoseFlag: true, 142 }, 143 144 "Debug And Firehose": { 145 in: "1:1:1:10", 146 sampledFlag: false, 147 debugFlag: true, 148 firehoseFlag: true, 149 }, 150 151 "Sampled And Debug And Firehose": { 152 in: "1:1:1:11", 153 sampledFlag: true, 154 debugFlag: true, 155 firehoseFlag: true, 156 }, 157 } 158 159 for name, tc := range tests { 160 t.Run(name, func(t *testing.T) { 161 ctx, err := ContextFromString(tc.in) 162 require.NoError(t, err) 163 assert.Equal(t, tc.sampledFlag, ctx.IsSampled()) 164 assert.Equal(t, tc.debugFlag, ctx.IsDebug()) 165 assert.Equal(t, tc.firehoseFlag, ctx.IsFirehose()) 166 }) 167 } 168} 169 170func TestSpanContext_CopyFrom(t *testing.T) { 171 ctx, err := ContextFromString("1:1:1:1") 172 require.NoError(t, err) 173 ctx2 := SpanContext{} 174 ctx2.CopyFrom(&ctx) 175 assert.Equal(t, ctx, ctx2) 176 // with baggage 177 ctx = ctx.WithBaggageItem("x", "y") 178 ctx2 = SpanContext{} 179 ctx2.CopyFrom(&ctx) 180 assert.Equal(t, ctx, ctx2) 181 assert.Equal(t, "y", ctx2.baggage["x"]) 182} 183 184func TestTraceIDString(t *testing.T) { 185 var tests = map[string]struct { 186 in TraceID 187 expected string 188 }{ 189 "Empty TraceID": { 190 in: TraceID{}, 191 expected: "0000000000000000", 192 }, 193 "TraceID low only": { 194 in: TraceID{Low: math.MaxUint64/16 - 405}, 195 expected: "0ffffffffffffe6a", 196 }, 197 "TraceID low and high": { 198 in: TraceID{High: math.MaxUint64 / 16, Low: math.MaxUint64/16 - 405}, 199 expected: "0fffffffffffffff0ffffffffffffe6a", 200 }, 201 } 202 for name, tc := range tests { 203 t.Run(name, func(t *testing.T) { 204 assert.Equal(t, tc.expected, tc.in.String()) 205 parsed, err := TraceIDFromString(tc.in.String()) 206 assert.NoError(t, err) 207 assert.Equal(t, tc.in, parsed) 208 }) 209 } 210} 211 212func TestSpanIDString(t *testing.T) { 213 var tests = map[string]struct { 214 in SpanID 215 expected string 216 }{ 217 "SpanID zero": { 218 in: 0, 219 expected: "0000000000000000", 220 }, 221 "SpanID non zero": { 222 in: math.MaxUint64/16 - 405, 223 expected: "0ffffffffffffe6a", 224 }, 225 } 226 for name, tc := range tests { 227 t.Run(name, func(t *testing.T) { 228 assert.Equal(t, tc.expected, tc.in.String()) 229 parsed, err := SpanIDFromString(tc.in.String()) 230 assert.NoError(t, err) 231 assert.Equal(t, tc.in, parsed) 232 }) 233 } 234} 235