123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- package mhayaSnowflake
- import (
- "bytes"
- "fmt"
- "hash/crc32"
- "strconv"
- "sync/atomic"
- "testing"
- "time"
- )
- func TestPrintID(t *testing.T) {
- node, err := NewNode(1)
- if err != nil {
- t.Log(err)
- return
- }
- for i := 0; i < 10000; i++ {
- id := node.Generate()
- fmt.Println(id.Int64(), id.Base58())
- }
- }
- //******************************************************************************
- // General Test funcs
- func TestNewNode(t *testing.T) {
- _, err := NewNode(1023)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- _, err = NewNode(5000)
- if err == nil {
- t.Fatalf("no error creating NewNode, %s", err)
- }
- }
- // lazy check if Generate will create duplicate IDs
- // would be good to later enhance this with more smarts
- func TestGenerateDuplicateID(t *testing.T) {
- node, _ := NewNode(1)
- var x, y ID
- for i := 0; i < 1000000; i++ {
- y = node.Generate()
- if x == y {
- t.Errorf("x(%d) & y(%d) are the same", x, y)
- }
- x = y
- }
- }
- // I feel like there's probably a better way
- func TestRace(t *testing.T) {
- node, _ := NewNode(1)
- go func() {
- for i := 0; i < 1000000000; i++ {
- NewNode(1)
- }
- }()
- for i := 0; i < 4000; i++ {
- node.Generate()
- }
- }
- func TestAtomicInt64(t *testing.T) {
- nodeId := "database-123"
- nodeIdCRC32 := CRC32(nodeId)
- t.Logf("nodeIdCRC32 : %#v", nodeIdCRC32)
- t.Logf("nodeIdCRC32 binary : %#v", strconv.FormatInt(int64(nodeIdCRC32), 2))
- atomicId := time.Now().Unix()
- t.Logf("atomicId : %#v", atomicId)
- t.Logf("atomicId binary : %#v", strconv.FormatInt(atomicId, 2))
- //1100 0000 0001 1100 0110 1111 0010 110
- for i := 0; i < 10; i++ {
- newId := atomic.AddInt64(&atomicId, 1)
- t.Logf("newid : %#v", newId)
- }
- }
- func CRC32(str string) uint32 {
- return crc32.ChecksumIEEE([]byte(str))
- }
- //******************************************************************************
- // Converters/Parsers Test funcs
- // We should have funcs here to test conversion both ways for everything
- func TestPrintAll(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- id := node.Generate()
- t.Logf("Int64 : %#v", id.Int64())
- t.Logf("String : %#v", id.String())
- t.Logf("Base2 : %#v", id.Base2())
- t.Logf("Base32 : %#v", id.Base32())
- t.Logf("Base36 : %#v", id.Base36())
- t.Logf("Base58 : %#v", id.Base58())
- t.Logf("Base64 : %#v", id.Base64())
- t.Logf("Bytes : %#v", id.Bytes())
- t.Logf("IntBytes : %#v", id.IntBytes())
- }
- func TestInt64(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- oID := node.Generate()
- i := oID.Int64()
- pID := ParseInt64(i)
- if pID != oID {
- t.Fatalf("pID %v != oID %v", pID, oID)
- }
- mi := int64(1116766490855473152)
- pID = ParseInt64(mi)
- if pID.Int64() != mi {
- t.Fatalf("pID %v != mi %v", pID.Int64(), mi)
- }
- }
- func TestString(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- oID := node.Generate()
- si := oID.String()
- pID, err := ParseString(si)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- if pID != oID {
- t.Fatalf("pID %v != oID %v", pID, oID)
- }
- ms := `1116766490855473152`
- _, err = ParseString(ms)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- ms = `1112316766490855473152`
- _, err = ParseString(ms)
- if err == nil {
- t.Fatalf("no error parsing %s", ms)
- }
- }
- func TestBase2(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- oID := node.Generate()
- i := oID.Base2()
- pID, err := ParseBase2(i)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- if pID != oID {
- t.Fatalf("pID %v != oID %v", pID, oID)
- }
- ms := `111101111111101110110101100101001000000000000000000000000000`
- _, err = ParseBase2(ms)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- ms = `1112316766490855473152`
- _, err = ParseBase2(ms)
- if err == nil {
- t.Fatalf("no error parsing %s", ms)
- }
- }
- func TestBase32(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- for i := 0; i < 100; i++ {
- sf := node.Generate()
- b32i := sf.Base32()
- psf, err := ParseBase32([]byte(b32i))
- if err != nil {
- t.Fatal(err)
- }
- if sf != psf {
- t.Fatal("Parsed does not match String.")
- }
- }
- }
- func TestBase36(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- oID := node.Generate()
- i := oID.Base36()
- pID, err := ParseBase36(i)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- if pID != oID {
- t.Fatalf("pID %v != oID %v", pID, oID)
- }
- ms := `8hgmw4blvlkw`
- _, err = ParseBase36(ms)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- ms = `68h5gmw443blv2lk1w`
- _, err = ParseBase36(ms)
- if err == nil {
- t.Fatalf("no error parsing, %s", err)
- }
- }
- func TestBase58(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- for i := 0; i < 10; i++ {
- sf := node.Generate()
- b58 := sf.Base58()
- psf, err := ParseBase58([]byte(b58))
- if err != nil {
- t.Fatal(err)
- }
- if sf != psf {
- t.Fatal("Parsed does not match String.")
- }
- }
- }
- func TestBase64(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- oID := node.Generate()
- i := oID.Base64()
- pID, err := ParseBase64(i)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- if pID != oID {
- t.Fatalf("pID %v != oID %v", pID, oID)
- }
- ms := `MTExNjgxOTQ5NDY2MDk5NzEyMA==`
- _, err = ParseBase64(ms)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- ms = `MTExNjgxOTQ5NDY2MDk5NzEyMA`
- _, err = ParseBase64(ms)
- if err == nil {
- t.Fatalf("no error parsing, %s", err)
- }
- }
- func TestBytes(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- oID := node.Generate()
- i := oID.Bytes()
- pID, err := ParseBytes(i)
- if err != nil {
- t.Fatalf("error parsing, %s", err)
- }
- if pID != oID {
- t.Fatalf("pID %v != oID %v", pID, oID)
- }
- ms := []byte{0x31, 0x31, 0x31, 0x36, 0x38, 0x32, 0x31, 0x36, 0x37, 0x39, 0x35, 0x37, 0x30, 0x34, 0x31, 0x39, 0x37, 0x31, 0x32}
- _, err = ParseBytes(ms)
- if err != nil {
- t.Fatalf("error parsing, %#v", err)
- }
- ms = []byte{0xFF, 0xFF, 0xFF, 0x31, 0x31, 0x31, 0x36, 0x38, 0x32, 0x31, 0x36, 0x37, 0x39, 0x35, 0x37, 0x30, 0x34, 0x31, 0x39, 0x37, 0x31, 0x32}
- _, err = ParseBytes(ms)
- if err == nil {
- t.Fatalf("no error parsing, %#v", err)
- }
- }
- func TestIntBytes(t *testing.T) {
- node, err := NewNode(0)
- if err != nil {
- t.Fatalf("error creating NewNode, %s", err)
- }
- oID := node.Generate()
- i := oID.IntBytes()
- pID := ParseIntBytes(i)
- if pID != oID {
- t.Fatalf("pID %v != oID %v", pID, oID)
- }
- ms := [8]uint8{0xf, 0x7f, 0xc0, 0xfc, 0x2f, 0x80, 0x0, 0x0}
- mi := int64(1116823421972381696)
- pID = ParseIntBytes(ms)
- if pID.Int64() != mi {
- t.Fatalf("pID %v != mi %v", pID.Int64(), mi)
- }
- }
- //******************************************************************************
- // Marshall Test Methods
- func TestMarshalJSON(t *testing.T) {
- id := ID(13587)
- expected := "\"13587\""
- jsonBytes, err := id.MarshalJSON()
- if err != nil {
- t.Fatalf("Unexpected error during MarshalJSON")
- }
- if string(jsonBytes) != expected {
- t.Fatalf("Got %s, expected %s", string(jsonBytes), expected)
- }
- }
- func TestMarshalsIntBytes(t *testing.T) {
- id := ID(13587).IntBytes()
- expected := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x35, 0x13}
- if !bytes.Equal(id[:], expected) {
- t.Fatalf("Expected ID to be encoded as %v, got %v", expected, id)
- }
- }
- func TestUnmarshalJSON(t *testing.T) {
- tt := []struct {
- json string
- expectedID ID
- expectedErr error
- }{
- {`"13587"`, 13587, nil},
- {`1`, 0, JSONSyntaxError{[]byte("1")}},
- {`"invalid`, 0, JSONSyntaxError{[]byte("invalid")}},
- }
- for _, tc := range tt {
- var id ID
- err := id.UnmarshalJSON([]byte(tc.json))
- if err != tc.expectedErr {
- t.Fatalf("Expected to get error '%s' decoding JSON, but got '%s'", tc.expectedErr, err)
- }
- if id != tc.expectedID {
- t.Fatalf("Expected to get ID '%s' decoding JSON, but got '%s'", tc.expectedID, id)
- }
- }
- }
- func TestDefaultNode(t *testing.T) {
- InitDefaultNode("0")
- for i := 0; i < 10; i++ {
- fmt.Println(NextId())
- }
- }
- // ****************************************************************************
- // Benchmark Methods
- func BenchmarkParseBase32(b *testing.B) {
- node, _ := NewNode(1)
- sf := node.Generate()
- b32i := sf.Base32()
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- ParseBase32([]byte(b32i))
- }
- }
- func BenchmarkBase32(b *testing.B) {
- node, _ := NewNode(1)
- sf := node.Generate()
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- sf.Base32()
- }
- }
- func BenchmarkParseBase58(b *testing.B) {
- node, _ := NewNode(1)
- sf := node.Generate()
- b58 := sf.Base58()
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- ParseBase58([]byte(b58))
- }
- }
- func BenchmarkBase58(b *testing.B) {
- node, _ := NewNode(1)
- sf := node.Generate()
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- sf.Base58()
- }
- }
- func BenchmarkGenerate(b *testing.B) {
- node, _ := NewNode(1)
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- _ = node.Generate()
- }
- }
- func BenchmarkGenerateMaxSequence(b *testing.B) {
- NodeBits = 1
- StepBits = 21
- node, _ := NewNode(1)
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- _ = node.Generate()
- }
- }
- func BenchmarkUnmarshal(b *testing.B) {
- // Generate the ID to unmarshal
- node, _ := NewNode(1)
- id := node.Generate()
- jsonBytes, _ := id.MarshalJSON()
- var id2 ID
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- _ = id2.UnmarshalJSON(jsonBytes)
- }
- }
- func BenchmarkMarshal(b *testing.B) {
- // Generate the ID to marshal
- node, _ := NewNode(1)
- id := node.Generate()
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- _, _ = id.MarshalJSON()
- }
- }
|