github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/util_internal_test.go (about) 1 // (c) Copyright IBM Corp. 2021 2 // (c) Copyright Instana Inc. 2017 3 4 package instana 5 6 import ( 7 "errors" 8 "io/ioutil" 9 "os" 10 "testing" 11 12 "github.com/opentracing/opentracing-go/ext" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 // Trace IDs (and Span IDs) are based on Java Signed Long datatype 18 const ( 19 MinInt64 int64 = -9223372036854775808 20 MaxInt64 int64 = 9223372036854775807 21 ) 22 23 func TestGeneratedIDRange(t *testing.T) { 24 for index := 0; index < 10000; index++ { 25 id := randomID() 26 assert.LessOrEqual(t, id, MaxInt64) 27 assert.GreaterOrEqual(t, id, MinInt64) 28 } 29 } 30 31 func TestParseID(t *testing.T) { 32 maxHex := "7fffffffffffffff" 33 34 // maxID (int64) -> header -> int64 35 header := FormatID(MaxInt64) 36 assert.Equal(t, maxHex, header) 37 38 id, err := ParseID(header) 39 require.NoError(t, err) 40 assert.Equal(t, MaxInt64, id) 41 } 42 43 func TestFormatID(t *testing.T) { 44 minID := int64(MinInt64) 45 minHex := "8000000000000000" 46 47 // minHex (unsigned 64bit hex string) -> signed 64bit int -> unsigned 64bit hex string 48 id, err := ParseID(minHex) 49 require.NoError(t, err) 50 assert.Equal(t, minID, id) 51 52 header := FormatID(id) 53 assert.Equal(t, minHex, header) 54 } 55 56 func TestParseLongID(t *testing.T) { 57 examples := map[string]struct { 58 Value string 59 ExpectedHi, ExpectedLo int64 60 }{ 61 "64-bit short": {"1234ab", 0x0, 0x1234ab}, 62 "64-bit padded": {"00000000001234ab", 0x0, 0x1234ab}, 63 "64-bit padded to 128-bit": {"000000000000000000000000001234ab", 0x0, 0x1234ab}, 64 "128-bit short": {"1c00000000001234ab", 0x1c, 0x1234ab}, 65 "128-bit padded": {"000000000000001c00000000001234ab", 0x1c, 0x1234ab}, 66 } 67 68 for name, example := range examples { 69 t.Run(name, func(t *testing.T) { 70 hi, lo, err := ParseLongID(example.Value) 71 require.NoError(t, err) 72 73 assert.Equal(t, example.ExpectedHi, hi) 74 assert.Equal(t, example.ExpectedLo, lo) 75 }) 76 } 77 } 78 79 func TestFormatLongID(t *testing.T) { 80 examples := map[string]struct { 81 Hi, Lo int64 82 Expected string 83 }{ 84 "64-bit": {0x0, 0x1234ab, "000000000000000000000000001234ab"}, 85 "128-bit": {0x1c, 0x1234ab, "000000000000001c00000000001234ab"}, 86 } 87 88 for name, example := range examples { 89 t.Run(name, func(t *testing.T) { 90 assert.Equal(t, example.Expected, FormatLongID(example.Hi, example.Lo)) 91 }) 92 } 93 } 94 95 func TestBogusValues(t *testing.T) { 96 var id int64 97 98 // ParseID with random strings should return 0 99 id, err := ParseID("this shouldnt work") 100 assert.Equal(t, int64(0), id, "Bad input should return 0") 101 assert.NotNil(t, err, "An error should be returned") 102 } 103 104 func TestHexGatewayToAddr(t *testing.T) { 105 tests := []struct { 106 in string 107 expected string 108 expectedErr error 109 }{ 110 { 111 in: "0101FEA9", 112 expected: "169.254.1.1", 113 expectedErr: nil, 114 }, 115 { 116 in: "0101FEAC", 117 expected: "172.254.1.1", 118 expectedErr: nil, 119 }, 120 { 121 in: "0101FEA", 122 expected: "", 123 expectedErr: errors.New("invalid gateway length"), 124 }, 125 } 126 127 for _, test := range tests { 128 gatewayHex := []rune(test.in) 129 gateway, err := hexGatewayToAddr(gatewayHex) 130 assert.Equal(t, test.expectedErr, err) 131 assert.Equal(t, test.expected, gateway) 132 } 133 } 134 135 func TestGetDefaultGateway(t *testing.T) { 136 137 tests := []struct { 138 in string 139 expected string 140 expectError bool 141 }{ 142 { 143 in: `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT 144 145 eth0 00000000 0101FEA9 0003 0 0 0 00000000 0 0 0 146 147 eth0 0101FEA9 00000000 0005 0 0 0 FFFFFFFF 0 0 0 148 149 `, 150 expected: "169.254.1.1", 151 }, 152 { 153 in: `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT 154 155 eth0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0 156 157 eth0 00000000 010011AC 0003 0 0 0 00000000 0 0 0 158 159 `, 160 expected: "172.17.0.1", 161 }, 162 } 163 164 for _, test := range tests { 165 func() { 166 tmpFile, err := ioutil.TempFile("", "getdefaultgateway") 167 if err != nil { 168 t.Fatal(err) 169 } 170 171 defer os.Remove(tmpFile.Name()) 172 173 _, err = tmpFile.WriteString(test.in) 174 175 if err != nil { 176 t.Fatal(err) 177 } 178 179 gateway, err := getDefaultGateway(tmpFile.Name()) 180 require.NoError(t, err) 181 assert.Equal(t, test.expected, gateway) 182 }() 183 } 184 } 185 186 func BenchmarkFormatID(b *testing.B) { 187 for i := 0; i < b.N; i++ { 188 FormatID(int64(i)) 189 } 190 } 191 192 func Test_isRootExitSpan(t *testing.T) { 193 type args struct { 194 kind interface{} 195 isRootSpan bool 196 } 197 tests := []struct { 198 name string 199 args args 200 want bool 201 }{ 202 { 203 name: "spanType_exit_rootSpan_true", 204 args: args{ 205 kind: ext.SpanKindRPCClientEnum, 206 isRootSpan: true, 207 }, 208 want: true, 209 }, 210 { 211 name: "spanType_exit_rootSpan_false", 212 args: args{ 213 kind: ext.SpanKindRPCServerEnum, 214 }, 215 want: false, 216 }, 217 { 218 name: "spanType_entry_rootSpan_true", 219 args: args{ 220 kind: nil, 221 }, 222 want: false, 223 }, 224 { 225 name: "spanType_entry_rootSpan_false", 226 args: args{ 227 kind: nil, 228 }, 229 want: false, 230 }, 231 { 232 name: "spanType_nil_rootSpan_true", 233 args: args{ 234 kind: nil, 235 }, 236 want: false, 237 }, 238 } 239 for _, tt := range tests { 240 t.Run(tt.name, func(t *testing.T) { 241 got := isRootExitSpan(tt.args.kind, tt.args.isRootSpan) 242 243 assert.Equal(t, tt.want, got) 244 }) 245 } 246 } 247 248 func Test_allowRootExitSpan(t *testing.T) { 249 tests := []struct { 250 name string 251 exportEnv bool 252 want bool 253 }{ 254 { 255 name: "env_set", 256 exportEnv: true, 257 want: true, 258 }, 259 { 260 name: "env_unset", 261 exportEnv: false, 262 want: false, 263 }, 264 } 265 for _, tt := range tests { 266 t.Run(tt.name, func(t *testing.T) { 267 268 if tt.exportEnv { 269 os.Setenv(allowRootExitSpanEnv, "1") 270 271 defer func() { 272 os.Unsetenv(allowRootExitSpanEnv) 273 }() 274 } 275 276 if got := allowRootExitSpan(); got != tt.want { 277 t.Errorf("allowRootExitSpan() = %v, want %v", got, tt.want) 278 } 279 }) 280 } 281 }