diff --git a/src/Microsoft.AspNetCore.Razor.Tools/DefaultRequestDispatcher.cs b/src/Microsoft.AspNetCore.Razor.Tools/DefaultRequestDispatcher.cs
index 26747a06b6..59d2bbc098 100644
--- a/src/Microsoft.AspNetCore.Razor.Tools/DefaultRequestDispatcher.cs
+++ b/src/Microsoft.AspNetCore.Razor.Tools/DefaultRequestDispatcher.cs
@@ -383,6 +383,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
ServerLogger.Log("End writing response.");
reason = ConnectionResult.Reason.CompilationCompleted;
+
+ _eventBus.CompilationCompleted();
}
catch
{
diff --git a/src/Microsoft.AspNetCore.Razor.Tools/EventBus.cs b/src/Microsoft.AspNetCore.Razor.Tools/EventBus.cs
index 958a637deb..dacd5c07e7 100644
--- a/src/Microsoft.AspNetCore.Razor.Tools/EventBus.cs
+++ b/src/Microsoft.AspNetCore.Razor.Tools/EventBus.cs
@@ -37,6 +37,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
public virtual void ConnectionCompleted(int count)
{
}
+
+ ///
+ /// Called when a compilation is completed successfully and the response is written to the stream.
+ ///
+ public virtual void CompilationCompleted()
+ {
+ }
///
/// Called when a bad client connection was detected and the server will be shutting down as a
diff --git a/test/Microsoft.AspNetCore.Razor.Tools.Test/DefaultRequestDispatcherTest.cs b/test/Microsoft.AspNetCore.Razor.Tools.Test/DefaultRequestDispatcherTest.cs
index 4e4f702fed..495649bd3e 100644
--- a/test/Microsoft.AspNetCore.Razor.Tools.Test/DefaultRequestDispatcherTest.cs
+++ b/test/Microsoft.AspNetCore.Razor.Tools.Test/DefaultRequestDispatcherTest.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Moq;
@@ -335,7 +336,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
///
/// Ensure server respects keep alive and shuts down after processing simultaneous connections.
///
- [Fact(Skip = "https://github.com/aspnet/Razor/issues/2018")]
+ [Fact]
public async Task Dispatcher_ProcessSimultaneousConnections_HitsKeepAliveTimeout()
{
// Arrange
@@ -352,6 +353,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
var source = new TaskCompletionSource();
var connectionTask = CreateConnectionWithEmptyServerRequest(c =>
{
+ // Keep the connection active until we decide to end it.
c.WaitForDisconnectAsyncFunc = _ => source.Task;
});
list.Add(source);
@@ -370,24 +372,42 @@ namespace Microsoft.AspNetCore.Razor.Tools
};
});
- var keepAlive = TimeSpan.FromSeconds(1);
var eventBus = new TestableEventBus();
+ var completedCompilations = 0;
+ var allCompilationsComplete = new TaskCompletionSource();
+ eventBus.CompilationComplete += (obj, args) =>
+ {
+ if (++completedCompilations == totalCount)
+ {
+ // All compilations have completed.
+ allCompilationsComplete.SetResult(true);
+ }
+ };
+ var keepAlive = TimeSpan.FromSeconds(1);
var dispatcherTask = Task.Run(() =>
{
var dispatcher = new DefaultRequestDispatcher(connectionHost.Object, compilerHost, CancellationToken.None, eventBus, keepAlive);
dispatcher.Run();
});
+ // Wait for all connections to be created.
await readySource.Task;
+
+ // Wait for all compilations to complete.
+ await allCompilationsComplete.Task;
+
+ // Now allow all the connections to be disconnected.
foreach (var source in list)
{
source.SetResult(true);
}
// Act
+ // Now dispatcher should be in an idle state with no active connections.
await dispatcherTask;
// Assert
+ Assert.False(eventBus.HasDetectedBadConnection);
Assert.Equal(totalCount, eventBus.CompletedCount);
Assert.True(eventBus.LastProcessedTime.HasValue, "LastProcessedTime should have had a value.");
Assert.True(eventBus.HitKeepAliveTimeout, "HitKeepAliveTimeout should have been hit.");
diff --git a/test/Microsoft.AspNetCore.Razor.Tools.Test/Infrastructure/TestableEventBus.cs b/test/Microsoft.AspNetCore.Razor.Tools.Test/Infrastructure/TestableEventBus.cs
index 4bc2465476..6430ce05df 100644
--- a/test/Microsoft.AspNetCore.Razor.Tools.Test/Infrastructure/TestableEventBus.cs
+++ b/test/Microsoft.AspNetCore.Razor.Tools.Test/Infrastructure/TestableEventBus.cs
@@ -2,21 +2,27 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Collections.Generic;
-using System.Text;
namespace Microsoft.AspNetCore.Razor.Tools
{
internal class TestableEventBus : EventBus
{
- public int ListeningCount;
- public int ConnectionCount;
- public int CompletedCount;
- public DateTime? LastProcessedTime;
- public TimeSpan? KeepAlive;
- public bool HasDetectedBadConnection;
- public bool HitKeepAliveTimeout;
public event EventHandler Listening;
+ public event EventHandler CompilationComplete;
+
+ public int ListeningCount { get; private set; }
+
+ public int ConnectionCount { get; private set; }
+
+ public int CompletedCount { get; private set; }
+
+ public DateTime? LastProcessedTime { get; private set; }
+
+ public TimeSpan? KeepAlive { get; private set; }
+
+ public bool HasDetectedBadConnection { get; private set; }
+
+ public bool HitKeepAliveTimeout { get; private set; }
public override void ConnectionListening()
{
@@ -35,6 +41,11 @@ namespace Microsoft.AspNetCore.Razor.Tools
LastProcessedTime = DateTime.Now;
}
+ public override void CompilationCompleted()
+ {
+ CompilationComplete?.Invoke(this, EventArgs.Empty);
+ }
+
public override void UpdateKeepAlive(TimeSpan timeSpan)
{
KeepAlive = timeSpan;
diff --git a/test/Microsoft.AspNetCore.Razor.Tools.Test/ServerLifecycleTest.cs b/test/Microsoft.AspNetCore.Razor.Tools.Test/ServerLifecycleTest.cs
index 7cb6b64ae0..3f415fe509 100644
--- a/test/Microsoft.AspNetCore.Razor.Tools.Test/ServerLifecycleTest.cs
+++ b/test/Microsoft.AspNetCore.Razor.Tools.Test/ServerLifecycleTest.cs
@@ -116,7 +116,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
/// A shutdown request should not abort an existing compilation. It should be allowed to run to
/// completion.
///
- [ConditionalFact(Skip = "Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991")]
+ // Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
+ [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public async Task ServerRunning_ShutdownRequest_DoesNotAbortCompilation()
{
@@ -153,7 +154,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
///
/// Multiple clients should be able to send shutdown requests to the server.
///
- [ConditionalFact(Skip = "Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991")]
+ // Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
+ [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public async Task ServerRunning_MultipleShutdownRequests_HandlesSuccessfully()
{
@@ -191,7 +193,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
}
}
- [ConditionalFact(Skip = "Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991")]
+ // Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
+ [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public async Task ServerRunning_CancelCompilation_CancelsSuccessfully()
{