123 lines
3.5 KiB
Go
123 lines
3.5 KiB
Go
package uuid
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
|
)
|
|
|
|
func TestGenerateUuid(t *testing.T) {
|
|
expectedUnixTime := time.Now().Unix()
|
|
expectedUuidServerId := uint8(90)
|
|
expectedUuidType := UUID_TYPE_TRANSACTION
|
|
|
|
generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: expectedUuidServerId})
|
|
uuid := generator.GenerateUuid(expectedUuidType)
|
|
uuidInfo := generator.ParseUuidInfo(uuid)
|
|
|
|
actualUnixTime := uuidInfo.UnixTime
|
|
assert.Equal(t, uint32(expectedUnixTime), actualUnixTime)
|
|
|
|
actualUuidServerId := uuidInfo.UuidServerId
|
|
assert.Equal(t, expectedUuidServerId, actualUuidServerId)
|
|
|
|
actualUuidType := uuidInfo.UuidType
|
|
assert.Equal(t, uint8(expectedUuidType), actualUuidType)
|
|
|
|
expectedSeqId := 0
|
|
actualSeqId := uuidInfo.SequentialId
|
|
assert.Equal(t, uint32(expectedSeqId), actualSeqId)
|
|
}
|
|
|
|
func TestGenerateUuid_MultiType(t *testing.T) {
|
|
generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: 1})
|
|
uuid := generator.GenerateUuid(UUID_TYPE_USER)
|
|
uuidInfo := generator.ParseUuidInfo(uuid)
|
|
|
|
expectedSeqId := 0
|
|
actualSeqId := uuidInfo.SequentialId
|
|
assert.Equal(t, uint32(expectedSeqId), actualSeqId)
|
|
|
|
uuid = generator.GenerateUuid(UUID_TYPE_ACCOUNT)
|
|
uuidInfo = generator.ParseUuidInfo(uuid)
|
|
actualSeqId = uuidInfo.SequentialId
|
|
assert.Equal(t, uint32(expectedSeqId), actualSeqId)
|
|
|
|
uuid = generator.GenerateUuid(UUID_TYPE_TRANSACTION)
|
|
uuidInfo = generator.ParseUuidInfo(uuid)
|
|
actualSeqId = uuidInfo.SequentialId
|
|
assert.Equal(t, uint32(expectedSeqId), actualSeqId)
|
|
}
|
|
|
|
func TestGenerateUuid_1000Times(t *testing.T) {
|
|
generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: 2})
|
|
expectedUnixTime := time.Now().Unix()
|
|
|
|
for i := 0; i < 1000; i++ {
|
|
uuid := generator.GenerateUuid(UUID_TYPE_USER)
|
|
uuidInfo := generator.ParseUuidInfo(uuid)
|
|
|
|
assert.Equal(t, uint32(expectedUnixTime), uuidInfo.UnixTime)
|
|
assert.Equal(t, uint32(i), uuidInfo.SequentialId)
|
|
}
|
|
|
|
time.Sleep(1 * time.Second)
|
|
expectedUnixTime = time.Now().Unix()
|
|
|
|
for i := 0; i < 1000; i++ {
|
|
uuid := generator.GenerateUuid(UUID_TYPE_USER)
|
|
uuidInfo := generator.ParseUuidInfo(uuid)
|
|
|
|
assert.Equal(t, uint32(expectedUnixTime), uuidInfo.UnixTime)
|
|
assert.Equal(t, uint32(i), uuidInfo.SequentialId)
|
|
}
|
|
}
|
|
|
|
func TestGenerateUuid_1000000TimesConcurrent(t *testing.T) {
|
|
generator, _ := NewInternalUuidGenerator(&settings.Config{UuidServerId: 3})
|
|
var mutex sync.Mutex
|
|
var generatedIds sync.Map
|
|
var waitGroup sync.WaitGroup
|
|
|
|
for i := 0; i < 50; i++ {
|
|
go func() {
|
|
waitGroup.Add(1)
|
|
|
|
for j := 0; j < 40000; j++ {
|
|
if j%10000 == 0 { // echo server can only generate 500,000 (50 * 10000) uuids in one second
|
|
time.Sleep(1000 * time.Millisecond)
|
|
}
|
|
|
|
expectedUnixTime := time.Now().Unix()
|
|
uuid := generator.GenerateUuid(UUID_TYPE_USER)
|
|
uuidInfo := generator.ParseUuidInfo(uuid)
|
|
|
|
if uint32(expectedUnixTime) != uuidInfo.UnixTime {
|
|
mutex.Lock()
|
|
assert.Equal(t, uint32(expectedUnixTime), uuidInfo.UnixTime)
|
|
mutex.Unlock()
|
|
}
|
|
|
|
if uuidInfo.SequentialId == 0 {
|
|
if existedUnixTime, exists := generatedIds.Load(uuid); exists {
|
|
mutex.Lock()
|
|
assert.Fail(t, fmt.Sprintf("uuid \"%d\" conflicts, seq id is %d, existed unixtime is %d, current unix time is %d", uuid, uuidInfo.SequentialId, existedUnixTime, uuidInfo.UnixTime))
|
|
mutex.Unlock()
|
|
}
|
|
|
|
generatedIds.Store(uuid, uuidInfo.UnixTime)
|
|
}
|
|
}
|
|
|
|
waitGroup.Done()
|
|
}()
|
|
}
|
|
|
|
waitGroup.Wait()
|
|
}
|