123 lines
3.4 KiB
C#
123 lines
3.4 KiB
C#
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);
|
||
}
|
||
} |