Skip to content

Commit 4847704

Browse files
authored
Serialize soak test execution (#412)
* soak tests * more soak tests * more soak tests ---------
1 parent 8a5aba4 commit 4847704

12 files changed

+463
-369
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using BitFaster.Caching.Buffers;
5+
using FluentAssertions;
6+
using Xunit;
7+
using Xunit.Abstractions;
8+
9+
namespace BitFaster.Caching.UnitTests.Buffers
10+
{
11+
[Collection("Soak")]
12+
public class MpscBoundedBufferSoakTests
13+
{
14+
private readonly ITestOutputHelper testOutputHelper;
15+
private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(30);
16+
17+
public MpscBoundedBufferSoakTests(ITestOutputHelper testOutputHelper)
18+
{
19+
this.testOutputHelper = testOutputHelper;
20+
}
21+
22+
[Fact]
23+
public async Task WhenAddIsContendedBufferCanBeFilled()
24+
{
25+
var buffer = new MpscBoundedBuffer<string>(1024);
26+
27+
await Threaded.Run(4, () =>
28+
{
29+
while (buffer.TryAdd("hello") != BufferStatus.Full)
30+
{
31+
}
32+
33+
buffer.Count.Should().Be(1024);
34+
});
35+
}
36+
37+
[Fact]
38+
public async Task WhileBufferIsFilledItemsCanBeTaken()
39+
{
40+
this.testOutputHelper.WriteLine($"ProcessorCount={Environment.ProcessorCount}.");
41+
42+
var buffer = new MpscBoundedBuffer<string>(1024);
43+
44+
var fill = Threaded.Run(4, () =>
45+
{
46+
var spin = new SpinWait();
47+
int count = 0;
48+
while (count < 256)
49+
{
50+
while (true)
51+
{
52+
if (buffer.TryAdd("hello") == BufferStatus.Success)
53+
{
54+
break;
55+
}
56+
spin.SpinOnce();
57+
}
58+
count++;
59+
}
60+
});
61+
62+
var take = Task.Run(() =>
63+
{
64+
int taken = 0;
65+
66+
while (taken < 1024)
67+
{
68+
var spin = new SpinWait();
69+
if (buffer.TryTake(out var _) == BufferStatus.Success)
70+
{
71+
taken++;
72+
}
73+
spin.SpinOnce();
74+
}
75+
});
76+
77+
await fill.TimeoutAfter(Timeout, "fill timed out");
78+
await take.TimeoutAfter(Timeout, "take timed out");
79+
}
80+
81+
[Fact]
82+
public async Task WhileBufferIsFilledBufferCanBeDrained()
83+
{
84+
this.testOutputHelper.WriteLine($"ProcessorCount={Environment.ProcessorCount}.");
85+
86+
var buffer = new MpscBoundedBuffer<string>(1024);
87+
88+
var fill = Threaded.Run(4, () =>
89+
{
90+
var spin = new SpinWait();
91+
int count = 0;
92+
while (count < 256)
93+
{
94+
while (true)
95+
{
96+
if (buffer.TryAdd("hello") == BufferStatus.Success)
97+
{
98+
break;
99+
}
100+
spin.SpinOnce();
101+
}
102+
count++;
103+
}
104+
});
105+
106+
var drain = Task.Run(() =>
107+
{
108+
int drained = 0;
109+
var drainBuffer = new ArraySegment<string>(new string[1024]);
110+
111+
while (drained < 1024)
112+
{
113+
drained += buffer.DrainTo(drainBuffer);
114+
}
115+
});
116+
117+
await fill.TimeoutAfter(Timeout, "fill timed out");
118+
await drain.TimeoutAfter(Timeout, "drain timed out");
119+
}
120+
}
121+
}

BitFaster.Caching.UnitTests/Buffers/MpscBoundedBufferTests.cs

Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
using System;
2-
using System.Threading;
3-
using System.Threading.Tasks;
42
using BitFaster.Caching.Buffers;
53
using FluentAssertions;
6-
using Xunit;
7-
using Xunit.Abstractions;
4+
using Xunit;
85

96
namespace BitFaster.Caching.UnitTests.Buffers
107
{
118
public class MpscBoundedBufferTests
129
{
13-
private readonly ITestOutputHelper testOutputHelper;
14-
private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(30);
1510
private readonly MpscBoundedBuffer<string> buffer = new MpscBoundedBuffer<string>(10);
16-
17-
public MpscBoundedBufferTests(ITestOutputHelper testOutputHelper)
18-
{
19-
this.testOutputHelper = testOutputHelper;
20-
}
2111

2212
[Fact]
2313
public void WhenSizeIsLessThan1CtorThrows()
@@ -161,104 +151,5 @@ public void WhenSegmentUsesOffsetItemsDrainedToOffset()
161151
outputBuffer[7].Should().Be("2");
162152
outputBuffer[8].Should().Be("3");
163153
}
164-
165-
[Fact]
166-
public async Task WhenAddIsContendedBufferCanBeFilled()
167-
{
168-
var buffer = new MpscBoundedBuffer<string>(1024);
169-
170-
await Threaded.Run(4, () =>
171-
{
172-
while (buffer.TryAdd("hello") != BufferStatus.Full)
173-
{
174-
}
175-
176-
buffer.Count.Should().Be(1024);
177-
});
178-
}
179-
180-
[Fact]
181-
public async Task WhileBufferIsFilledItemsCanBeTaken()
182-
{
183-
this.testOutputHelper.WriteLine($"ProcessorCount={Environment.ProcessorCount}.");
184-
185-
var buffer = new MpscBoundedBuffer<string>(1024);
186-
187-
var fill = Threaded.Run(4, () =>
188-
{
189-
var spin = new SpinWait();
190-
int count = 0;
191-
while (count < 256)
192-
{
193-
while (true)
194-
{
195-
if (buffer.TryAdd("hello") == BufferStatus.Success)
196-
{
197-
break;
198-
}
199-
spin.SpinOnce();
200-
}
201-
count++;
202-
}
203-
});
204-
205-
var take = Task.Run(() =>
206-
{
207-
int taken = 0;
208-
209-
while (taken < 1024)
210-
{
211-
var spin = new SpinWait();
212-
if (buffer.TryTake(out var _) == BufferStatus.Success)
213-
{
214-
taken++;
215-
}
216-
spin.SpinOnce();
217-
}
218-
});
219-
220-
await fill.TimeoutAfter(Timeout, $"fill timed out");
221-
await take.TimeoutAfter(Timeout, "take timed out");
222-
}
223-
224-
[Fact]
225-
public async Task WhileBufferIsFilledBufferCanBeDrained()
226-
{
227-
this.testOutputHelper.WriteLine($"ProcessorCount={Environment.ProcessorCount}.");
228-
229-
var buffer = new MpscBoundedBuffer<string>(1024);
230-
231-
var fill = Threaded.Run(4, () =>
232-
{
233-
var spin = new SpinWait();
234-
int count = 0;
235-
while (count < 256)
236-
{
237-
while (true)
238-
{
239-
if (buffer.TryAdd("hello") == BufferStatus.Success)
240-
{
241-
break;
242-
}
243-
spin.SpinOnce();
244-
}
245-
count++;
246-
}
247-
});
248-
249-
var drain = Task.Run(() =>
250-
{
251-
int drained = 0;
252-
var drainBuffer = new ArraySegment<string>(new string[1024]);
253-
254-
while (drained < 1024)
255-
{
256-
drained += buffer.DrainTo(drainBuffer);
257-
}
258-
});
259-
260-
await fill.TimeoutAfter(Timeout, "fill timed out");
261-
await drain.TimeoutAfter(Timeout, "drain timed out");
262-
}
263154
}
264155
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Threading.Tasks;
2+
using BitFaster.Caching.Counters;
3+
using FluentAssertions;
4+
using Xunit;
5+
6+
namespace BitFaster.Caching.UnitTests.Counters
7+
{
8+
[Collection("Soak")]
9+
public class CounterSoakTests
10+
{
11+
[Fact]
12+
public async Task WhenAddingConcurrentlySumIsCorrect()
13+
{
14+
var adder = new Counter();
15+
16+
await Threaded.Run(4, () =>
17+
{
18+
for (int i = 0; i < 100_000; i++)
19+
{
20+
adder.Increment();
21+
}
22+
});
23+
24+
adder.Count().Should().Be(400_000);
25+
}
26+
}
27+
}
Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Threading.Tasks;
2-
using BitFaster.Caching.Counters;
1+
using BitFaster.Caching.Counters;
32
using FluentAssertions;
43
using Xunit;
54

@@ -22,21 +21,5 @@ public void WhenIncrementedOneIsAdded()
2221

2322
adder.Count().Should().Be(1);
2423
}
25-
26-
[Fact]
27-
public async Task WhenAddingConcurrentlySumIsCorrect()
28-
{
29-
var adder = new Counter();
30-
31-
await Threaded.Run(4, () =>
32-
{
33-
for (int i = 0; i < 100_000; i++)
34-
{
35-
adder.Increment();
36-
}
37-
});
38-
39-
adder.Count().Should().Be(400_000);
40-
}
4124
}
4225
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using BitFaster.Caching.Lfu;
5+
using BitFaster.Caching.Scheduler;
6+
using FluentAssertions;
7+
using Xunit;
8+
using Xunit.Abstractions;
9+
10+
namespace BitFaster.Caching.UnitTests.Lfu
11+
{
12+
[Collection("Soak")]
13+
public class ConcurrentLfuSoakTests
14+
{
15+
private readonly ITestOutputHelper output;
16+
public ConcurrentLfuSoakTests(ITestOutputHelper testOutputHelper)
17+
{
18+
this.output = testOutputHelper;
19+
}
20+
21+
[Fact]
22+
public async Task ThreadedVerifyMisses()
23+
{
24+
// buffer size is 1, this will cause dropped writes on some threads where the buffer is full
25+
var cache = new ConcurrentLfu<int, int>(1, 20, new NullScheduler(), EqualityComparer<int>.Default);
26+
27+
int threads = 4;
28+
int iterations = 100_000;
29+
30+
await Threaded.Run(threads, i =>
31+
{
32+
Func<int, int> func = x => x;
33+
34+
int start = i * iterations;
35+
36+
for (int j = start; j < start + iterations; j++)
37+
{
38+
cache.GetOrAdd(j, func);
39+
}
40+
});
41+
42+
var samplePercent = cache.Metrics.Value.Misses / (double)iterations / threads * 100;
43+
44+
this.output.WriteLine($"Cache misses {cache.Metrics.Value.Misses} (sampled {samplePercent}%)");
45+
this.output.WriteLine($"Maintenance ops {cache.Scheduler.RunCount}");
46+
47+
cache.Metrics.Value.Misses.Should().Be(iterations * threads);
48+
}
49+
}
50+
}

BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuTests.cs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -832,35 +832,6 @@ public void VerifyMisses()
832832
cache.Metrics.Value.Misses.Should().Be(iterations);
833833
}
834834

835-
[Fact]
836-
public async Task ThreadedVerifyMisses()
837-
{
838-
// buffer size is 1, this will cause dropped writes on some threads where the buffer is full
839-
cache = new ConcurrentLfu<int, int>(1, 20, new NullScheduler(), EqualityComparer<int>.Default);
840-
841-
int threads = 4;
842-
int iterations = 100_000;
843-
844-
await Threaded.Run(threads, i =>
845-
{
846-
Func<int, int> func = x => x;
847-
848-
int start = i * iterations;
849-
850-
for (int j = start; j < start + iterations; j++)
851-
{
852-
cache.GetOrAdd(j, func);
853-
}
854-
});
855-
856-
var samplePercent = this.cache.Metrics.Value.Misses / (double)iterations / threads * 100;
857-
858-
this.output.WriteLine($"Cache misses {this.cache.Metrics.Value.Misses} (sampled {samplePercent}%)");
859-
this.output.WriteLine($"Maintenance ops {this.cache.Scheduler.RunCount}");
860-
861-
cache.Metrics.Value.Misses.Should().Be(iterations * threads);
862-
}
863-
864835
private void VerifyHits(int iterations, int minSamples)
865836
{
866837
Func<int, int> func = x => x;

0 commit comments

Comments
 (0)