209 lines
4.4 KiB
Go
209 lines
4.4 KiB
Go
package priority
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
func getRedis() *redis.Client {
|
|
client := redis.NewClient(&redis.Options{
|
|
Addr: "127.0.0.1" + ":" + "6379",
|
|
Password: "123456", // no password set
|
|
DB: 0, // use default DB
|
|
})
|
|
if client == nil {
|
|
panic("redis init error")
|
|
}
|
|
return client
|
|
}
|
|
|
|
func TestPriority(t *testing.T) {
|
|
re := getRedis()
|
|
ctx := context.Background()
|
|
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
|
|
fmt.Println("ff")
|
|
|
|
go func() {
|
|
time.Sleep(time.Second * 5)
|
|
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
|
|
pro, _ := InitPriority(ctx, re, "test", 10, WithUpdateInterval(time.Second*1))
|
|
|
|
for i := 0; i < 10; i++ {
|
|
bb := pro.IsLatest(ctx)
|
|
fmt.Println("cc:", bb)
|
|
time.Sleep(time.Second)
|
|
}
|
|
|
|
cancel()
|
|
}()
|
|
|
|
pro, _ := InitPriority(ctx, re, "test", 0, WithUpdateInterval(time.Second*1))
|
|
|
|
for i := 0; i < 25; i++ {
|
|
bb := pro.IsLatest(ctx)
|
|
fmt.Println("bb:", bb)
|
|
time.Sleep(time.Second)
|
|
}
|
|
|
|
}
|
|
|
|
// MockRedisClient 模拟Redis客户端
|
|
type MockRedisClient struct {
|
|
redis.UniversalClient
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *MockRedisClient) Eval(ctx context.Context, script string, keys []string, args ...interface{}) *redis.Cmd {
|
|
arguments := m.Called(ctx, script, keys, args)
|
|
return arguments.Get(0).(*redis.Cmd)
|
|
}
|
|
|
|
func (m *MockRedisClient) Get(ctx context.Context, key string) *redis.StringCmd {
|
|
arguments := m.Called(ctx, key)
|
|
return arguments.Get(0).(*redis.StringCmd)
|
|
}
|
|
|
|
func (m *MockRedisClient) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd {
|
|
arguments := m.Called(ctx, key, value, expiration)
|
|
return arguments.Get(0).(*redis.StatusCmd)
|
|
}
|
|
|
|
func TestInitPriority(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
// 测试正常初始化
|
|
priority, _ := InitPriority(ctx, getRedis(), "test", 100)
|
|
assert.NotNil(t, priority)
|
|
assert.Equal(t, int64(100), priority.priority)
|
|
}
|
|
|
|
func TestSetPriorityScenarios(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
currentRedis interface{}
|
|
newPriority int64
|
|
expectedStatus string
|
|
expectedValue int64
|
|
}{
|
|
{
|
|
name: "首次设置优先级",
|
|
currentRedis: nil, // Redis中不存在key
|
|
newPriority: 100,
|
|
expectedStatus: "SET",
|
|
expectedValue: 100,
|
|
},
|
|
{
|
|
name: "更新更高优先级",
|
|
currentRedis: "50", // Redis中存在较低优先级
|
|
newPriority: 100,
|
|
expectedStatus: "UPDATED",
|
|
expectedValue: 100,
|
|
},
|
|
{
|
|
name: "保持相同优先级",
|
|
currentRedis: "100", // Redis中存在相同优先级
|
|
newPriority: 100,
|
|
expectedStatus: "EXTENDED",
|
|
expectedValue: 100,
|
|
},
|
|
{
|
|
name: "忽略较低优先级",
|
|
currentRedis: "150", // Redis中存在更高优先级
|
|
newPriority: 100,
|
|
expectedStatus: "IGNORED",
|
|
expectedValue: 150,
|
|
},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
redisConn := getRedis()
|
|
// 删除Key
|
|
redisConn.Del(ctx, "timer:priority_test22")
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
priority, _ := InitPriority(ctx, redisConn, "test22", tc.newPriority)
|
|
defer priority.Close()
|
|
|
|
time.Sleep(time.Second * 1)
|
|
|
|
_, err := priority.setPriority()
|
|
|
|
assert.NoError(t, err)
|
|
// assert.Equal(t, tc.expectedStatus, sta)
|
|
})
|
|
}
|
|
}
|
|
|
|
// 并发安全测试
|
|
func TestConcurrentAccess(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
priority, _ := InitPriority(ctx, getRedis(), "testacc", 100)
|
|
|
|
time.Sleep(time.Second * 1)
|
|
|
|
// 并发读取IsLatest
|
|
var wg sync.WaitGroup
|
|
results := make(chan bool, 100)
|
|
|
|
for i := 0; i < 100; i++ {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
results <- priority.IsLatest(ctx)
|
|
}()
|
|
}
|
|
|
|
wg.Wait()
|
|
close(results)
|
|
|
|
// 所有结果应该相同
|
|
firstResult := <-results
|
|
for result := range results {
|
|
t.Log(result)
|
|
assert.Equal(t, firstResult, result)
|
|
}
|
|
}
|
|
|
|
// 错误处理测试
|
|
func TestErrorScenarios(t *testing.T) {
|
|
t.Run("Redis连接失败", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
priority, _ := InitPriority(ctx, getRedis(), "test", 100)
|
|
_, err := priority.setPriority()
|
|
|
|
assert.Error(t, err)
|
|
})
|
|
|
|
t.Run("Redis返回值解析错误", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
priority := &Priority{
|
|
redis: getRedis(),
|
|
redisKey: "timer:priority_test",
|
|
priority: 100,
|
|
ctx: ctx,
|
|
}
|
|
|
|
_, err := priority.getCurrentPriority()
|
|
assert.Error(t, err)
|
|
})
|
|
}
|