1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20package thrift 21 22import ( 23 "fmt" 24 "testing" 25 "testing/quick" 26) 27 28func TestHexToByte(t *testing.T) { 29 for _, c := range []struct { 30 s string 31 b byte 32 fail bool 33 }{ 34 { 35 s: "ff", 36 b: 0xff, 37 }, 38 { 39 s: "FF", 40 b: 0xff, 41 }, 42 { 43 s: "00", 44 b: 0, 45 }, 46 { 47 s: "77", 48 b: 0x77, 49 }, 50 { 51 s: "aC", 52 b: 0xac, 53 }, 54 { 55 s: "xx", 56 fail: true, 57 }, 58 { 59 s: "x0", 60 fail: true, 61 }, 62 { 63 s: "fx", 64 fail: true, 65 }, 66 } { 67 t.Run(c.s, func(t *testing.T) { 68 b, ok := hexToByte(c.s[0], c.s[1]) 69 if ok != !c.fail { 70 t.Errorf("Want failure, got %x, %v", b, ok) 71 } 72 if !c.fail && b != c.b { 73 t.Errorf("Want %x, got %x", c.b, b) 74 } 75 }) 76 } 77} 78 79func TestUUIDString(t *testing.T) { 80 for _, c := range []struct { 81 uuid Tuuid 82 want string 83 }{ 84 { 85 uuid: Tuuid{}, 86 want: "00000000-0000-0000-0000-000000000000", 87 }, 88 { 89 uuid: Tuuid{ 90 0x6b, 0xa7, 0xb8, 0x10, 91 0x9d, 0xad, 92 0x11, 0xd1, 93 0x80, 0xb4, 94 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, 95 }, 96 want: "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 97 }, 98 { 99 uuid: Tuuid{ 100 0x6b, 0xa7, 0xB8, 0x11, 101 0x9d, 0xAd, 102 0x11, 0xd1, 103 0x80, 0xb4, 104 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, 105 }, 106 want: "6ba7b811-9dad-11d1-80b4-00c04fd430c8", 107 }, 108 { 109 uuid: Tuuid{ 110 0x6b, 0xa7, 0xb8, 0x12, 111 0x9d, 0xad, 112 0x11, 0xd1, 113 0x80, 0xb4, 114 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, 115 }, 116 want: "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 117 }, 118 { 119 uuid: Tuuid{ 120 0x6b, 0xa7, 0xb8, 0x14, 121 0x9d, 0xad, 122 0x11, 0xd1, 123 0x80, 0xb4, 124 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, 125 }, 126 want: "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 127 }, 128 } { 129 t.Run(fmt.Sprintf("% 02x", c.uuid[:]), func(t *testing.T) { 130 got := c.uuid.String() 131 if got != c.want { 132 t.Errorf("got %q, want %q", got, c.want) 133 } 134 }) 135 } 136} 137 138func TestUUIDParse(t *testing.T) { 139 for _, c := range []struct { 140 uuid string 141 want Tuuid 142 err bool 143 }{ 144 { 145 uuid: "00000000-0000-0000-0000-000000000000", 146 want: Tuuid{ 147 0x00, 0x00, 0x00, 0x00, 148 0x00, 0x00, 149 0x00, 0x00, 150 0x00, 0x00, 151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 152 }, 153 }, 154 { 155 uuid: "6BA7B810-9DAD-11D1-80B4-00C04FD430C8", 156 want: Tuuid{ 157 0x6B, 0xA7, 0xB8, 0x10, 158 0x9D, 0xAD, 159 0x11, 0xD1, 160 0x80, 0xB4, 161 0x00, 0xC0, 0x4F, 0xD4, 0x30, 0xC8, 162 }, 163 }, 164 { 165 uuid: "6ba7B811-9dAd-11d1-80b4-00c04fd430c8", 166 want: Tuuid{ 167 0x6b, 0xa7, 0xB8, 0x11, 168 0x9d, 0xAd, 169 0x11, 0xd1, 170 0x80, 0xb4, 171 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, 172 }, 173 }, 174 { 175 uuid: "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 176 want: Tuuid{ 177 0x6b, 0xa7, 0xb8, 0x12, 178 0x9d, 0xad, 179 0x11, 0xd1, 180 0x80, 0xb4, 181 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, 182 }, 183 }, 184 { 185 uuid: "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 186 want: Tuuid{ 187 0x6b, 0xa7, 0xb8, 0x14, 188 0x9d, 0xad, 189 0x11, 0xd1, 190 0x80, 0xb4, 191 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, 192 }, 193 }, 194 { 195 uuid: "00000000000000000000000000000000", 196 err: true, // not in canonical form 197 }, 198 { 199 uuid: "6ba7b810-9d-ad11d1-80b4-00c04fd430c8", 200 err: true, // wrong position of hyphens 201 }, 202 { 203 uuid: "urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8", 204 err: true, // urn form is not supported 205 }, 206 { 207 uuid: "{6ba7b812-9dad-11d1-80b4-00c04fd430c8}", 208 err: true, // guid with braces form is not supported 209 }, 210 { 211 uuid: "6xa7b814-9dad-11d1-80b4-00c04fd430c8", 212 err: true, // non-hex numbers 213 }, 214 } { 215 t.Run(c.uuid, func(t *testing.T) { 216 uuid, err := ParseTuuid(c.uuid) 217 if c.err { 218 if err == nil { 219 t.Errorf("Got %v, want error", uuid) 220 } 221 } else { 222 if err != nil { 223 t.Errorf("Failed to parse: %v", err) 224 } 225 if uuid != c.want { 226 t.Errorf("Got %v, want %v", uuid, c.want) 227 } 228 } 229 }) 230 } 231} 232 233func TestUUIDQuick(t *testing.T) { 234 f := func(u Tuuid) bool { 235 s := u.String() 236 parsed, err := ParseTuuid(s) 237 if err != nil { 238 t.Error(err) 239 } 240 if parsed != u { 241 t.Errorf("Parsed %v want %v", parsed, u) 242 } 243 return !t.Failed() 244 } 245 if err := quick.Check(f, nil); err != nil { 246 t.Error(err) 247 } 248} 249 250func BenchmarkUUIDParse(b *testing.B) { 251 for _, s := range []string{ 252 "00000000-0000-0000-0000-000000000000", 253 "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 254 "6ba7b811-9dad-11d1-80b4-00c04fd430c8", 255 "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 256 "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 257 } { 258 b.Run(s, func(b *testing.B) { 259 b.ReportAllocs() 260 if _, err := ParseTuuid(s); err != nil { 261 b.Fatalf("Unable to parse %q: %v", s, err) 262 } 263 b.ResetTimer() 264 b.RunParallel(func(pb *testing.PB) { 265 for pb.Next() { 266 ParseTuuid(s) 267 } 268 }) 269 }) 270 } 271} 272 273func BenchmarkUUIDString(b *testing.B) { 274 for _, u := range []Tuuid{ 275 {}, 276 Must(ParseTuuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8")), 277 Must(ParseTuuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8")), 278 Must(ParseTuuid("6ba7b812-9dad-11d1-80b4-00c04fd430c8")), 279 Must(ParseTuuid("6ba7b814-9dad-11d1-80b4-00c04fd430c8")), 280 } { 281 b.Run(u.String(), func(b *testing.B) { 282 b.ReportAllocs() 283 b.RunParallel(func(pb *testing.PB) { 284 for pb.Next() { 285 _ = u.String() 286 } 287 }) 288 }) 289 } 290} 291