github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/snow/snow_test.go (about) 1 package snow 2 3 import ( 4 "bytes" 5 "fmt" 6 "reflect" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestNewNodeLocalIP(t *testing.T) { 14 that := assert.New(t) 15 16 node, err := NewNode(WithNodeIDLocalIP(0, "192.168.0.10")) 17 18 that.Nil(err) 19 that.Equal(int64(10), node.GetNodeID()) 20 that.Equal(int64(10), node.NodeIDOf(node.Next())) 21 22 node, err = NewNode(WithNodeIDLocalIP(1, "192.168.0.10")) 23 24 that.Nil(err) 25 that.Equal(int64(1<<8|10), node.GetNodeID()) 26 that.Equal(int64(1<<8|10), node.NodeIDOf(node.Next())) 27 28 node, err = NewNode(WithEpoch(12345678)) 29 30 that.Nil(err) 31 that.True(node.TimeOf(node.Next()) > node.GetEpoch()) 32 } 33 34 //****************************************************************************** 35 // General Test funcs 36 37 func TestNewNode(t *testing.T) { 38 _, err := NewNode(WithNodeID(0)) 39 if err != nil { 40 t.Fatalf("error creating NewNode, %s", err) 41 } 42 43 _, err = NewNode(WithNodeID(5000)) 44 if err == nil { 45 t.Fatalf("no error creating NewNode, %s", err) 46 } 47 } 48 49 // lazy check if Next will create duplicate IDs 50 // would be good to later enhance this with more smarts 51 func TestGenerateDuplicateID(t *testing.T) { 52 node, _ := NewNode(WithNodeID(1)) 53 54 var x, y ID 55 for i := 0; i < 1000000; i++ { 56 y = node.Next() 57 if x == y { 58 t.Errorf("x(%d) & y(%d) are the same", x, y) 59 } 60 61 x = y 62 } 63 } 64 65 // I feel like there's probably a better way 66 func TestRace(t *testing.T) { 67 node, _ := NewNode(WithNodeID(1)) 68 69 go func() { 70 for i := 0; i < 1000000000; i++ { 71 NewNode(WithNodeID(1)) 72 } 73 }() 74 75 for i := 0; i < 4000; i++ { 76 node.Next() 77 } 78 } 79 80 func TestUint32(t *testing.T) { 81 start := time.Now() 82 for i := 0; i < 10; i++ { 83 fmt.Println(Next32()) 84 } 85 86 fmt.Println(time.Since(start)) 87 } 88 89 //****************************************************************************** 90 // Converters/Parsers Test funcs 91 // We should have funcs here to test conversion both ways for everything 92 93 func TestPrintAll(t *testing.T) { 94 node, err := NewNode(WithNodeID(0)) 95 if err != nil { 96 t.Fatalf("error creating NewNode, %s", err) 97 } 98 99 id := node.Next() 100 101 t.Logf("Int32 : %d", id.Int32()) 102 v := node.Next() 103 t.Logf("Uint32 : %d", uint32(v)) 104 t.Logf("Uint32 : %d", uint32(v+1)) 105 t.Logf("Uint32 : %d", uint32(v+2)) 106 t.Logf("Uint32 : %d", uint32(v+3)) 107 t.Logf("Uint32 : %d", uint32(v+4)) 108 t.Logf("Int64 : %d", id.Int64()) 109 t.Logf("Uint64 : %d", id.Uint64()) 110 t.Logf("String : %s", id.String()) 111 t.Logf("Base2 : %s", id.Base2()) 112 t.Logf("Base32 : %s", id.Base32()) 113 t.Logf("Base36 : %s", id.Base36()) 114 t.Logf("Base58 : %s", id.Base58()) 115 t.Logf("Base64 : %s", id.Base64()) 116 t.Logf("Bytes : %v", id.Bytes()) 117 t.Logf("IntBytes : %v", id.IntBytes()) 118 } 119 120 func TestInt64(t *testing.T) { 121 node, err := NewNode(WithNodeID(0)) 122 if err != nil { 123 t.Fatalf("error creating NewNode, %s", err) 124 } 125 126 oID := node.Next() 127 i := oID.Int64() 128 129 pID := ParseInt64(i) 130 if pID != oID { 131 t.Fatalf("pID %v != oID %v", pID, oID) 132 } 133 134 mi := int64(1116766490855473152) 135 pID = ParseInt64(mi) 136 137 if pID.Int64() != mi { 138 t.Fatalf("pID %v != mi %v", pID.Int64(), mi) 139 } 140 } 141 142 func TestString(t *testing.T) { 143 node, err := NewNode(WithNodeID(0)) 144 if err != nil { 145 t.Fatalf("error creating NewNode, %s", err) 146 } 147 148 oID := node.Next() 149 si := oID.String() 150 151 pID, err := ParseString(si) 152 if err != nil { 153 t.Fatalf("error parsing, %s", err) 154 } 155 156 if pID != oID { 157 t.Fatalf("pID %v != oID %v", pID, oID) 158 } 159 160 ms := `1116766490855473152` 161 _, err = ParseString(ms) 162 163 if err != nil { 164 t.Fatalf("error parsing, %s", err) 165 } 166 167 ms = `1112316766490855473152` 168 169 _, err = ParseString(ms) 170 171 if err == nil { 172 t.Fatalf("no error parsing %s", ms) 173 } 174 } 175 176 func TestBase2(t *testing.T) { 177 node, err := NewNode(WithNodeID(0)) 178 if err != nil { 179 t.Fatalf("error creating NewNode, %s", err) 180 } 181 182 oID := node.Next() 183 i := oID.Base2() 184 185 pID, err := ParseBase2(i) 186 if err != nil { 187 t.Fatalf("error parsing, %s", err) 188 } 189 190 if pID != oID { 191 t.Fatalf("pID %v != oID %v", pID, oID) 192 } 193 194 ms := `111101111111101110110101100101001000000000000000000000000000` 195 _, err = ParseBase2(ms) 196 197 if err != nil { 198 t.Fatalf("error parsing, %s", err) 199 } 200 201 ms = `1112316766490855473152` 202 _, err = ParseBase2(ms) 203 204 if err == nil { 205 t.Fatalf("no error parsing %s", ms) 206 } 207 } 208 209 func TestBase32(t *testing.T) { 210 node, err := NewNode(WithNodeID(0)) 211 if err != nil { 212 t.Fatalf("error creating NewNode, %s", err) 213 } 214 215 for i := 0; i < 100; i++ { 216 sf := node.Next() 217 b32i := sf.Base32() 218 psf, err := ParseBase32([]byte(b32i)) 219 if err != nil { 220 t.Fatal(err) 221 } 222 223 if sf != psf { 224 t.Fatal("Parsed does not match String.") 225 } 226 } 227 } 228 229 func TestBase36(t *testing.T) { 230 node, err := NewNode(WithNodeID(0)) 231 if err != nil { 232 t.Fatalf("error creating NewNode, %s", err) 233 } 234 235 oID := node.Next() 236 i := oID.Base36() 237 238 pID, err := ParseBase36(i) 239 if err != nil { 240 t.Fatalf("error parsing, %s", err) 241 } 242 243 if pID != oID { 244 t.Fatalf("pID %v != oID %v", pID, oID) 245 } 246 247 ms := `8hgmw4blvlkw` 248 _, err = ParseBase36(ms) 249 250 if err != nil { 251 t.Fatalf("error parsing, %s", err) 252 } 253 254 ms = `68h5gmw443blv2lk1w` 255 _, err = ParseBase36(ms) 256 257 if err == nil { 258 t.Fatalf("no error parsing, %s", err) 259 } 260 } 261 262 func TestBase58(t *testing.T) { 263 node, err := NewNode(WithNodeID(0)) 264 if err != nil { 265 t.Fatalf("error creating NewNode, %s", err) 266 } 267 268 for i := 0; i < 10; i++ { 269 sf := node.Next() 270 b58 := sf.Base58() 271 psf, err := ParseBase58([]byte(b58)) 272 if err != nil { 273 t.Fatal(err) 274 } 275 276 if sf != psf { 277 t.Fatal("Parsed does not match String.") 278 } 279 } 280 } 281 282 func TestBase64(t *testing.T) { 283 node, err := NewNode(WithNodeID(0)) 284 if err != nil { 285 t.Fatalf("error creating NewNode, %s", err) 286 } 287 288 oID := node.Next() 289 i := oID.Base64() 290 291 pID, err := ParseBase64(i) 292 if err != nil { 293 t.Fatalf("error parsing, %s", err) 294 } 295 296 if pID != oID { 297 t.Fatalf("pID %v != oID %v", pID, oID) 298 } 299 300 ms := `MTExNjgxOTQ5NDY2MDk5NzEyMA==` 301 _, err = ParseBase64(ms) 302 303 if err != nil { 304 t.Fatalf("error parsing, %s", err) 305 } 306 307 ms = `MTExNjgxOTQ5NDY2MDk5NzEyMA` 308 _, err = ParseBase64(ms) 309 310 if err == nil { 311 t.Fatalf("no error parsing, %s", err) 312 } 313 } 314 315 func TestBytes(t *testing.T) { 316 node, err := NewNode(WithNodeID(0)) 317 if err != nil { 318 t.Fatalf("error creating NewNode, %s", err) 319 } 320 321 oID := node.Next() 322 i := oID.Bytes() 323 324 pID, err := ParseBytes(i) 325 if err != nil { 326 t.Fatalf("error parsing, %s", err) 327 } 328 329 if pID != oID { 330 t.Fatalf("pID %v != oID %v", pID, oID) 331 } 332 333 ms := []byte{0x31, 0x31, 0x31, 0x36, 0x38, 0x32, 0x31, 0x36, 0x37, 0x39, 0x35, 0x37, 0x30, 0x34, 0x31, 0x39, 0x37, 0x31, 0x32} 334 _, err = ParseBytes(ms) 335 336 if err != nil { 337 t.Fatalf("error parsing, %#v", err) 338 } 339 340 ms = []byte{0xFF, 0xFF, 0xFF, 0x31, 0x31, 0x31, 0x36, 0x38, 0x32, 0x31, 0x36, 0x37, 0x39, 0x35, 0x37, 0x30, 0x34, 0x31, 0x39, 0x37, 0x31, 0x32} 341 _, err = ParseBytes(ms) 342 343 if err == nil { 344 t.Fatalf("no error parsing, %#v", err) 345 } 346 } 347 348 func TestIntBytes(t *testing.T) { 349 node, err := NewNode(WithNodeID(0)) 350 if err != nil { 351 t.Fatalf("error creating NewNode, %s", err) 352 } 353 354 oID := node.Next() 355 i := oID.IntBytes() 356 357 pID := ParseIntBytes(i) 358 if pID != oID { 359 t.Fatalf("pID %v != oID %v", pID, oID) 360 } 361 362 ms := [8]uint8{0xf, 0x7f, 0xc0, 0xfc, 0x2f, 0x80, 0x0, 0x0} 363 mi := int64(1116823421972381696) 364 pID = ParseIntBytes(ms) 365 366 if pID.Int64() != mi { 367 t.Fatalf("pID %v != mi %v", pID.Int64(), mi) 368 } 369 } 370 371 //****************************************************************************** 372 // Marshall Test Methods 373 374 func TestMarshalJSON(t *testing.T) { 375 id := ID(13587) 376 expected := "\"13587\"" 377 378 bytes, err := id.MarshalJSON() 379 if err != nil { 380 t.Fatalf("Unexpected error during MarshalJSON") 381 } 382 383 if string(bytes) != expected { 384 t.Fatalf("Got %s, expected %s", string(bytes), expected) 385 } 386 } 387 388 func TestMarshalsIntBytes(t *testing.T) { 389 id := ID(13587).IntBytes() 390 expected := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x35, 0x13} 391 392 if !bytes.Equal(id[:], expected) { 393 t.Fatalf("Expected ID to be encoded as %v, got %v", expected, id) 394 } 395 } 396 397 func TestUnmarshalJSON(t *testing.T) { 398 tt := []struct { 399 json string 400 expectedID ID 401 expectedErr error 402 }{ 403 {`"13587"`, 13587, nil}, 404 {`1`, 0, JSONSyntaxError{[]byte(`1`)}}, 405 {`"invalid`, 0, JSONSyntaxError{[]byte(`"invalid`)}}, 406 } 407 408 for _, tc := range tt { 409 var id ID 410 err := id.UnmarshalJSON([]byte(tc.json)) 411 412 if !reflect.DeepEqual(err, tc.expectedErr) { 413 t.Fatalf("Expected to get error '%s' decoding JSON, but got '%s'", tc.expectedErr, err) 414 } 415 416 if id != tc.expectedID { 417 t.Fatalf("Expected to get ID '%s' decoding JSON, but got '%s'", tc.expectedID, id) 418 } 419 } 420 } 421 422 // **************************************************************************** 423 // Benchmark Methods 424 425 // nolint gomnd 426 func BenchmarkParseBase32(b *testing.B) { 427 node, _ := NewNode(WithNodeID(1)) 428 sf := node.Next() 429 b32i := sf.Base32() 430 431 b.ReportAllocs() 432 b.ResetTimer() 433 434 for n := 0; n < b.N; n++ { 435 ParseBase32([]byte(b32i)) 436 } 437 } 438 439 func BenchmarkBase32(b *testing.B) { 440 node, _ := NewNode(WithNodeID(1)) 441 sf := node.Next() 442 443 b.ReportAllocs() 444 445 b.ResetTimer() 446 447 for n := 0; n < b.N; n++ { 448 sf.Base32() 449 } 450 } 451 452 func BenchmarkParseBase58(b *testing.B) { 453 node, _ := NewNode(WithNodeID(1)) 454 sf := node.Next() 455 b58 := sf.Base58() 456 457 b.ReportAllocs() 458 459 b.ResetTimer() 460 461 for n := 0; n < b.N; n++ { 462 ParseBase58([]byte(b58)) 463 } 464 } 465 466 func BenchmarkBase58(b *testing.B) { 467 node, _ := NewNode(WithNodeID(1)) 468 sf := node.Next() 469 470 b.ReportAllocs() 471 472 b.ResetTimer() 473 474 for n := 0; n < b.N; n++ { 475 sf.Base58() 476 } 477 } 478 479 func BenchmarkGenerate(b *testing.B) { 480 node, _ := NewNode(WithNodeID(1)) 481 482 b.ReportAllocs() 483 484 b.ResetTimer() 485 486 for n := 0; n < b.N; n++ { 487 _ = node.Next() 488 } 489 } 490 491 func BenchmarkGenerateMaxSequence(b *testing.B) { 492 node, _ := NewNode(WithNodeID(1), WithNodeBits(1), WithStepBits(21)) 493 494 b.ReportAllocs() 495 b.ResetTimer() 496 497 for n := 0; n < b.N; n++ { 498 _ = node.Next() 499 } 500 } 501 502 func BenchmarkUnmarshal(b *testing.B) { 503 // Next the ID to unmarshal 504 node, _ := NewNode(WithNodeID(1)) 505 id := node.Next() 506 bytes, _ := id.MarshalJSON() 507 508 var id2 ID 509 510 b.ReportAllocs() 511 b.ResetTimer() 512 513 for n := 0; n < b.N; n++ { 514 _ = id2.UnmarshalJSON(bytes) 515 } 516 } 517 518 func BenchmarkMarshal(b *testing.B) { 519 // Next the ID to marshal 520 node, _ := NewNode(WithNodeID(1)) 521 id := node.Next() 522 523 b.ReportAllocs() 524 b.ResetTimer() 525 526 for n := 0; n < b.N; n++ { 527 _, _ = id.MarshalJSON() 528 } 529 }