github.com/benz9527/xboot@v0.0.0-20240504061247-c23f15593274/lib/id/x_snowflake_id_test.go (about)

     1  package id
     2  
     3  import (
     4  	"net"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestXSnowflakeID_53BitsMask(t *testing.T) {
    12  	require.Equal(t, int64(0b111), -1^(int64(-1)<<3))
    13  	require.Equal(t, int64(0x1F_FFFF_FFFF_FFFF), xSnowflakeTsAndSequenceMask)
    14  }
    15  
    16  func TestGetMACAsWorkerID(t *testing.T) {
    17  	interfaces, err := net.Interfaces()
    18  	if err != nil {
    19  		t.Skip("unable to fetch interfaces MAC", err)
    20  	}
    21  
    22  	iface := interfaces[0]
    23  	if len(iface.HardwareAddr) <= 0 {
    24  		t.Skip("unable to fetch interfaces MAC", iface)
    25  	}
    26  
    27  	t.Log(iface.HardwareAddr[4], iface.HardwareAddr[5])
    28  }
    29  
    30  func TestXSnowFlakeID(t *testing.T) {
    31  	gen, err := XSnowFlakeID(
    32  		-1,
    33  		1,
    34  		func() time.Time {
    35  			return time.Now()
    36  		},
    37  	)
    38  	require.Error(t, err)
    39  
    40  	gen, err = XSnowFlakeID(
    41  		1,
    42  		-1,
    43  		func() time.Time {
    44  			return time.Now()
    45  		},
    46  	)
    47  	require.Error(t, err)
    48  
    49  	gen, err = XSnowFlakeID(
    50  		xSnowflakeDIDMax+1,
    51  		1,
    52  		func() time.Time {
    53  			return time.Now()
    54  		},
    55  	)
    56  	require.Error(t, err)
    57  
    58  	gen, err = XSnowFlakeID(
    59  		1,
    60  		xSnowflakeMIDMax+1,
    61  		func() time.Time {
    62  			return time.Now()
    63  		},
    64  	)
    65  	require.Error(t, err)
    66  
    67  	interfaces, err := net.Interfaces()
    68  	if err != nil {
    69  		t.Skip("unable to fetch interfaces MAC", err)
    70  	}
    71  
    72  	iface := interfaces[0]
    73  	if len(iface.HardwareAddr) <= 0 {
    74  		t.Skip("unable to fetch interfaces MAC", iface)
    75  	}
    76  
    77  	workerID := ((int64(iface.HardwareAddr[4]) & 0b11) << 8) | int64(iface.HardwareAddr[5]&0xFF)
    78  	gen, err = XSnowFlakeIDByWorkerID(
    79  		workerID,
    80  		func() time.Time {
    81  			return time.Now()
    82  		},
    83  	)
    84  	require.NoError(t, err)
    85  	require.NotNil(t, gen)
    86  	for i := 0; i < 1000; i++ {
    87  		require.Less(t, gen.Number(), gen.Number())
    88  	}
    89  	require.NotEqual(t, gen.Str(), gen.Str())
    90  }
    91  
    92  func TestXSnowFlakeID_ByMAC_DataRace(t *testing.T) {
    93  	interfaces, err := net.Interfaces()
    94  	if err != nil {
    95  		t.Skip("unable to fetch interfaces MAC", err)
    96  	}
    97  
    98  	iface := interfaces[0]
    99  	if len(iface.HardwareAddr) <= 0 {
   100  		t.Skip("unable to fetch interfaces MAC", iface)
   101  	}
   102  	workerID := ((int64(iface.HardwareAddr[4]) & 0b11) << 8) | int64(iface.HardwareAddr[5]&0xFF)
   103  	gen, err := XSnowFlakeIDByWorkerID(
   104  		workerID,
   105  		func() time.Time {
   106  			return time.Now()
   107  		},
   108  	)
   109  	require.NoError(t, err)
   110  	require.NotNil(t, gen)
   111  	for i := 0; i < 1000; i++ {
   112  		go func() {
   113  			require.Less(t, gen.Number(), gen.Number())
   114  		}()
   115  	}
   116  	require.NotEqual(t, gen.Str(), gen.Str())
   117  }
   118  
   119  func BenchmarkXSnowFlakeID_ByMAC(b *testing.B) {
   120  	interfaces, err := net.Interfaces()
   121  	if err != nil {
   122  		b.Skip("unable to fetch interfaces MAC", err)
   123  	}
   124  
   125  	iface := interfaces[0]
   126  	if len(iface.HardwareAddr) <= 0 {
   127  		b.Skip("unable to fetch interfaces MAC", iface)
   128  	}
   129  
   130  	workerID := ((int64(iface.HardwareAddr[4]) & 0b11) << 8) | int64(iface.HardwareAddr[5]&0xFF)
   131  	gen, err := XSnowFlakeIDByWorkerID(
   132  		workerID,
   133  		func() time.Time {
   134  			return time.Now()
   135  		},
   136  	)
   137  	require.NoError(b, err)
   138  	require.NotNil(b, gen)
   139  
   140  	b.ResetTimer()
   141  	for i := 0; i < b.N; i++ {
   142  		_ = gen.Number()
   143  	}
   144  	b.ReportAllocs()
   145  }