Fixed flaky shutdown tests
This commit is contained in:
parent
41c923926e
commit
7e18efbf1f
|
|
@ -26,7 +26,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
internal static ServerData CreateServer(
|
internal static ServerData CreateServer(
|
||||||
string pipeName = null,
|
string pipeName = null,
|
||||||
CompilerHost compilerHost = null,
|
CompilerHost compilerHost = null,
|
||||||
ConnectionHost connectionHost = null)
|
ConnectionHost connectionHost = null,
|
||||||
|
Action<object, EventArgs> onListening = null)
|
||||||
{
|
{
|
||||||
pipeName = pipeName ?? Guid.NewGuid().ToString();
|
pipeName = pipeName ?? Guid.NewGuid().ToString();
|
||||||
compilerHost = compilerHost ?? CompilerHost.Create();
|
compilerHost = compilerHost ?? CompilerHost.Create();
|
||||||
|
|
@ -40,6 +41,10 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
{
|
{
|
||||||
var eventBus = new TestableEventBus();
|
var eventBus = new TestableEventBus();
|
||||||
eventBus.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
|
eventBus.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
|
||||||
|
if (onListening != null)
|
||||||
|
{
|
||||||
|
eventBus.Listening += (sender, e) => onListening(sender, e);
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RunServer(
|
RunServer(
|
||||||
|
|
|
||||||
|
|
@ -116,17 +116,19 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
/// A shutdown request should not abort an existing compilation. It should be allowed to run to
|
/// A shutdown request should not abort an existing compilation. It should be allowed to run to
|
||||||
/// completion.
|
/// completion.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
|
[Fact]
|
||||||
[ConditionalFact]
|
|
||||||
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
|
||||||
public async Task ServerRunning_ShutdownRequest_DoesNotAbortCompilation()
|
public async Task ServerRunning_ShutdownRequest_DoesNotAbortCompilation()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var completionSource = new TaskCompletionSource<bool>();
|
var startCompilationSource = new TaskCompletionSource<bool>();
|
||||||
|
var finishCompilationSource = new TaskCompletionSource<bool>();
|
||||||
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) =>
|
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) =>
|
||||||
{
|
{
|
||||||
|
// At this point, the connection has been accepted and the compilation has started.
|
||||||
|
startCompilationSource.SetResult(true);
|
||||||
|
|
||||||
// We want this to keep running even after the shutdown is seen.
|
// We want this to keep running even after the shutdown is seen.
|
||||||
completionSource.Task.Wait();
|
finishCompilationSource.Task.Wait();
|
||||||
return EmptyServerResponse;
|
return EmptyServerResponse;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -134,13 +136,16 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
{
|
{
|
||||||
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
|
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
|
||||||
|
|
||||||
|
// Wait for the request to go through and trigger compilation.
|
||||||
|
await startCompilationSource.Task;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
// The compilation is now in progress, send the shutdown.
|
// The compilation is now in progress, send the shutdown.
|
||||||
await ServerUtilities.SendShutdown(serverData.PipeName);
|
await ServerUtilities.SendShutdown(serverData.PipeName);
|
||||||
Assert.False(compileTask.IsCompleted);
|
Assert.False(compileTask.IsCompleted);
|
||||||
|
|
||||||
// Now let the task complete.
|
// Now let the task complete.
|
||||||
completionSource.SetResult(true);
|
finishCompilationSource.SetResult(true);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var response = await compileTask;
|
var response = await compileTask;
|
||||||
|
|
@ -154,17 +159,19 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Multiple clients should be able to send shutdown requests to the server.
|
/// Multiple clients should be able to send shutdown requests to the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
|
[Fact]
|
||||||
[ConditionalFact]
|
|
||||||
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
|
||||||
public async Task ServerRunning_MultipleShutdownRequests_HandlesSuccessfully()
|
public async Task ServerRunning_MultipleShutdownRequests_HandlesSuccessfully()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var completionSource = new TaskCompletionSource<bool>();
|
var startCompilationSource = new TaskCompletionSource<bool>();
|
||||||
|
var finishCompilationSource = new TaskCompletionSource<bool>();
|
||||||
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) =>
|
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) =>
|
||||||
{
|
{
|
||||||
|
// At this point, the connection has been accepted and the compilation has started.
|
||||||
|
startCompilationSource.SetResult(true);
|
||||||
|
|
||||||
// We want this to keep running even after the shutdown is seen.
|
// We want this to keep running even after the shutdown is seen.
|
||||||
completionSource.Task.Wait();
|
finishCompilationSource.Task.Wait();
|
||||||
return EmptyServerResponse;
|
return EmptyServerResponse;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -172,6 +179,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
{
|
{
|
||||||
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
|
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
|
||||||
|
|
||||||
|
// Wait for the request to go through and trigger compilation.
|
||||||
|
await startCompilationSource.Task;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
for (var i = 0; i < 10; i++)
|
for (var i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -182,7 +192,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now let the task complete.
|
// Now let the task complete.
|
||||||
completionSource.SetResult(true);
|
finishCompilationSource.SetResult(true);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var response = await compileTask;
|
var response = await compileTask;
|
||||||
|
|
@ -193,9 +203,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
|
[Fact]
|
||||||
[ConditionalFact]
|
|
||||||
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
|
||||||
public async Task ServerRunning_CancelCompilation_CancelsSuccessfully()
|
public async Task ServerRunning_CancelCompilation_CancelsSuccessfully()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -213,18 +221,28 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
return new RejectedServerResponse();
|
return new RejectedServerResponse();
|
||||||
});
|
});
|
||||||
|
|
||||||
using (var serverData = ServerUtilities.CreateServer(compilerHost: host))
|
var semaphore = new SemaphoreSlim(1);
|
||||||
|
Action<object, EventArgs> onListening = (s, e) =>
|
||||||
{
|
{
|
||||||
var tasks = new List<Task<ServerResponse>>();
|
semaphore.Release();
|
||||||
|
};
|
||||||
|
using (var serverData = ServerUtilities.CreateServer(compilerHost: host, onListening: onListening))
|
||||||
|
{
|
||||||
|
// Send all the requests.
|
||||||
|
var clients = new List<Client>();
|
||||||
for (var i = 0; i < requestCount; i++)
|
for (var i = 0; i < requestCount; i++)
|
||||||
{
|
{
|
||||||
var task = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
|
// Wait for the server to start listening.
|
||||||
tasks.Add(task);
|
await semaphore.WaitAsync(TimeSpan.FromMinutes(1));
|
||||||
|
|
||||||
|
var client = await Client.ConnectAsync(serverData.PipeName, timeout: null, cancellationToken: default);
|
||||||
|
await EmptyServerRequest.WriteAsync(client.Stream);
|
||||||
|
clients.Add(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
// Wait until all of the connections are being processed by the server.
|
// Wait until all of the connections are being processed by the server.
|
||||||
completionSource.Task.Wait();
|
await completionSource.Task;
|
||||||
|
|
||||||
// Now cancel
|
// Now cancel
|
||||||
var stats = await serverData.CancelAndCompleteAsync();
|
var stats = await serverData.CancelAndCompleteAsync();
|
||||||
|
|
@ -233,10 +251,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
||||||
Assert.Equal(requestCount, stats.Connections);
|
Assert.Equal(requestCount, stats.Connections);
|
||||||
Assert.Equal(requestCount, count);
|
Assert.Equal(requestCount, count);
|
||||||
|
|
||||||
foreach (var task in tasks)
|
// Read the server response to each client.
|
||||||
|
foreach (var client in clients)
|
||||||
{
|
{
|
||||||
|
var task = ServerResponse.ReadAsync(client.Stream);
|
||||||
// We expect this to throw because the stream is already closed.
|
// We expect this to throw because the stream is already closed.
|
||||||
await Assert.ThrowsAsync<EndOfStreamException>(() => task);
|
await Assert.ThrowsAnyAsync<IOException>(() => task);
|
||||||
|
client.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue