Speed up unit tests

- Remove unnecessary uses of Task.Delay
- Change all usages to CancellationToken.None to default(CancellationToken)
  for consistency
This commit is contained in:
Stephen Halter 2016-01-27 13:01:44 -08:00
parent 00b8a13b55
commit a2fe59fb2c
8 changed files with 34 additions and 56 deletions

View File

@ -312,7 +312,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
} }
} }
await FlushAsync(CancellationToken.None); await FlushAsync(default(CancellationToken));
return DuplexStream; return DuplexStream;
} }

View File

@ -262,7 +262,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
Task.Factory.StartNew( Task.Factory.StartNew(
(o) => ((Frame)o).RequestProcessingAsync(), (o) => ((Frame)o).RequestProcessingAsync(),
this, this,
CancellationToken.None, default(CancellationToken),
TaskCreationOptions.DenyChildAttach, TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default); TaskScheduler.Default);
} }

View File

@ -59,9 +59,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
#if NET451 #if NET451
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{ {
ValidateState(CancellationToken.None); ValidateState(default(CancellationToken));
var task = ReadAsync(buffer, offset, count, CancellationToken.None, state); var task = ReadAsync(buffer, offset, count, default(CancellationToken), state);
if (callback != null) if (callback != null)
{ {
task.ContinueWith(t => callback.Invoke(t)); task.ContinueWith(t => callback.Invoke(t));

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
public override void Flush() public override void Flush()
{ {
ValidateState(CancellationToken.None); ValidateState(default(CancellationToken));
_context.FrameControl.Flush(); _context.FrameControl.Flush();
} }
@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)
{ {
ValidateState(CancellationToken.None); ValidateState(default(CancellationToken));
_context.FrameControl.Write(new ArraySegment<byte>(buffer, offset, count)); _context.FrameControl.Write(new ArraySegment<byte>(buffer, offset, count));
} }

View File

@ -474,7 +474,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
void ISocketOutput.Write(ArraySegment<byte> buffer, bool chunk) void ISocketOutput.Write(ArraySegment<byte> buffer, bool chunk)
{ {
WriteAsync(buffer, CancellationToken.None, chunk, isSync: true).GetAwaiter().GetResult(); WriteAsync(buffer, default(CancellationToken), chunk, isSync: true).GetAwaiter().GetResult();
} }
Task ISocketOutput.WriteAsync(ArraySegment<byte> buffer, bool chunk, CancellationToken cancellationToken) Task ISocketOutput.WriteAsync(ArraySegment<byte> buffer, bool chunk, CancellationToken cancellationToken)

View File

@ -209,16 +209,16 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
using (var connection = new TestConnection()) using (var connection = new TestConnection())
{ {
var requestData = var requestData =
Enumerable.Repeat("GET / HTTP/1.1\r\n", loopCount) Enumerable.Repeat("GET / HTTP/1.1\r\n", loopCount)
.Concat(new[] { "GET / HTTP/1.1\r\nConnection: close\r\n\r\nGoodbye" }); .Concat(new[] { "GET / HTTP/1.1\r\nConnection: close\r\n\r\nGoodbye" });
var responseData = var responseData =
Enumerable.Repeat("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n", loopCount) Enumerable.Repeat("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n", loopCount)
.Concat(new[] { "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nGoodbye" }); .Concat(new[] { "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nGoodbye" });
await connection.SendEnd(requestData.ToArray()); await connection.SendEnd(requestData.ToArray());
await connection.ReceiveEnd(responseData.ToArray()); await connection.ReceiveEnd(responseData.ToArray());
} }
@ -475,7 +475,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{ {
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
socket.Connect(IPAddress.Loopback, 54321); socket.Connect(IPAddress.Loopback, 54321);
await Task.Delay(200);
socket.Dispose(); socket.Dispose();
await Task.Delay(200); await Task.Delay(200);
@ -1096,9 +1095,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Test hangs after execution on Mono.")] [FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Test hangs after execution on Mono.")]
public async Task FailedWritesResultInAbortedRequest(ServiceContext testContext) public async Task FailedWritesResultInAbortedRequest(ServiceContext testContext)
{ {
const int resetEventTimeout = 2000;
// This should match _maxBytesPreCompleted in SocketOutput // This should match _maxBytesPreCompleted in SocketOutput
const int 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);
@ -1122,9 +1120,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
try try
{ {
// Ensure write is long enough to disable write-behind buffering // Ensure write is long enough to disable write-behind buffering
for (int i = 0; i < 100; i++) for (int i = 0; i < 10; i++)
{ {
await response.WriteAsync(largeString, lifetime.RequestAborted).ConfigureAwait(false); await response.WriteAsync(largeString, lifetime.RequestAborted);
} }
} }
catch (Exception ex) catch (Exception ex)
@ -1142,7 +1140,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
"POST / HTTP/1.1", "POST / HTTP/1.1",
"Content-Length: 5", "Content-Length: 5",
"", "",
"Hello").ConfigureAwait(false); "Hello");
// Don't wait to receive the response. Just close the socket. // Don't wait to receive the response. Just close the socket.
} }
@ -1151,7 +1149,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
// Write failed // Write failed
await Assert.ThrowsAsync<TaskCanceledException>(async () => await writeTcs.Task); await Assert.ThrowsAsync<TaskCanceledException>(async () => await writeTcs.Task);
// RequestAborted tripped // RequestAborted tripped
Assert.True(registrationWh.Wait(resetEventTimeout)); Assert.True(registrationWh.Wait(1000));
} }
} }

View File

@ -119,9 +119,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.True(completedWh.Wait(1000)); Assert.True(completedWh.Wait(1000));
} }
} }
[Fact] [Fact]
public async Task WritesDontCompleteImmediatelyWhenTooManyBytesIncludingNonImmediateAreAlreadyPreCompleted() public void WritesDontCompleteImmediatelyWhenTooManyBytesIncludingNonImmediateAreAlreadyPreCompleted()
{ {
// This should match _maxBytesPreCompleted in SocketOutput // This should match _maxBytesPreCompleted in SocketOutput
var maxBytesPreCompleted = 65536; var maxBytesPreCompleted = 65536;
@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
var halfWriteBehindBuffer = new ArraySegment<byte>(data, 0, bufferSize); var halfWriteBehindBuffer = new ArraySegment<byte>(data, 0, bufferSize);
// Act // Act
var writeTask1 = socketOutput.WriteAsync(halfWriteBehindBuffer, CancellationToken.None); var writeTask1 = socketOutput.WriteAsync(halfWriteBehindBuffer, default(CancellationToken));
// Assert // Assert
// The first write should pre-complete since it is <= _maxBytesPreCompleted. // The first write should pre-complete since it is <= _maxBytesPreCompleted.
Assert.Equal(TaskStatus.RanToCompletion, writeTask1.Status); Assert.Equal(TaskStatus.RanToCompletion, writeTask1.Status);
@ -168,7 +168,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
socketOutput.ProducingComplete(iter); socketOutput.ProducingComplete(iter);
// Act // Act
var writeTask2 = socketOutput.WriteAsync(halfWriteBehindBuffer, CancellationToken.None); var writeTask2 = socketOutput.WriteAsync(halfWriteBehindBuffer, default(CancellationToken));
// Assert // Assert
// Too many bytes are already pre-completed for the fourth write to pre-complete. // Too many bytes are already pre-completed for the fourth write to pre-complete.
Assert.True(writeRequestedWh.Wait(1000)); Assert.True(writeRequestedWh.Wait(1000));
@ -230,15 +230,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.False(task1Success.IsCanceled); Assert.False(task1Success.IsCanceled);
Assert.False(task1Success.IsFaulted); Assert.False(task1Success.IsFaulted);
task1Success.GetAwaiter().GetResult();
// following tasks should wait. // following tasks should wait.
var task2Throw = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token); var task2Throw = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token);
var task3Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken)); var task3Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken));
// Give time for tasks to percolate // Give time for tasks to percolate
await Task.Delay(1000).ConfigureAwait(false); await Task.Delay(1000);
// Second task is not completed // Second task is not completed
Assert.False(task2Throw.IsCompleted); Assert.False(task2Throw.IsCompleted);
@ -252,18 +249,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
cts.Cancel(); cts.Cancel();
// Give time for tasks to percolate
await Task.Delay(1000).ConfigureAwait(false);
// Second task is now canceled // Second task is now canceled
Assert.True(task2Throw.IsCompleted); await Assert.ThrowsAsync<TaskCanceledException>(() => task2Throw);
Assert.True(task2Throw.IsCanceled); Assert.True(task2Throw.IsCanceled);
Assert.False(task2Throw.IsFaulted);
// Third task is now completed // Third task is now completed
Assert.True(task3Success.IsCompleted); await task3Success;
Assert.False(task3Success.IsCanceled);
Assert.False(task3Success.IsFaulted);
// Fourth task immediately cancels as the token is canceled // Fourth task immediately cancels as the token is canceled
var task4Throw = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token); var task4Throw = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token);
@ -272,25 +263,21 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.True(task4Throw.IsCanceled); Assert.True(task4Throw.IsCanceled);
Assert.False(task4Throw.IsFaulted); Assert.False(task4Throw.IsFaulted);
Assert.Throws<TaskCanceledException>(() => task4Throw.GetAwaiter().GetResult());
var task5Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken)); var task5Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken));
// task5 should complete immediately // task5 should complete immediately
Assert.True(task5Success.IsCompleted); Assert.True(task5Success.IsCompleted);
Assert.False(task5Success.IsCanceled); Assert.False(task5Success.IsCanceled);
Assert.False(task5Success.IsFaulted); Assert.False(task5Success.IsFaulted);
cts = new CancellationTokenSource(); cts = new CancellationTokenSource();
var task6Throw = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token); var task6Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token);
// task6 should complete immediately but not cancel as its cancellation token isn't set // task6 should complete immediately but not cancel as its cancellation token isn't set
Assert.True(task6Throw.IsCompleted); Assert.True(task6Success.IsCompleted);
Assert.False(task6Throw.IsCanceled); Assert.False(task6Success.IsCanceled);
Assert.False(task6Throw.IsFaulted); Assert.False(task6Success.IsFaulted);
task6Throw.GetAwaiter().GetResult();
Assert.True(true); Assert.True(true);
} }
@ -342,14 +329,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.False(task1Success.IsCanceled); Assert.False(task1Success.IsCanceled);
Assert.False(task1Success.IsFaulted); Assert.False(task1Success.IsFaulted);
task1Success.GetAwaiter().GetResult();
// following tasks should wait. // following tasks should wait.
var task2Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: CancellationToken.None); var task2Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken));
var task3Canceled = socketOutput.WriteAsync(fullBuffer, cancellationToken: abortedSource.Token); var task3Canceled = socketOutput.WriteAsync(fullBuffer, cancellationToken: abortedSource.Token);
// Give time for tasks to percolate // Give time for tasks to percolate
await Task.Delay(1000).ConfigureAwait(false); await Task.Delay(1000);
// Second task is not completed // Second task is not completed
Assert.False(task2Success.IsCompleted); Assert.False(task2Success.IsCompleted);
@ -364,18 +349,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
// Cause the first write to fail. // Cause the first write to fail.
completeQueue.Dequeue()(-1); completeQueue.Dequeue()(-1);
// Give time for tasks to percolate
await Task.Delay(1000).ConfigureAwait(false);
// Second task is now completed // Second task is now completed
Assert.True(task2Success.IsCompleted); await task2Success;
Assert.False(task2Success.IsCanceled);
Assert.False(task2Success.IsFaulted);
// Third task is now canceled // Third task is now canceled
Assert.True(task3Canceled.IsCompleted); await Assert.ThrowsAsync<TaskCanceledException>(() => task3Canceled);
Assert.True(task3Canceled.IsCanceled); Assert.True(task3Canceled.IsCanceled);
Assert.False(task3Canceled.IsFaulted);
} }
} }

View File

@ -49,7 +49,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
var ch = text[index]; var ch = text[index];
await writer.WriteAsync(ch); await writer.WriteAsync(ch);
await writer.FlushAsync(); await writer.FlushAsync();
await Task.Delay(TimeSpan.FromMilliseconds(5)); // Re-add delay to help find socket input consumption bugs more consistently
//await Task.Delay(TimeSpan.FromMilliseconds(5));
} }
writer.Flush(); writer.Flush();
_stream.Flush(); _stream.Flush();