Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using adas_core.Application.Services.Caching;
|
||||
|
||||
namespace adas_core.Test.Services;
|
||||
|
||||
[TestFixture]
|
||||
public class InMemoryLockProviderTest
|
||||
{
|
||||
private InMemoryLockProvider _provider = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_provider = new InMemoryLockProvider();
|
||||
}
|
||||
|
||||
private ConcurrentDictionary<string, SemaphoreSlim> GetLocks()
|
||||
{
|
||||
var field = typeof(InMemoryLockProvider)
|
||||
.GetField("_locks", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
return (ConcurrentDictionary<string, SemaphoreSlim>)field!.GetValue(_provider)!;
|
||||
}
|
||||
|
||||
#region TC-50
|
||||
[Test]
|
||||
public async Task AcquireAsync_ReturnsTrue_AndCreatesEntryInLocksDictionary()
|
||||
{
|
||||
var result = await _provider.AcquireAsync("key", TimeSpan.FromSeconds(1));
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
|
||||
var locks = GetLocks();
|
||||
Assert.That(locks.ContainsKey("key"), Is.True);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TC-51
|
||||
[Test]
|
||||
public async Task AcquireAsync_ReturnsFalse_WhenSemaphoreOccupiedAndTimeoutExpires()
|
||||
{
|
||||
await _provider.AcquireAsync("key", TimeSpan.FromSeconds(5));
|
||||
|
||||
var result = await _provider.AcquireAsync("key", TimeSpan.FromMilliseconds(100));
|
||||
|
||||
Assert.That(result, Is.False);
|
||||
|
||||
await _provider.ReleaseAsync("key");
|
||||
|
||||
var locks = GetLocks();
|
||||
Assert.That(locks["key"].CurrentCount, Is.EqualTo(1));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TC-52
|
||||
[Test]
|
||||
public async Task ReleaseAsync_MakesSemaphoreAvailableForNextAcquire()
|
||||
{
|
||||
await _provider.AcquireAsync("key", TimeSpan.FromSeconds(1));
|
||||
await _provider.ReleaseAsync("key");
|
||||
|
||||
var result = await _provider.AcquireAsync("key", TimeSpan.FromSeconds(1));
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
|
||||
var locks = GetLocks();
|
||||
Assert.That(locks["key"].CurrentCount, Is.EqualTo(0));
|
||||
|
||||
await _provider.ReleaseAsync("key");
|
||||
|
||||
Assert.That(locks["key"].CurrentCount, Is.EqualTo(1));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TC-53
|
||||
[Test]
|
||||
public async Task ReleaseAsync_DoesNotThrow_WhenCalledWithoutPriorAcquire()
|
||||
{
|
||||
await _provider.ReleaseAsync("nonexistent-key");
|
||||
|
||||
await _provider.AcquireAsync("key", TimeSpan.FromSeconds(1));
|
||||
await _provider.ReleaseAsync("key");
|
||||
await _provider.ReleaseAsync("key");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TC-54
|
||||
[Test]
|
||||
public async Task AcquireAsync_IsThreadSafe_OnlyOneHolderAtATime_SingleSemaphorePerKey()
|
||||
{
|
||||
const string key = "same-key";
|
||||
const int threadCount = 10;
|
||||
var acquiredCount = 0;
|
||||
var currentHolders = 0;
|
||||
|
||||
var tasks = Enumerable.Range(0, threadCount).Select(_ => Task.Run(async () =>
|
||||
{
|
||||
var acquired = await _provider.AcquireAsync(key, TimeSpan.FromSeconds(10));
|
||||
|
||||
Assert.That(acquired, Is.True);
|
||||
|
||||
var current = Interlocked.Increment(ref currentHolders);
|
||||
Assert.That(current, Is.EqualTo(1));
|
||||
|
||||
Interlocked.Increment(ref acquiredCount);
|
||||
await Task.Delay(5);
|
||||
|
||||
Interlocked.Decrement(ref currentHolders);
|
||||
await _provider.ReleaseAsync(key);
|
||||
})).ToArray();
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
Assert.That(acquiredCount, Is.EqualTo(threadCount));
|
||||
|
||||
var locks = GetLocks();
|
||||
Assert.That(locks.ContainsKey(key), Is.True);
|
||||
Assert.That(locks.Keys.Count(k => k == key), Is.EqualTo(1));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user