Skip to content

Commit e86f251

Browse files
committed
Add more unit-tests
1 parent 1747082 commit e86f251

File tree

4 files changed

+223
-21
lines changed

4 files changed

+223
-21
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
using System.Threading.Tasks;
6+
using SixLabors.ImageSharp.Web.Synchronization;
7+
using Xunit;
8+
9+
namespace SixLabors.ImageSharp.Web.Tests.Synchronization
10+
{
11+
public class AsyncKeyLockTests
12+
{
13+
[Fact]
14+
public async Task OneAtATime()
15+
{
16+
AsyncKeyLock<string> l = new();
17+
18+
Task<IDisposable> first = l.LockAsync("key");
19+
Assert.True(first.IsCompletedSuccessfully);
20+
21+
Task<IDisposable> second = l.LockAsync("key");
22+
Assert.False(second.IsCompleted);
23+
24+
// Release first hold on the lock
25+
first.Result.Dispose();
26+
27+
// Await the second task to make sure we get the lock.
28+
await second;
29+
30+
l.Dispose();
31+
}
32+
33+
[Fact]
34+
public async Task OneAtATime_ByKey()
35+
{
36+
AsyncKeyLock<string> l = new();
37+
38+
Task<IDisposable> firstFoo = l.LockAsync("Foo");
39+
Assert.True(firstFoo.IsCompletedSuccessfully);
40+
41+
Task<IDisposable> secondFoo = l.LockAsync("Foo");
42+
Assert.False(secondFoo.IsCompleted);
43+
44+
// Now take a different lock ("bar") and confirm it doesn't conflict with the previous lock
45+
Task<IDisposable> firstBar = l.LockAsync("Bar");
46+
Assert.True(firstBar.IsCompletedSuccessfully);
47+
48+
// Release the "bar" lock, and confirm it doesn't change anything about the original "foo" lock.
49+
// The second caller that was waiting on the "foo" lock should still be waiting.
50+
firstBar.Result.Dispose();
51+
Assert.False(secondFoo.IsCompleted);
52+
53+
// Release the "foo" lock
54+
firstFoo.Result.Dispose();
55+
56+
// Await the second task to make sure it gets the lock.
57+
await secondFoo;
58+
59+
l.Dispose();
60+
}
61+
}
62+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
using System.Threading.Tasks;
6+
using SixLabors.ImageSharp.Web.Synchronization;
7+
using Xunit;
8+
9+
namespace SixLabors.ImageSharp.Web.Tests.Synchronization
10+
{
11+
public class AsyncKeyReaderWriterLockTests
12+
{
13+
[Fact]
14+
public void OneWriterAtATime()
15+
{
16+
AsyncKeyReaderWriterLock<string> l = new();
17+
18+
Task<IDisposable> first = l.WriterLockAsync("key");
19+
Assert.True(first.IsCompletedSuccessfully);
20+
21+
Task<IDisposable> second = l.WriterLockAsync("key");
22+
Assert.False(second.IsCompleted);
23+
24+
first.Result.Dispose();
25+
Assert.True(second.IsCompletedSuccessfully);
26+
}
27+
28+
[Fact]
29+
public async Task OneWriterAtATime_ByKey()
30+
{
31+
AsyncKeyReaderWriterLock<string> l = new();
32+
33+
Task<IDisposable> firstFoo = l.WriterLockAsync("Foo");
34+
Assert.True(firstFoo.IsCompletedSuccessfully);
35+
36+
Task<IDisposable> secondFoo = l.WriterLockAsync("Foo");
37+
Assert.False(secondFoo.IsCompleted);
38+
39+
// Now take a different lock ("bar") and confirm it doesn't conflict with the previous lock
40+
Task<IDisposable> firstBar = l.WriterLockAsync("Bar");
41+
Assert.True(firstBar.IsCompletedSuccessfully);
42+
43+
// Release the "bar" lock, and confirm it doesn't change anything about the original "foo" lock.
44+
// The second caller that was waiting on the "foo" lock should still be waiting.
45+
firstBar.Result.Dispose();
46+
Assert.False(secondFoo.IsCompleted);
47+
48+
// Release the "foo" lock
49+
firstFoo.Result.Dispose();
50+
51+
// Await the second task to make sure it gets the lock.
52+
await secondFoo;
53+
}
54+
55+
[Fact]
56+
public void WriterBlocksReaders()
57+
{
58+
AsyncKeyReaderWriterLock<string> l = new();
59+
60+
Task<IDisposable> first = l.WriterLockAsync("key");
61+
Assert.True(first.IsCompletedSuccessfully);
62+
63+
Task<IDisposable> second = l.ReaderLockAsync("key");
64+
Assert.False(second.IsCompleted);
65+
66+
first.Result.Dispose();
67+
Assert.True(second.IsCompletedSuccessfully);
68+
}
69+
70+
[Fact]
71+
public void WaitingWriterBlocksReaders()
72+
{
73+
AsyncKeyReaderWriterLock<string> l = new();
74+
75+
Task<IDisposable> first = l.ReaderLockAsync("key");
76+
Assert.True(first.IsCompletedSuccessfully);
77+
78+
Task<IDisposable> second = l.WriterLockAsync("key");
79+
Assert.False(second.IsCompleted);
80+
81+
Task<IDisposable> third = l.ReaderLockAsync("key");
82+
Assert.False(third.IsCompleted);
83+
84+
first.Result.Dispose();
85+
Assert.True(second.IsCompletedSuccessfully);
86+
Assert.False(third.IsCompleted);
87+
88+
second.Result.Dispose();
89+
Assert.True(third.IsCompletedSuccessfully);
90+
}
91+
92+
[Fact]
93+
public void MultipleReadersAtOnce()
94+
{
95+
AsyncKeyReaderWriterLock<string> l = new();
96+
97+
Task<IDisposable> first = l.ReaderLockAsync("key");
98+
Assert.True(first.IsCompletedSuccessfully);
99+
100+
Task<IDisposable> second = l.ReaderLockAsync("key");
101+
Assert.True(second.IsCompletedSuccessfully);
102+
103+
Task<IDisposable> third = l.ReaderLockAsync("key");
104+
Assert.True(third.IsCompletedSuccessfully);
105+
}
106+
107+
[Fact]
108+
public void AllWaitingReadersReleasedConcurrently()
109+
{
110+
AsyncKeyReaderWriterLock<string> l = new();
111+
112+
Task<IDisposable> writer = l.WriterLockAsync("key");
113+
Assert.True(writer.IsCompletedSuccessfully);
114+
115+
Task<IDisposable> reader1 = l.ReaderLockAsync("key");
116+
Assert.False(reader1.IsCompleted);
117+
118+
Task<IDisposable> reader2 = l.ReaderLockAsync("key");
119+
Assert.False(reader2.IsCompleted);
120+
121+
Task<IDisposable> reader3 = l.ReaderLockAsync("key");
122+
Assert.False(reader3.IsCompleted);
123+
124+
writer.Result.Dispose();
125+
Assert.True(reader1.IsCompletedSuccessfully);
126+
Assert.True(reader2.IsCompletedSuccessfully);
127+
Assert.True(reader3.IsCompletedSuccessfully);
128+
}
129+
}
130+
}

tests/ImageSharp.Web.Tests/Synchronization/AsyncLockTests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,24 @@ namespace SixLabors.ImageSharp.Web.Tests.Synchronization
1010
{
1111
public class AsyncLockTests
1212
{
13-
private readonly AsyncLock l = new();
14-
1513
[Fact]
1614
public async Task OneAtATime()
1715
{
18-
Task<IDisposable> first = this.l.LockAsync();
16+
AsyncLock l = new();
17+
18+
Task<IDisposable> first = l.LockAsync();
1919
Assert.True(first.IsCompletedSuccessfully);
2020

21-
Task<IDisposable> second = this.l.LockAsync();
21+
Task<IDisposable> second = l.LockAsync();
2222
Assert.False(second.IsCompleted);
2323

2424
// Release first hold on the lock and then await the second task to confirm it completes.
2525
first.Result.Dispose();
2626

27-
// Await the second task to make sure we get the lock. The timeout specified in the [Fact] above will prevent this from running forever.
27+
// Await the second task to make sure we get the lock.
2828
await second;
29+
30+
l.Dispose();
2931
}
3032
}
3133
}

tests/ImageSharp.Web.Tests/Synchronization/AsyncReaderWriterLockTests.cs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ namespace SixLabors.ImageSharp.Web.Tests.Synchronization
1010
{
1111
public class AsyncReaderWriterLockTests
1212
{
13-
private readonly AsyncReaderWriterLock l = new();
14-
1513
[Fact]
1614
public void OneWriterAtATime()
1715
{
18-
Task<IDisposable> first = this.l.WriterLockAsync();
16+
AsyncReaderWriterLock l = new();
17+
18+
Task<IDisposable> first = l.WriterLockAsync();
1919
Assert.True(first.IsCompletedSuccessfully);
2020

21-
Task<IDisposable> second = this.l.WriterLockAsync();
21+
Task<IDisposable> second = l.WriterLockAsync();
2222
Assert.False(second.IsCompleted);
2323

2424
first.Result.Dispose();
@@ -28,10 +28,12 @@ public void OneWriterAtATime()
2828
[Fact]
2929
public void WriterBlocksReaders()
3030
{
31-
Task<IDisposable> first = this.l.WriterLockAsync();
31+
AsyncReaderWriterLock l = new();
32+
33+
Task<IDisposable> first = l.WriterLockAsync();
3234
Assert.True(first.IsCompletedSuccessfully);
3335

34-
Task<IDisposable> second = this.l.ReaderLockAsync();
36+
Task<IDisposable> second = l.ReaderLockAsync();
3537
Assert.False(second.IsCompleted);
3638

3739
first.Result.Dispose();
@@ -41,13 +43,15 @@ public void WriterBlocksReaders()
4143
[Fact]
4244
public void WaitingWriterBlocksReaders()
4345
{
44-
Task<IDisposable> first = this.l.ReaderLockAsync();
46+
AsyncReaderWriterLock l = new();
47+
48+
Task<IDisposable> first = l.ReaderLockAsync();
4549
Assert.True(first.IsCompletedSuccessfully);
4650

47-
Task<IDisposable> second = this.l.WriterLockAsync();
51+
Task<IDisposable> second = l.WriterLockAsync();
4852
Assert.False(second.IsCompleted);
4953

50-
Task<IDisposable> third = this.l.ReaderLockAsync();
54+
Task<IDisposable> third = l.ReaderLockAsync();
5155
Assert.False(third.IsCompleted);
5256

5357
first.Result.Dispose();
@@ -61,29 +65,33 @@ public void WaitingWriterBlocksReaders()
6165
[Fact]
6266
public void MultipleReadersAtOnce()
6367
{
64-
Task<IDisposable> first = this.l.ReaderLockAsync();
68+
AsyncReaderWriterLock l = new();
69+
70+
Task<IDisposable> first = l.ReaderLockAsync();
6571
Assert.True(first.IsCompletedSuccessfully);
6672

67-
Task<IDisposable> second = this.l.ReaderLockAsync();
73+
Task<IDisposable> second = l.ReaderLockAsync();
6874
Assert.True(second.IsCompletedSuccessfully);
6975

70-
Task<IDisposable> third = this.l.ReaderLockAsync();
76+
Task<IDisposable> third = l.ReaderLockAsync();
7177
Assert.True(third.IsCompletedSuccessfully);
7278
}
7379

7480
[Fact]
7581
public void AllWaitingReadersReleasedConcurrently()
7682
{
77-
Task<IDisposable> writer = this.l.WriterLockAsync();
83+
AsyncReaderWriterLock l = new();
84+
85+
Task<IDisposable> writer = l.WriterLockAsync();
7886
Assert.True(writer.IsCompletedSuccessfully);
7987

80-
Task<IDisposable> reader1 = this.l.ReaderLockAsync();
88+
Task<IDisposable> reader1 = l.ReaderLockAsync();
8189
Assert.False(reader1.IsCompleted);
8290

83-
Task<IDisposable> reader2 = this.l.ReaderLockAsync();
91+
Task<IDisposable> reader2 = l.ReaderLockAsync();
8492
Assert.False(reader2.IsCompleted);
8593

86-
Task<IDisposable> reader3 = this.l.ReaderLockAsync();
94+
Task<IDisposable> reader3 = l.ReaderLockAsync();
8795
Assert.False(reader3.IsCompleted);
8896

8997
writer.Result.Dispose();

0 commit comments

Comments
 (0)