Remove spaghetti
MODIFY
WalletWasabi.Tests/UnitTests/AsyncMutexTests.cs
WalletWasabi.Tests/UnitTests/AsyncMutexTests.cs
@@ -11,43 +11,9 @@ namespace WalletWasabi.Tests.UnitTests
{
public class AsyncMutexTests
{
- [Fact]
- public async Task AsyncMutexTestsAsync()
- {
- var mutexName1 = $"mutex1-{DateTime.Now.Ticks.ToString()}"; // Randomize the name to avoid system wide collisions.
-
- AsyncMutex asyncMutex = new AsyncMutex(mutexName1);
-
- // Cannot be IDisposable because the pattern is like Nito's AsyncLock.
- Assert.False(asyncMutex is IDisposable);
-
- // Use the mutex two times after each other.
- using (await asyncMutex.LockAsync())
+ private static async Task TestMutexConcurrencyAsync(AsyncMutex asyncMutex, AsyncMutex asyncMutex2)
{
- await Task.Delay(1);
- }
-
- using (await asyncMutex.LockAsync())
- {
- await Task.Delay(1);
- }
-
- // Release the Mutex from another thread.
-
- var disposable = await asyncMutex.LockAsync();
-
- var myThread = new Thread(new ThreadStart(() =>
- {
- disposable.Dispose();
- }));
- myThread.Start();
- myThread.Join();
-
- using (await asyncMutex.LockAsync())
- {
- await Task.Delay(1);
- }
-
+ // Concurrency test with the same AsyncMutex object.
using (var phase1 = new AutoResetEvent(false))
using (var phase2 = new AutoResetEvent(false))
using (var phase3 = new AutoResetEvent(false))
@@ -75,7 +41,7 @@ namespace WalletWasabi.Tests.UnitTests
{
await Assert.ThrowsAsync<IOException>(async () =>
{
- using (await asyncMutex.LockAsync(cts.Token))
+ using (await asyncMutex2.LockAsync(cts.Token))
{
throw new InvalidOperationException("Mutex should not be acquired here.");
};
@@ -89,13 +55,51 @@ namespace WalletWasabi.Tests.UnitTests
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(2)))
{
// We should get this immediately.
- using (await asyncMutex.LockAsync())
+ using (await asyncMutex2.LockAsync())
{
};
}
Assert.True(myTask.IsCompletedSuccessfully);
}
+ }
+
+ [Fact]
+ public async Task AsyncMutexTestsAsync()
+ {
+ var mutexName1 = $"mutex1-{DateTime.Now.Ticks.ToString()}"; // Randomize the name to avoid system wide collisions.
+
+ AsyncMutex asyncMutex = new AsyncMutex(mutexName1);
+
+ // Cannot be IDisposable because the pattern is like Nito's AsyncLock.
+ Assert.False(asyncMutex is IDisposable);
+
+ // Use the mutex two times after each other.
+ using (await asyncMutex.LockAsync())
+ {
+ await Task.Delay(1);
+ }
+
+ using (await asyncMutex.LockAsync())
+ {
+ await Task.Delay(1);
+ }
+
+ // Release the Mutex from another thread.
+
+ var disposable = await asyncMutex.LockAsync();
+
+ var myThread = new Thread(new ThreadStart(() =>
+ {
+ disposable.Dispose();
+ }));
+ myThread.Start();
+ myThread.Join();
+
+ using (await asyncMutex.LockAsync())
+ {
+ await Task.Delay(1);
+ }
// Standard Mutex test.
int cnt = 0;
@@ -164,38 +168,12 @@ namespace WalletWasabi.Tests.UnitTests
}
}
- // Different AsyncMutex object but same name.
- AsyncMutex asyncMutex2 = new AsyncMutex(mutexName1);
- using (ManualResetEvent locked = new ManualResetEvent(false))
- {
- locked.Reset();
- // Acquire the first mutex with a background thread and hold it for a while.
- var myTask = Task.Run(async () =>
- {
- using (await asyncMutex.LockAsync())
- {
- locked.Set();
- await Task.Delay(3000);
- }
- });
-
- // Make sure the task started.
- Assert.True(locked.WaitOne(TimeSpan.FromSeconds(5)));
+ // Concurrency test with the same AsyncMutex object.
+ await TestMutexConcurrencyAsync(asyncMutex, asyncMutex);
- var timeOfstart = DateTime.Now;
- DateTime timeOfAcquired = default;
- // Now try to acquire another AsyncMutex object but with the same name!
- using (await asyncMutex2.LockAsync())
- {
- timeOfAcquired = DateTime.Now;
- }
-
- await myTask;
- Assert.True(myTask.IsCompletedSuccessfully);
-
- var elapsed = timeOfAcquired - timeOfstart;
- Assert.InRange(elapsed, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4));
- }
+ // Concurrency test with different AsyncMutex object but same name.
+ AsyncMutex asyncMutex2 = new AsyncMutex(mutexName1);
+ await TestMutexConcurrencyAsync(asyncMutex, asyncMutex2);
}
}
}

Remove spaghetti