From a960fd3d568e9d65ccda0fb7d0e46d78c85e92f0 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 13 Aug 2023 16:52:20 +0800 Subject: [PATCH] improve unit test --- pkg/uuid/internal_generator_test.go | 172 ++++++++++++++++++++++++---- 1 file changed, 149 insertions(+), 23 deletions(-) diff --git a/pkg/uuid/internal_generator_test.go b/pkg/uuid/internal_generator_test.go index b670b9d3..ec2f05c7 100644 --- a/pkg/uuid/internal_generator_test.go +++ b/pkg/uuid/internal_generator_test.go @@ -12,16 +12,21 @@ import ( ) func TestGenerateUuid(t *testing.T) { - expectedUnixTime := time.Now().Unix() expectedUuidServerId := uint8(90) expectedUuidType := UUID_TYPE_TRANSACTION generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: expectedUuidServerId}) + + generationStartUnixTime := time.Now().Unix() uuid := generator.GenerateUuid(expectedUuidType) + generationEndUnixTime := time.Now().Unix() + uuidInfo := generator.parseInternalUuidInfo(uuid) - actualUnixTime := uuidInfo.UnixTime - assert.Equal(t, uint32(expectedUnixTime), actualUnixTime) + if generationStartUnixTime == generationEndUnixTime { + actualUnixTime := uuidInfo.UnixTime + assert.Equal(t, uint32(generationStartUnixTime), actualUnixTime) + } actualUuidServerId := uuidInfo.UuidServerId assert.Equal(t, expectedUuidServerId, actualUuidServerId) @@ -56,24 +61,34 @@ func TestGenerateUuid_MultiType(t *testing.T) { func TestGenerateUuid_2000TimesIn2Seconds(t *testing.T) { generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: 2}) - expectedUnixTime := time.Now().Unix() for i := 0; i < 1000; i++ { + generationStartUnixTime := time.Now().Unix() uuid := generator.GenerateUuid(UUID_TYPE_USER) + generationEndUnixTime := time.Now().Unix() + uuidInfo := generator.parseInternalUuidInfo(uuid) - assert.Equal(t, uint32(expectedUnixTime), uuidInfo.UnixTime) + if generationStartUnixTime == generationEndUnixTime { + assert.Equal(t, uint32(generationStartUnixTime), uuidInfo.UnixTime) + } + assert.Equal(t, uint32(i), uuidInfo.SequentialId) } time.Sleep(1 * time.Second) - expectedUnixTime = time.Now().Unix() for i := 0; i < 1000; i++ { + generationStartUnixTime := time.Now().Unix() uuid := generator.GenerateUuid(UUID_TYPE_USER) + generationEndUnixTime := time.Now().Unix() + uuidInfo := generator.parseInternalUuidInfo(uuid) - assert.Equal(t, uint32(expectedUnixTime), uuidInfo.UnixTime) + if generationStartUnixTime == generationEndUnixTime { + assert.Equal(t, uint32(generationStartUnixTime), uuidInfo.UnixTime) + } + assert.Equal(t, uint32(i), uuidInfo.SequentialId) } } @@ -90,14 +105,66 @@ func TestGenerateUuid_10000TimesConcurrent(t *testing.T) { waitGroup.Add(1) for cycle := 0; cycle < 1000; cycle++ { - expectedUnixTime := time.Now().Unix() + generationStartUnixTime := time.Now().Unix() uuid := generator.GenerateUuid(UUID_TYPE_USER) + generationEndUnixTime := time.Now().Unix() + uuidInfo := generator.parseInternalUuidInfo(uuid) - if uint32(expectedUnixTime) != uuidInfo.UnixTime { - mutex.Lock() - assert.Equal(t, uint32(expectedUnixTime), uuidInfo.UnixTime) - mutex.Unlock() + if generationStartUnixTime == generationEndUnixTime { + if uint32(generationStartUnixTime) != uuidInfo.UnixTime { + mutex.Lock() + assert.Equal(t, uint32(generationStartUnixTime), uuidInfo.UnixTime) + mutex.Unlock() + } + } + + if uuidInfo.SequentialId == 0 { + if existedRoutineIndex, exists := generatedIds.Load(uuid); exists { + mutex.Lock() + assert.Fail(t, fmt.Sprintf("uuid \"%d\" conflicts, unix time is %d, seq id is %d, existed routine index is %d, current routine index is %d", uuid, uuidInfo.UnixTime, uuidInfo.SequentialId, existedRoutineIndex, currentRoutineIndex)) + mutex.Unlock() + } + + generatedIds.Store(uuid, currentRoutineIndex) + } + } + + waitGroup.Done() + }(routineIndex) + } + + waitGroup.Wait() +} + +func TestGenerateUuid_1000000TimesConcurrent(t *testing.T) { + concurrentCount := 50 + generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: 3}) + var mutex sync.Mutex + var generatedIds sync.Map + var waitGroup sync.WaitGroup + + for routineIndex := 0; routineIndex < concurrentCount; routineIndex++ { + go func(currentRoutineIndex int) { + waitGroup.Add(1) + + for cycle := 0; cycle < 40000; cycle++ { + if cycle%10000 == 0 { // each server can only generate 500,000 (50 * 10000) uuids in one second + time.Sleep(1000 * time.Millisecond) + } + + generationStartUnixTime := time.Now().Unix() + uuid := generator.GenerateUuid(UUID_TYPE_USER) + generationEndUnixTime := time.Now().Unix() + + uuidInfo := generator.parseInternalUuidInfo(uuid) + + if generationStartUnixTime == generationEndUnixTime { + if uint32(generationStartUnixTime) != uuidInfo.UnixTime { + mutex.Lock() + assert.Equal(t, uint32(generationStartUnixTime), uuidInfo.UnixTime) + mutex.Unlock() + } } if uuidInfo.SequentialId == 0 { @@ -130,19 +197,23 @@ func TestGenerateUuids_Count0(t *testing.T) { } func TestGenerateUuids_Count255(t *testing.T) { - expectedUnixTime := time.Now().Unix() expectedUuidServerId := uint8(90) expectedUuidType := UUID_TYPE_TRANSACTION expectedUuidCount := uint8(255) generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: expectedUuidServerId}) + + generationStartUnixTime := time.Now().Unix() uuids := generator.GenerateUuids(expectedUuidType, expectedUuidCount) + generationEndUnixTime := time.Now().Unix() for i := 0; i < int(expectedUuidCount); i++ { uuidInfo := generator.parseInternalUuidInfo(uuids[i]) - actualUnixTime := uuidInfo.UnixTime - assert.Equal(t, uint32(expectedUnixTime), actualUnixTime) + if generationStartUnixTime == generationEndUnixTime { + actualUnixTime := uuidInfo.UnixTime + assert.Equal(t, uint32(generationStartUnixTime), actualUnixTime) + } actualUuidServerId := uuidInfo.UuidServerId assert.Equal(t, expectedUuidServerId, actualUuidServerId) @@ -166,15 +237,18 @@ func TestGenerateUuids_30TimesIn3Seconds(t *testing.T) { generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: expectedUuidServerId}) for cycle := 0; cycle < 30; cycle++ { - expectedUnixTime := time.Now().Unix() + generationStartUnixTime := time.Now().Unix() uuids := generator.GenerateUuids(expectedUuidType, expectedUuidCount) + generationEndUnixTime := time.Now().Unix() var firstSeqId uint32 for i := 0; i < int(expectedUuidCount); i++ { uuidInfo := generator.parseInternalUuidInfo(uuids[i]) - actualUnixTime := uuidInfo.UnixTime - assert.Equal(t, uint32(expectedUnixTime), actualUnixTime) + if generationStartUnixTime == generationEndUnixTime { + actualUnixTime := uuidInfo.UnixTime + assert.Equal(t, uint32(generationStartUnixTime), actualUnixTime) + } actualUuidServerId := uuidInfo.UuidServerId assert.Equal(t, expectedUuidServerId, actualUuidServerId) @@ -208,16 +282,68 @@ func TestGenerateUuids_20000TimesConcurrent(t *testing.T) { waitGroup.Add(1) for cycle := 0; cycle < 100; cycle++ { - expectedUnixTime := time.Now().Unix() + generationStartUnixTime := time.Now().Unix() uuids := generator.GenerateUuids(UUID_TYPE_USER, expectedUuidCount) + generationEndUnixTime := time.Now().Unix() for i := 0; i < int(expectedUuidCount); i++ { uuidInfo := generator.parseInternalUuidInfo(uuids[i]) - if uint32(expectedUnixTime) != uuidInfo.UnixTime { - mutex.Lock() - assert.Equal(t, uint32(expectedUnixTime), uuidInfo.UnixTime) - mutex.Unlock() + if generationStartUnixTime == generationEndUnixTime { + if uint32(generationStartUnixTime) != uuidInfo.UnixTime { + mutex.Lock() + assert.Equal(t, uint32(generationStartUnixTime), uuidInfo.UnixTime) + mutex.Unlock() + } + } + + if existedRoutineIndex, exists := generatedIds.Load(uuids[i]); exists { + mutex.Lock() + assert.Fail(t, fmt.Sprintf("uuid \"%d\" conflicts, unix time is %d, seq id is %d, existed routine index is %d, current routine index is %d", uuids[i], uuidInfo.UnixTime, uuidInfo.SequentialId, existedRoutineIndex, currentRoutineIndex)) + mutex.Unlock() + } + + generatedIds.Store(uuids[i], currentRoutineIndex) + } + } + + waitGroup.Done() + }(routineIndex) + } + + waitGroup.Wait() +} + +func TestGenerateUuids_1000000TimesConcurrent(t *testing.T) { + concurrentCount := 50 + expectedUuidCount := uint8(100) + generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: 3}) + var mutex sync.Mutex + var generatedIds sync.Map + var waitGroup sync.WaitGroup + + for routineIndex := 0; routineIndex < concurrentCount; routineIndex++ { + go func(currentRoutineIndex int) { + waitGroup.Add(1) + + for cycle := 0; cycle < 400; cycle++ { + if cycle%100 == 0 { // each server can only generate 500,000 (50 * 10000) uuids in one second + time.Sleep(1000 * time.Millisecond) + } + + generationStartUnixTime := time.Now().Unix() + uuids := generator.GenerateUuids(UUID_TYPE_USER, expectedUuidCount) + generationEndUnixTime := time.Now().Unix() + + for i := 0; i < int(expectedUuidCount); i++ { + uuidInfo := generator.parseInternalUuidInfo(uuids[i]) + + if generationStartUnixTime == generationEndUnixTime { + if uint32(generationStartUnixTime) != uuidInfo.UnixTime { + mutex.Lock() + assert.Equal(t, uint32(generationStartUnixTime), uuidInfo.UnixTime) + mutex.Unlock() + } } if existedRoutineIndex, exists := generatedIds.Load(uuids[i]); exists {