Redis/XUnitTest/RedisLockTest.cs

123 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Diagnostics;
using System.Threading;
using NewLife.Caching;
using NewLife.Log;
using NewLife.UnitTest;
using Xunit;
namespace XUnitTest;
//[Collection("Basic")]
[TestCaseOrderer("NewLife.UnitTest.PriorityOrderer", "NewLife.UnitTest")]
public class RedisLockTest
{
private Redis _redis;
public RedisLockTest()
{
var config = BasicTest.GetConfig();
_redis = new Redis();
_redis.Init(config);
_redis.Log = XTrace.Log;
#if DEBUG
_redis.ClientLog = XTrace.Log;
#endif
}
[TestOrder(50)]
[Fact(DisplayName = "正常锁")]
public void TestLock1()
{
var ic = _redis;
var ck = ic.AcquireLock("lock:TestLock1", 3000);
var k2 = ck as CacheLock;
Assert.NotNull(k2);
Assert.Equal("lock:TestLock1", k2.Key);
// 实际上存在这个key
Assert.True(ic.ContainsKey(k2.Key));
// 取有效期
var exp = ic.GetExpire(k2.Key);
Assert.True(exp.TotalMilliseconds <= 3000);
// 释放锁
ck.Dispose();
// 这个key已经不存在
Assert.False(ic.ContainsKey(k2.Key));
}
[TestOrder(52)]
[Fact(DisplayName = "抢锁失败")]
public void TestLock2()
{
var ic = _redis;
var ck1 = ic.AcquireLock("lock:TestLock2", 2000);
// 故意不用using验证GC是否能回收
//using var ck1 = ic.AcquireLock("TestLock2", 3000);
var sw = Stopwatch.StartNew();
// 抢相同锁不可能成功。超时时间必须小于3000否则前面的锁过期后这里还是可以抢到的
Assert.Throws<InvalidOperationException>(() => ic.AcquireLock("lock:TestLock2", 1000));
// 耗时必须超过有效期
sw.Stop();
XTrace.WriteLine("TestLock2 ElapsedMilliseconds={0}ms", sw.ElapsedMilliseconds);
Assert.True(sw.ElapsedMilliseconds >= 1000);
Thread.Sleep(2000 - 1000 + 100);
// 那个锁其实已经不在了,缓存应该把它干掉
Assert.False(ic.ContainsKey("lock:TestLock2"));
}
[TestOrder(54)]
[Fact(DisplayName = "抢锁失败2")]
public void TestLock3()
{
var ic = _redis;
var ck1 = ic.AcquireLock("lock:TestLock3", 2000);
// 故意不用using验证GC是否能回收
//using var ck1 = ic.AcquireLock("TestLock3", 3000);
var sw = Stopwatch.StartNew();
// 抢相同锁不可能成功。超时时间必须小于3000否则前面的锁过期后这里还是可以抢到的
var ck2 = ic.AcquireLock("lock:TestLock3", 1000, 1000, false);
Assert.Null(ck2);
// 耗时必须超过有效期
sw.Stop();
XTrace.WriteLine("TestLock3 ElapsedMilliseconds={0}ms", sw.ElapsedMilliseconds);
Assert.True(sw.ElapsedMilliseconds >= 1000);
Thread.Sleep(2000 - 1000 + 100);
// 那个锁其实已经不在了,缓存应该把它干掉
Assert.False(ic.ContainsKey("lock:TestLock3"));
}
[TestOrder(56)]
[Fact(DisplayName = "抢死锁")]
public void TestLock4()
{
var ic = _redis;
using var ck = ic.AcquireLock("TestLock4", 1000);
// 已经过了一点时间
Thread.Sleep(500);
// 循环多次后,可以抢到
using var ck2 = ic.AcquireLock("TestLock4", 1000);
Assert.NotNull(ck2);
}
}