Skip to content

Commit 67bb85d

Browse files
author
Alex Peck
committed
unit test
1 parent 94f0d95 commit 67bb85d

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

BitFaster.Caching.UnitTests/Atomic/AtomicFactoryTests.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
using System;
23
using System.Threading;
34
using System.Threading.Tasks;
45
using BitFaster.Caching.Atomic;
@@ -159,5 +160,92 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner()
159160

160161
winnerCount.Should().Be(1);
161162
}
163+
164+
[Fact]
165+
public async Task WhenCallersRunConcurrentlyAndFailExceptionIsPropogated()
166+
{
167+
var enter = new ManualResetEvent(false);
168+
var resume = new ManualResetEvent(false);
169+
170+
var atomicFactory = new AtomicFactory<int, int>();
171+
var throwCount = 0;
172+
173+
Task<int> first = Task.Run(() =>
174+
{
175+
return atomicFactory.GetValue(1, k =>
176+
{
177+
enter.Set();
178+
resume.WaitOne();
179+
180+
Interlocked.Increment(ref throwCount);
181+
throw new Exception();
182+
});
183+
});
184+
185+
Task<int> second = Task.Run(() =>
186+
{
187+
return atomicFactory.GetValue(1, k =>
188+
{
189+
enter.Set();
190+
resume.WaitOne();
191+
192+
Interlocked.Increment(ref throwCount);
193+
throw new Exception();
194+
});
195+
});
196+
197+
enter.WaitOne();
198+
resume.Set();
199+
200+
Func<Task> act1 = () => first;
201+
Func<Task> act2 = () => second;
202+
203+
await act1.Should().ThrowAsync<Exception>();
204+
await act2.Should().ThrowAsync<Exception>();
205+
206+
// verify only one exception was thrown
207+
throwCount.Should().Be(1);
208+
}
209+
210+
[Fact]
211+
public async Task WhenCallersRunConcurrentlyAndFailNewCallerStartsClean()
212+
{
213+
var enter = new ManualResetEvent(false);
214+
var resume = new ManualResetEvent(false);
215+
216+
var atomicFactory = new AtomicFactory<int, int>();
217+
218+
Task<int> first = Task.Run(() =>
219+
{
220+
return atomicFactory.GetValue(1, k =>
221+
{
222+
enter.Set();
223+
resume.WaitOne();
224+
throw new Exception();
225+
});
226+
});
227+
228+
Task<int> second = Task.Run(() =>
229+
{
230+
return atomicFactory.GetValue(1, k =>
231+
{
232+
enter.Set();
233+
resume.WaitOne();
234+
throw new Exception();
235+
});
236+
});
237+
238+
enter.WaitOne();
239+
resume.Set();
240+
241+
Func<Task> act1 = () => first;
242+
Func<Task> act2 = () => second;
243+
244+
await act1.Should().ThrowAsync<Exception>();
245+
await act2.Should().ThrowAsync<Exception>();
246+
247+
// verify exception is no longer cached
248+
atomicFactory.GetValue(1, k => k).Should().Be(1);
249+
}
162250
}
163251
}

0 commit comments

Comments
 (0)