Skip to content

Commit 1f5e0ea

Browse files
fix: Adaptive Timeout tests are too optimistic about runtime capabilities (#232)
* fix: Take 1 at making adaptive timeout tests more robust * fix: Tests need to be less optimisitc about runtime capabilities * chore: remove unecessary task delay
1 parent afe28af commit 1f5e0ea

1 file changed

Lines changed: 21 additions & 38 deletions

File tree

test/unit/AdaptiveTimeoutTest.cs

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,8 @@ public async Task AdaptiveTimeout_GetAdaptiveTimeout_TimeSpikeSafetyValve() {
6464

6565
await Task.WhenAll(tasks);
6666

67-
for (int i = 0; i < 3; i++) {
68-
await adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(200));
69-
await Task.Delay(i + 5);
70-
}
67+
for (int i = 0; i < 3; i++)
68+
await adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(500));
7169

7270
var adaptiveTimeoutResult = adaptiveTimeout.GetAdaptiveTimeout();
7371
Assert.Equal(maxTimeout, adaptiveTimeoutResult);
@@ -76,25 +74,23 @@ public async Task AdaptiveTimeout_GetAdaptiveTimeout_TimeSpikeSafetyValve() {
7674
[Fact]
7775
public async Task AdaptiveTimeout_GetAdaptiveTimeout_TimeSpikeSafetyValve_IgnoreHiccup() {
7876
var tasks = new List<Task>();
79-
var maxTimeout = TimeSpan.FromMilliseconds(100);
80-
var numSamples = 10;
81-
var adaptiveTimeout = new AdaptiveTimeout(maxTimeout, new TestLogger(_testOutputHelper, Microsoft.Extensions.Logging.LogLevel.Trace), numSamples, 1000, 5);
77+
var maxTimeout = TimeSpan.FromSeconds(1);
78+
var numSamples = 5;
79+
var adaptiveTimeout = new AdaptiveTimeout(maxTimeout, new TestLogger(_testOutputHelper, Microsoft.Extensions.Logging.LogLevel.Trace), numSamples, 1000, 2);
8280

8381
// Prepare our successful samples
8482
for (int i = 0; i < numSamples; i++)
85-
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(i)));
83+
tasks.Add(adaptiveTimeout.ExecuteWithTimeout((_) => Task.CompletedTask));
8684

8785
await Task.WhenAll(tasks);
8886

8987
// Add some timeout tasks that will resolve last
90-
for (int i = 0; i < 3; i++) {
91-
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(200)));
92-
await Task.Delay(i + 5);
93-
}
88+
for (int i = 0; i < 5; i++)
89+
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(2000)));
9490

9591
// These tasks are added later but will resolve first
9692
for (int i = 0; i < 4; i++)
97-
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(i)));
93+
tasks.Add(adaptiveTimeout.ExecuteWithTimeout((_) => Task.CompletedTask));
9894

9995
await Task.WhenAll(tasks);
10096
var adaptiveTimeoutResult = adaptiveTimeout.GetAdaptiveTimeout();
@@ -106,48 +102,35 @@ public async Task AdaptiveTimeout_GetAdaptiveTimeout_TimeSpikeSafetyValve_Ignore
106102
[Fact]
107103
public async Task AdaptiveTimeout_GetAdaptiveTimeout_ThrowWhenExcessiveTimeouts() {
108104
var tasks = new List<Task>();
109-
var maxTimeout = TimeSpan.FromMilliseconds(100);
110-
var numSamples = 10;
111-
var adaptiveTimeout = new AdaptiveTimeout(maxTimeout, new TestLogger(_testOutputHelper, Microsoft.Extensions.Logging.LogLevel.Trace), numSamples, 1000, 5, throwIfExcessiveTimeouts: true);
105+
var maxTimeout = TimeSpan.FromMilliseconds(500);
106+
var numSamples = 5;
107+
var adaptiveTimeout = new AdaptiveTimeout(maxTimeout, new TestLogger(_testOutputHelper, Microsoft.Extensions.Logging.LogLevel.Trace), numSamples, 1000, 2, throwIfExcessiveTimeouts: true);
112108

113109
for (int i = 0; i < numSamples; i++)
114-
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(10)));
110+
tasks.Add(adaptiveTimeout.ExecuteWithTimeout((_) => Task.CompletedTask));
115111

116112
await Task.WhenAll(tasks);
117113

118-
for (int i = 0; i < 15; i++) {
119-
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(200)));
120-
// Staggering these tasks because TimeSpikeSafetyValve is not entirely atomic.
121-
// There's no guarantee that _timeSpikeDecay can't change between the moment it's read to the moment it's modified
122-
// So too many concurrent reads may cause a race condition that bungles the process.
123-
// In this case I suspect the cure is worse than the illness though,
124-
// as I'm less worried about a little bit of wiggle in this process
125-
// than I am about the additional overhead of guaranteeing atomicity through memory locks
126-
// on a process that I want to run very very fast.
127-
// So instead of making TimeSpikeSafetyValve more thread safe than it is now,
128-
// I think I'd rather leave that hole and hack some thread stagger in this test.
129-
await Task.Delay(i + 5);
130-
}
114+
for (int i = 0; i < 20; i++)
115+
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(1000)));
131116

132117
await Assert.ThrowsAsync<ExcessiveTimeoutsException>(async () => await Task.WhenAll(tasks));
133118
}
134119

135120
[Fact]
136121
public async Task AdaptiveTimeout_GetAdaptiveTimeout_DoNotThrowWhenExcessiveTimeouts() {
137122
var tasks = new List<Task>();
138-
var maxTimeout = TimeSpan.FromMilliseconds(100);
139-
var numSamples = 10;
140-
var adaptiveTimeout = new AdaptiveTimeout(maxTimeout, new TestLogger(_testOutputHelper, Microsoft.Extensions.Logging.LogLevel.Trace), numSamples, 1000, 5, throwIfExcessiveTimeouts: false);
123+
var maxTimeout = TimeSpan.FromMilliseconds(500);
124+
var numSamples = 5;
125+
var adaptiveTimeout = new AdaptiveTimeout(maxTimeout, new TestLogger(_testOutputHelper, Microsoft.Extensions.Logging.LogLevel.Trace), numSamples, 1000, 2, throwIfExcessiveTimeouts: false);
141126

142127
for (int i = 0; i < numSamples; i++)
143-
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(10)));
128+
tasks.Add(adaptiveTimeout.ExecuteWithTimeout((_) => Task.CompletedTask));
144129

145130
await Task.WhenAll(tasks);
146131

147-
for (int i = 0; i < 15; i++) {
148-
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(200)));
149-
await Task.Delay(i + 5);
150-
}
132+
for (int i = 0; i < 20; i++)
133+
tasks.Add(adaptiveTimeout.ExecuteWithTimeout(async (_) => await Task.Delay(1000)));
151134

152135
await Task.WhenAll(tasks);
153136
}

0 commit comments

Comments
 (0)