Don't block so many threads in HeartbeatTests (#2610)
This commit is contained in:
parent
cf684a1e8f
commit
f70088c2d9
|
|
@ -22,58 +22,73 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BlockedHeartbeatDoesntCauseOverlapsAndIsLoggedAsError()
|
public async Task BlockedHeartbeatDoesntCauseOverlapsAndIsLoggedAsError()
|
||||||
{
|
{
|
||||||
var systemClock = new MockSystemClock();
|
var systemClock = new MockSystemClock();
|
||||||
var heartbeatHandler = new Mock<IHeartbeatHandler>();
|
var heartbeatHandler = new Mock<IHeartbeatHandler>();
|
||||||
var debugger = new Mock<IDebugger>();
|
var debugger = new Mock<IDebugger>();
|
||||||
var kestrelTrace = new Mock<IKestrelTrace>();
|
var kestrelTrace = new Mock<IKestrelTrace>();
|
||||||
var handlerMre = new ManualResetEventSlim();
|
var handlerMre = new ManualResetEventSlim();
|
||||||
var traceMre = new ManualResetEventSlim();
|
var handlerStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var onHeartbeatTasks = new Task[2];
|
|
||||||
|
|
||||||
heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() => handlerMre.Wait());
|
heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() =>
|
||||||
|
{
|
||||||
|
handlerStartedTcs.SetResult(null);
|
||||||
|
handlerMre.Wait();
|
||||||
|
});
|
||||||
debugger.Setup(d => d.IsAttached).Returns(false);
|
debugger.Setup(d => d.IsAttached).Returns(false);
|
||||||
kestrelTrace.Setup(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow)).Callback(() => traceMre.Set());
|
|
||||||
|
Task blockedHeartbeatTask;
|
||||||
|
|
||||||
using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, debugger.Object, kestrelTrace.Object))
|
using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, debugger.Object, kestrelTrace.Object))
|
||||||
{
|
{
|
||||||
onHeartbeatTasks[0] = Task.Run(() => heartbeat.OnHeartbeat());
|
blockedHeartbeatTask = Task.Run(() => heartbeat.OnHeartbeat());
|
||||||
onHeartbeatTasks[1] = Task.Run(() => heartbeat.OnHeartbeat());
|
|
||||||
Assert.True(traceMre.Wait(TimeSpan.FromSeconds(10)));
|
await handlerStartedTcs.Task.DefaultTimeout();
|
||||||
|
|
||||||
|
heartbeat.OnHeartbeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
handlerMre.Set();
|
handlerMre.Set();
|
||||||
Task.WaitAll(onHeartbeatTasks);
|
|
||||||
|
await blockedHeartbeatTask.DefaultTimeout();
|
||||||
|
|
||||||
heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once());
|
heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once());
|
||||||
kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Once());
|
kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BlockedHeartbeatIsNotLoggedAsErrorIfDebuggerAttached()
|
public async Task BlockedHeartbeatIsNotLoggedAsErrorIfDebuggerAttached()
|
||||||
{
|
{
|
||||||
var systemClock = new MockSystemClock();
|
var systemClock = new MockSystemClock();
|
||||||
var heartbeatHandler = new Mock<IHeartbeatHandler>();
|
var heartbeatHandler = new Mock<IHeartbeatHandler>();
|
||||||
var debugger = new Mock<IDebugger>();
|
var debugger = new Mock<IDebugger>();
|
||||||
var kestrelTrace = new Mock<IKestrelTrace>();
|
var kestrelTrace = new Mock<IKestrelTrace>();
|
||||||
var handlerMre = new ManualResetEventSlim();
|
var handlerMre = new ManualResetEventSlim();
|
||||||
var traceMre = new ManualResetEventSlim();
|
var handlerStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var onHeartbeatTasks = new Task[2];
|
|
||||||
|
|
||||||
heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() => handlerMre.Wait());
|
heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() =>
|
||||||
debugger.Setup(d => d.IsAttached).Returns(true);
|
|
||||||
kestrelTrace.Setup(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow)).Callback(() => traceMre.Set());
|
|
||||||
|
|
||||||
using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, debugger.Object, kestrelTrace.Object, TimeSpan.FromSeconds(0.01)))
|
|
||||||
{
|
{
|
||||||
onHeartbeatTasks[0] = Task.Run(() => heartbeat.OnHeartbeat());
|
handlerStartedTcs.SetResult(null);
|
||||||
onHeartbeatTasks[1] = Task.Run(() => heartbeat.OnHeartbeat());
|
handlerMre.Wait();
|
||||||
Assert.False(traceMre.Wait(TimeSpan.FromSeconds(2)));
|
});
|
||||||
|
|
||||||
|
debugger.Setup(d => d.IsAttached).Returns(true);
|
||||||
|
|
||||||
|
Task blockedHeartbeatTask;
|
||||||
|
|
||||||
|
using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, debugger.Object, kestrelTrace.Object))
|
||||||
|
{
|
||||||
|
blockedHeartbeatTask = Task.Run(() => heartbeat.OnHeartbeat());
|
||||||
|
|
||||||
|
await handlerStartedTcs.Task.DefaultTimeout();
|
||||||
|
|
||||||
|
heartbeat.OnHeartbeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
handlerMre.Set();
|
handlerMre.Set();
|
||||||
Task.WaitAll(onHeartbeatTasks);
|
|
||||||
|
await blockedHeartbeatTask.DefaultTimeout();
|
||||||
|
|
||||||
heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once());
|
heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once());
|
||||||
kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Never());
|
kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Never());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue