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  }