From ae064236c76bce1ba70ee5495864304d58f9aa23 Mon Sep 17 00:00:00 2001 From: douxu Date: Tue, 1 Apr 2025 16:20:55 +0800 Subject: [PATCH] add redis lock refresh test of rwlocker --- distributedlock/rwlock_test.go | 115 +++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 12 deletions(-) diff --git a/distributedlock/rwlock_test.go b/distributedlock/rwlock_test.go index d71241b..ffc9bee 100644 --- a/distributedlock/rwlock_test.go +++ b/distributedlock/rwlock_test.go @@ -159,7 +159,6 @@ func TestRWLockRefreshRLock(t *testing.T) { return } -// TODO 设计两个客户端分别加读锁,测试是否可以加锁成功 func TestRWLock2ClientRLock(t *testing.T) { ctx := context.TODO() rdb := redis.NewClient(&redis.Options{ @@ -208,25 +207,24 @@ func TestRWLock2ClientRLock(t *testing.T) { err = rdb.HLen(ctx, rwLocker1.key).Err() assert.Equal(t, nil, err) hLen := rdb.HLen(ctx, rwLocker1.key).Val() - assert.Equal(t, 3, hLen) + assert.Equal(t, int64(3), hLen) // locker1解读锁 err = rwLocker1.UnRLock(ctx) assert.Equal(t, nil, err) - // locker1解读锁 + // locker2解读锁 err = rwLocker2.UnRLock(ctx) assert.Equal(t, nil, err) err = rdb.Exists(ctx, rwLocker1.key).Err() - assert.Equal(t, redis.Nil, err) + assert.Equal(t, nil, err) existNum := rdb.Exists(ctx, rwLocker1.key).Val() - assert.Equal(t, 0, existNum) + assert.Equal(t, int64(0), existNum) t.Log("rwLock 2 client lock test success") return } -// TODO 设计两个客户端分别加时间不同的读锁,测试ttl时间在有一个key删除后是否可以变换成功 func TestRWLock2CWith2DifTimeRLock(t *testing.T) { ctx := context.TODO() rdb := redis.NewClient(&redis.Options{ @@ -275,20 +273,113 @@ func TestRWLock2CWith2DifTimeRLock(t *testing.T) { err = rdb.HLen(ctx, rwLocker1.key).Err() assert.Equal(t, nil, err) hLen := rdb.HLen(ctx, rwLocker1.key).Val() - assert.Equal(t, 3, hLen) + assert.Equal(t, int64(3), hLen) + + script := `return redis.call('httl', KEYS[1], 'fields', '1', ARGV[1]);` + result, err := rdb.Eval(ctx, script, []string{rwLocker1.key}, tokenKey1).Result() + assert.Equal(t, nil, err) + ttls, ok := result.([]interface{}) + assert.Equal(t, true, ok) + ttl, ok := ttls[0].(int64) + assert.Equal(t, true, ok) + compareValue := int64(110) + assert.Greater(t, ttl, compareValue) // locker1解读锁 err = rwLocker1.UnRLock(ctx) assert.Equal(t, nil, err) - // locker1解读锁 + hashTTL := rdb.TTL(ctx, rwLocker1.key).Val().Seconds() + assert.Greater(t, hashTTL, float64(20)) + + // locker2解读锁 err = rwLocker2.UnRLock(ctx) assert.Equal(t, nil, err) err = rdb.Exists(ctx, rwLocker1.key).Err() - assert.Equal(t, redis.Nil, err) + assert.Equal(t, nil, err) existNum := rdb.Exists(ctx, rwLocker1.key).Val() - assert.Equal(t, 0, existNum) + assert.Equal(t, int64(0), existNum) + t.Log("rwLock 2 client lock test success") + return +} + +// TODO 设计两个客户端分别加时间不同的读锁,测试ttl时间在有一个key删除后是否可以变换成功 +func TestRWLock2CWithTimeTransformRLock(t *testing.T) { + ctx := context.TODO() + rdb := redis.NewClient(&redis.Options{ + Network: "tcp", + Addr: "192.168.2.104:6379", + Password: "cnstar", + PoolSize: 50, + DialTimeout: 10 * time.Second, + }) + + rwLocker1 := GetRWLocker(rdb, &RedissionLockConfig{ + LockLeaseTime: 120, + NeedRefresh: true, + Key: "component", + Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a", + }) + rwLocker1.logger = log + + rwLocker2 := GetRWLocker(rdb, &RedissionLockConfig{ + LockLeaseTime: 30, + NeedRefresh: true, + Key: "component", + Token: "fd348a84-e07c-4a61-8c19-f753e6bc5577", + }) + rwLocker2.logger = log + + duration := 10 * time.Second + // locker1加读锁 + err := rwLocker1.RLock(ctx, duration) + assert.Equal(t, nil, err) + + tokenKey1 := strings.Join([]string{rwLocker1.rwTokenTimeoutPrefix, rwLocker1.token}, ":") + num, err := rdb.HGet(ctx, rwLocker1.key, tokenKey1).Int() + assert.Equal(t, nil, err) + assert.Equal(t, 1, num) + + // locker2加读锁 + err = rwLocker2.RLock(ctx, duration) + assert.Equal(t, nil, err) + + tokenKey2 := strings.Join([]string{rwLocker2.rwTokenTimeoutPrefix, rwLocker2.token}, ":") + num, err = rdb.HGet(ctx, rwLocker2.key, tokenKey2).Int() + assert.Equal(t, nil, err) + assert.Equal(t, 1, num) + + err = rdb.HLen(ctx, rwLocker1.key).Err() + assert.Equal(t, nil, err) + hLen := rdb.HLen(ctx, rwLocker1.key).Val() + assert.Equal(t, int64(3), hLen) + + script := `return redis.call('httl', KEYS[1], 'fields', '1', ARGV[1]);` + result, err := rdb.Eval(ctx, script, []string{rwLocker1.key}, tokenKey1).Result() + assert.Equal(t, nil, err) + ttls, ok := result.([]interface{}) + assert.Equal(t, true, ok) + ttl, ok := ttls[0].(int64) + assert.Equal(t, true, ok) + compareValue := int64(110) + assert.Greater(t, ttl, compareValue) + + // locker1解读锁 + err = rwLocker1.UnRLock(ctx) + assert.Equal(t, nil, err) + + hashTTL := rdb.TTL(ctx, rwLocker1.key).Val().Seconds() + assert.Greater(t, hashTTL, float64(20)) + + // locker2解读锁 + err = rwLocker2.UnRLock(ctx) + assert.Equal(t, nil, err) + + err = rdb.Exists(ctx, rwLocker1.key).Err() + assert.Equal(t, nil, err) + existNum := rdb.Exists(ctx, rwLocker1.key).Val() + assert.Equal(t, int64(0), existNum) t.Log("rwLock 2 client lock test success") return } @@ -386,7 +477,7 @@ func TestRWLockReentrantWLock(t *testing.T) { return } -// TODO 设计两个客户端分别加读锁与写锁 +// TODO 设计两个客户端,C1先加读锁与C2后加写锁 func TestRWLock2CWithRLockAndWLock(t *testing.T) { ctx := context.TODO() rdb := redis.NewClient(&redis.Options{ @@ -437,7 +528,7 @@ func TestRWLock2CWithRLockAndWLock(t *testing.T) { return } -// TODO 设计两个客户端分别加读锁与写锁 +// TODO 设计两个客户端,C1先加写锁与C2后加读锁 func TestRWLock2CWithWLockAndRLock(t *testing.T) { ctx := context.TODO() rdb := redis.NewClient(&redis.Options{