Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop

This commit is contained in:
jrojas
2026-06-26 09:52:35 +02:00
commit 319fd3dfb0
746 changed files with 106610 additions and 0 deletions
@@ -0,0 +1,175 @@
using System.Diagnostics;
using adas_core.Application.Services.Caching;
using Moq;
using StackExchange.Redis;
namespace adas_core.Test.Services;
[TestFixture]
public class RedisLockProviderTest
{
private Mock<IDatabase> _mockDb = null!;
private RedisLockProvider _provider = null!;
[SetUp]
public void SetUp()
{
_mockDb = new Mock<IDatabase>();
_provider = new RedisLockProvider(() => _mockDb.Object);
}
#region TC-45
[Test]
public async Task AcquireAsync_ReturnsTrue_AndStoresToken_WhenRedisAcceptsNxSet()
{
_mockDb
.Setup(db => db.StringSetAsync(
It.IsAny<RedisKey>(),
It.IsAny<RedisValue>(),
It.IsAny<TimeSpan?>(),
It.IsAny<When>()))
.ReturnsAsync(true);
_mockDb
.Setup(db => db.ScriptEvaluateAsync(
It.IsAny<string>(),
It.IsAny<RedisKey[]?>(),
It.IsAny<RedisValue[]?>(),
It.IsAny<CommandFlags>()))
.Returns(Task.FromResult<RedisResult>(null!));
var result = await _provider.AcquireAsync("key", TimeSpan.FromSeconds(5));
Assert.That(result, Is.True);
_mockDb.Verify(db => db.StringSetAsync(
It.Is<RedisKey>(k => k == (RedisKey)"lock:key"),
It.IsAny<RedisValue>(),
(TimeSpan?)TimeSpan.FromSeconds(5),
When.NotExists), Times.Once());
await _provider.ReleaseAsync("key");
_mockDb.Verify(db => db.ScriptEvaluateAsync(
It.IsAny<string>(),
It.IsAny<RedisKey[]?>(),
It.IsAny<RedisValue[]?>(),
It.IsAny<CommandFlags>()), Times.Once());
}
#endregion
#region TC-46
[Test]
public async Task AcquireAsync_RetriesWithDelays_UntilNxSucceeds()
{
_mockDb
.SetupSequence(db => db.StringSetAsync(
It.IsAny<RedisKey>(),
It.IsAny<RedisValue>(),
It.IsAny<TimeSpan?>(),
It.IsAny<When>()))
.ReturnsAsync(false)
.ReturnsAsync(false)
.ReturnsAsync(false)
.ReturnsAsync(true);
var sw = Stopwatch.StartNew();
var result = await _provider.AcquireAsync("key", TimeSpan.FromSeconds(1));
sw.Stop();
Assert.That(result, Is.True);
_mockDb.Verify(db => db.StringSetAsync(
It.IsAny<RedisKey>(),
It.IsAny<RedisValue>(),
It.IsAny<TimeSpan?>(),
It.IsAny<When>()), Times.Exactly(4));
Assert.That(sw.ElapsedMilliseconds, Is.GreaterThan(100));
}
#endregion
#region TC-47
[Test]
public async Task AcquireAsync_ReturnsFalse_AfterTimeoutWithMultipleRetries()
{
_mockDb
.Setup(db => db.StringSetAsync(
It.IsAny<RedisKey>(),
It.IsAny<RedisValue>(),
It.IsAny<TimeSpan?>(),
It.IsAny<When>()))
.ReturnsAsync(false);
var sw = Stopwatch.StartNew();
var result = await _provider.AcquireAsync("key", TimeSpan.FromMilliseconds(200));
sw.Stop();
Assert.That(result, Is.False);
Assert.That(sw.ElapsedMilliseconds, Is.GreaterThan(100));
_mockDb.Verify(db => db.StringSetAsync(
It.IsAny<RedisKey>(),
It.IsAny<RedisValue>(),
It.IsAny<TimeSpan?>(),
It.IsAny<When>()), Times.AtLeast(2));
}
#endregion
#region TC-48
[Test]
public async Task ReleaseAsync_CallsScriptEvaluateWithCorrectKeyAndToken()
{
RedisValue capturedToken = default;
_mockDb
.Setup(db => db.StringSetAsync(
It.IsAny<RedisKey>(),
It.IsAny<RedisValue>(),
It.IsAny<TimeSpan?>(),
It.IsAny<When>()))
.Callback<RedisKey, RedisValue, TimeSpan?, When>(
(_, v, _, _) => capturedToken = v)
.ReturnsAsync(true);
_mockDb
.Setup(db => db.ScriptEvaluateAsync(
It.IsAny<string>(),
It.IsAny<RedisKey[]?>(),
It.IsAny<RedisValue[]?>(),
It.IsAny<CommandFlags>()))
.Returns(Task.FromResult<RedisResult>(null!));
await _provider.AcquireAsync("key", TimeSpan.FromSeconds(5));
await _provider.ReleaseAsync("key");
_mockDb.Verify(db => db.ScriptEvaluateAsync(
It.IsAny<string>(),
It.Is<RedisKey[]?>(keys => keys != null && keys[0] == (RedisKey)"lock:key"),
It.Is<RedisValue[]?>(vals => vals != null && vals[0] == capturedToken),
It.IsAny<CommandFlags>()), Times.Once());
}
#endregion
#region TC-49
[Test]
public async Task ReleaseAsync_IsIdempotent_WhenCalledWithoutPriorAcquire()
{
_mockDb
.Setup(db => db.ScriptEvaluateAsync(
It.IsAny<string>(),
It.IsAny<RedisKey[]?>(),
It.IsAny<RedisValue[]?>(),
It.IsAny<CommandFlags>()))
.Returns(Task.FromResult<RedisResult>(null!));
await _provider.ReleaseAsync("key");
_mockDb.Verify(db => db.ScriptEvaluateAsync(
It.IsAny<string>(),
It.IsAny<RedisKey[]?>(),
It.IsAny<RedisValue[]?>(),
It.IsAny<CommandFlags>()), Times.Never());
}
#endregion
}