Fix flaky ResponseTests.FailedWritesResultInAbortedRequest.
This commit is contained in:
parent
7f0319f5dd
commit
f8a6433cd5
|
|
@ -2063,40 +2063,32 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionAdapterData))]
|
[MemberData(nameof(ConnectionAdapterData))]
|
||||||
public async Task FailedWritesResultInAbortedRequest(ListenOptions listenOptions)
|
public async Task ThrowsOnWriteWithRequestAbortedTokenAfterRequestIsAborted(ListenOptions listenOptions)
|
||||||
{
|
{
|
||||||
var testContext = new TestServiceContext();
|
|
||||||
|
|
||||||
// This should match _maxBytesPreCompleted in SocketOutput
|
// This should match _maxBytesPreCompleted in SocketOutput
|
||||||
var maxBytesPreCompleted = 65536;
|
var maxBytesPreCompleted = 65536;
|
||||||
|
|
||||||
// Ensure string is long enough to disable write-behind buffering
|
// Ensure string is long enough to disable write-behind buffering
|
||||||
var largeString = new string('a', maxBytesPreCompleted + 1);
|
var largeString = new string('a', maxBytesPreCompleted + 1);
|
||||||
|
|
||||||
var writeTcs = new TaskCompletionSource<object>();
|
var writeTcs = new TaskCompletionSource<object>();
|
||||||
var registrationWh = new ManualResetEventSlim();
|
var requestAbortedWh = new ManualResetEventSlim();
|
||||||
var connectionCloseWh = new ManualResetEventSlim();
|
|
||||||
var requestStartWh = new ManualResetEventSlim();
|
var requestStartWh = new ManualResetEventSlim();
|
||||||
|
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
requestStartWh.Set();
|
requestStartWh.Set();
|
||||||
|
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
var request = httpContext.Request;
|
var request = httpContext.Request;
|
||||||
var lifetime = httpContext.Features.Get<IHttpRequestLifetimeFeature>();
|
var lifetime = httpContext.Features.Get<IHttpRequestLifetimeFeature>();
|
||||||
|
|
||||||
lifetime.RequestAborted.Register(() => registrationWh.Set());
|
lifetime.RequestAborted.Register(() => requestAbortedWh.Set());
|
||||||
|
Assert.True(requestAbortedWh.Wait(TimeSpan.FromSeconds(10)));
|
||||||
await request.Body.CopyToAsync(Stream.Null);
|
|
||||||
Assert.True(connectionCloseWh.Wait(10_000));
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Ensure write is long enough to disable write-behind buffering
|
await response.WriteAsync(largeString, lifetime.RequestAborted);
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
await response.WriteAsync(largeString, lifetime.RequestAborted);
|
|
||||||
registrationWh.Wait(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -2105,26 +2097,26 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
writeTcs.SetException(new Exception("This shouldn't be reached."));
|
writeTcs.SetException(new Exception("This shouldn't be reached."));
|
||||||
}, testContext, listenOptions))
|
}, new TestServiceContext(), listenOptions))
|
||||||
{
|
{
|
||||||
using (var connection = server.CreateConnection())
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
"Host:",
|
"Host:",
|
||||||
"Content-Length: 5",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"Hello");
|
"");
|
||||||
|
|
||||||
Assert.True(requestStartWh.Wait(10_000));
|
Assert.True(requestStartWh.Wait(TimeSpan.FromSeconds(10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionCloseWh.Set();
|
// Write failed - can throw TaskCanceledException or OperationCanceledException,
|
||||||
|
// dependending on how far the canceled write goes.
|
||||||
|
await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await writeTcs.Task).TimeoutAfter(TimeSpan.FromSeconds(15));
|
||||||
|
|
||||||
// Write failed
|
|
||||||
await Assert.ThrowsAsync<TaskCanceledException>(async () => await writeTcs.Task).TimeoutAfter(TimeSpan.FromSeconds(15));
|
|
||||||
// RequestAborted tripped
|
// RequestAborted tripped
|
||||||
Assert.True(registrationWh.Wait(1000));
|
Assert.True(requestAbortedWh.Wait(TimeSpan.FromSeconds(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue