-
Notifications
You must be signed in to change notification settings - Fork 247
Expand file tree
/
Copy pathDistributedReaderWriterLockCoreTestCases.cs
More file actions
97 lines (76 loc) · 4.69 KB
/
DistributedReaderWriterLockCoreTestCases.cs
File metadata and controls
97 lines (76 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using NUnit.Framework;
namespace Medallion.Threading.Tests;
public abstract class DistributedReaderWriterLockCoreTestCases<TLockProvider, TStrategy>
where TLockProvider : TestingReaderWriterLockProvider<TStrategy>, new()
where TStrategy : TestingSynchronizationStrategy, new()
{
private TLockProvider _lockProvider = default!;
[SetUp]
public async Task SetUp()
{
this._lockProvider = new TLockProvider();
await this._lockProvider.SetupAsync();
}
[TearDown]
public async Task TearDown() => await this._lockProvider.DisposeAsync();
[Test]
public async Task TestMultipleReadersSingleWriter()
{
IDistributedReaderWriterLock Lock() =>
this._lockProvider.CreateReaderWriterLock(nameof(TestMultipleReadersSingleWriter));
using var readHandle1 = await Lock().TryAcquireReadLockAsync();
Assert.That(readHandle1, Is.Not.Null, this.GetType().ToString());
using var readHandle2 = Lock().TryAcquireReadLock();
Assert.That(readHandle2, Is.Not.Null, this.GetType().ToString());
using var writeHandle1 = Lock().TryAcquireWriteLock();
Assert.That(writeHandle1, Is.Null);
var writeHandleTask = Task.Run(() => Lock().AcquireWriteLockAsync().AsTask());
Assert.That(writeHandleTask.Wait(TimeSpan.FromSeconds(.05)), Is.False);
readHandle1!.Dispose();
Assert.That(writeHandleTask.Wait(TimeSpan.FromSeconds(.05)), Is.False);
readHandle2!.Dispose();
Assert.That(writeHandleTask.Wait(TimeSpan.FromSeconds(10)), Is.True);
using var writeHandle2 = writeHandleTask.Result;
using var writeHandle3 = Lock().TryAcquireWriteLock();
Assert.That(writeHandle3, Is.Null);
writeHandle2.Dispose();
using var writeHandle4 = Lock().TryAcquireWriteLock();
Assert.That(writeHandle4, Is.Not.Null);
}
[Test]
public async Task TestWriterTrumpsReader()
{
IDistributedReaderWriterLock Lock() =>
this._lockProvider.CreateReaderWriterLock(nameof(this.TestWriterTrumpsReader));
await using var readerHandle = await Lock().AcquireReadLockAsync();
var writerHandleTask = Task.Run(() => Lock().AcquireWriteLockAsync().AsTask());
Assert.That(await writerHandleTask.TryWaitAsync(TimeSpan.FromSeconds(0.2)), Is.False);
// trying to take a read lock here fails because there is a writer waiting
await using var readerHandle2 = await Lock().TryAcquireReadLockAsync();
Assert.That(readerHandle2, Is.Null);
await readerHandle.DisposeAsync();
Assert.That(await writerHandleTask.TryWaitAsync(TimeSpan.FromSeconds(5)), Is.True);
await writerHandleTask.Result.DisposeAsync();
}
[Test]
public void TestReaderWriterLockBadArguments()
{
var @lock = this._lockProvider.CreateReaderWriterLock(nameof(TestReaderWriterLockBadArguments));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireReadLock(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireReadLockAsync(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireReadLock(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireReadLockAsync(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireReadLock(TimeSpan.FromSeconds(int.MaxValue)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireReadLockAsync(TimeSpan.FromSeconds(int.MaxValue)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireReadLock(TimeSpan.FromSeconds(int.MaxValue)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireReadLockAsync(TimeSpan.FromSeconds(int.MaxValue)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireWriteLock(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireWriteLockAsync(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireWriteLock(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireWriteLockAsync(TimeSpan.FromSeconds(-2)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireWriteLock(TimeSpan.FromSeconds(int.MaxValue)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.AcquireWriteLockAsync(TimeSpan.FromSeconds(int.MaxValue)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireWriteLock(TimeSpan.FromSeconds(int.MaxValue)));
Assert.Catch<ArgumentOutOfRangeException>(() => @lock.TryAcquireWriteLockAsync(TimeSpan.FromSeconds(int.MaxValue)));
}
}