Ensure that KeepAliveTimeoutTests do not run with sync context (#1718)

- With Task.Delay(1).ConfigureAwait(false) there's a race where
  Task.IsCompleted could already be true by the time it's evaluated.
This commit is contained in:
Stephen Halter 2017-04-18 17:20:59 -07:00 committed by GitHub
parent 88890595d1
commit e4ba1d01ce
1 changed files with 20 additions and 20 deletions

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Net;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -22,33 +21,34 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
private static readonly TimeSpan ShortDelay = TimeSpan.FromSeconds(LongDelay.TotalSeconds / 10); private static readonly TimeSpan ShortDelay = TimeSpan.FromSeconds(LongDelay.TotalSeconds / 10);
[Fact] [Fact]
public async Task TestKeepAliveTimeout() public Task TestKeepAliveTimeout()
{ {
// Delays in these tests cannot be much longer than expected. // Delays in these tests cannot be much longer than expected.
// Call ConfigureAwait(false) to get rid of Xunit's synchronization context, // Call Task.Run() to get rid of Xunit's synchronization context,
// otherwise it can cause unexpectedly longer delays when multiple tests // otherwise it can cause unexpectedly longer delays when multiple tests
// are running in parallel. These tests becomes flaky on slower // are running in parallel. These tests becomes flaky on slower
// hardware because the continuations for the delay tasks might take too long to be // hardware because the continuations for the delay tasks might take too long to be
// scheduled if running on Xunit's synchronization context. // scheduled if running on Xunit's synchronization context.
await Task.Delay(1).ConfigureAwait(false); return Task.Run(async () =>
var longRunningCancellationTokenSource = new CancellationTokenSource();
var upgradeCancellationTokenSource = new CancellationTokenSource();
using (var server = CreateServer(longRunningCancellationTokenSource.Token, upgradeCancellationTokenSource.Token))
{ {
var tasks = new[] var longRunningCancellationTokenSource = new CancellationTokenSource();
{ var upgradeCancellationTokenSource = new CancellationTokenSource();
ConnectionClosedWhenKeepAliveTimeoutExpires(server),
ConnectionKeptAliveBetweenRequests(server),
ConnectionNotTimedOutWhileRequestBeingSent(server),
ConnectionNotTimedOutWhileAppIsRunning(server, longRunningCancellationTokenSource),
ConnectionTimesOutWhenOpenedButNoRequestSent(server),
KeepAliveTimeoutDoesNotApplyToUpgradedConnections(server, upgradeCancellationTokenSource)
};
await Task.WhenAll(tasks); using (var server = CreateServer(longRunningCancellationTokenSource.Token, upgradeCancellationTokenSource.Token))
} {
var tasks = new[]
{
ConnectionClosedWhenKeepAliveTimeoutExpires(server),
ConnectionKeptAliveBetweenRequests(server),
ConnectionNotTimedOutWhileRequestBeingSent(server),
ConnectionNotTimedOutWhileAppIsRunning(server, longRunningCancellationTokenSource),
ConnectionTimesOutWhenOpenedButNoRequestSent(server),
KeepAliveTimeoutDoesNotApplyToUpgradedConnections(server, upgradeCancellationTokenSource)
};
await Task.WhenAll(tasks);
}
});
} }
private async Task ConnectionClosedWhenKeepAliveTimeoutExpires(TimeoutTestServer server) private async Task ConnectionClosedWhenKeepAliveTimeoutExpires(TimeoutTestServer server)