Merge branch 'release/2.2'
This commit is contained in:
commit
3327267396
|
|
@ -96,7 +96,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
|||
return;
|
||||
}
|
||||
|
||||
_readTimingElapsedTicks += timestamp - _lastTimestamp;
|
||||
// Assume overly long tick intervals are the result of server resource starvation.
|
||||
// Don't count extra time between ticks against the rate limit.
|
||||
_readTimingElapsedTicks += Math.Min(timestamp - _lastTimestamp, Heartbeat.Interval.Ticks);
|
||||
|
||||
if (_minReadRate.BytesPerSecond > 0 && _readTimingElapsedTicks > _minReadRate.GracePeriod.Ticks)
|
||||
{
|
||||
|
|
@ -124,6 +126,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
|||
{
|
||||
lock (_writeTimingLock)
|
||||
{
|
||||
// Assume overly long tick intervals are the result of server resource starvation.
|
||||
// Don't count extra time between ticks against the rate limit.
|
||||
var extraTimeForTick = timestamp - _lastTimestamp - Heartbeat.Interval.Ticks;
|
||||
|
||||
if (extraTimeForTick > 0)
|
||||
{
|
||||
_writeTimingTimeoutTimestamp += extraTimeForTick;
|
||||
}
|
||||
|
||||
if (_concurrentAwaitingWrites > 0 && timestamp > _writeTimingTimeoutTimestamp && !Debugger.IsAttached)
|
||||
{
|
||||
_timeoutHandler.OnTimeout(TimeoutReason.WriteDataRate);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Moq;
|
||||
|
|
@ -13,11 +14,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
{
|
||||
private readonly Mock<ITimeoutHandler> _mockTimeoutHandler;
|
||||
private readonly TimeoutControl _timeoutControl;
|
||||
private readonly MockSystemClock _systemClock;
|
||||
|
||||
public TimeoutControlTests()
|
||||
{
|
||||
_mockTimeoutHandler = new Mock<ITimeoutHandler>();
|
||||
_timeoutControl = new TimeoutControl(_mockTimeoutHandler.Object);
|
||||
_systemClock = new MockSystemClock();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -28,7 +31,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_timeoutControl.Debugger = mockDebugger.Object;
|
||||
|
||||
var now = DateTimeOffset.Now;
|
||||
_timeoutControl.Tick(now);
|
||||
_timeoutControl.Initialize(now);
|
||||
_timeoutControl.SetTimeout(1, TimeoutReason.RequestHeaders);
|
||||
_timeoutControl.Tick(now.AddTicks(2).Add(Heartbeat.Interval));
|
||||
|
||||
|
|
@ -64,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
// Initialize timestamp
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
_timeoutControl.Tick(now);
|
||||
_timeoutControl.Initialize(now);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
|
@ -78,7 +81,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Tick after grace period w/ low data rate
|
||||
now += TimeSpan.FromSeconds(2);
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(now);
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(10);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
|
|
@ -94,13 +99,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
// Initialize timestamp
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
_timeoutControl.Tick(now);
|
||||
_timeoutControl.Initialize(now);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
// Set base data rate to 200 bytes/second
|
||||
now += gracePeriod;
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(now);
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(400);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
|
|
@ -149,49 +156,54 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
[Fact]
|
||||
public void RequestBodyDataRateNotComputedOnPausedTime()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
// Initialize timestamp
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_timeoutControl.Initialize(_systemClock.UtcNow);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
// Tick at 3s, expected counted time is 3s, expected data rate is 200 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(3);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(600);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Pause at 3.5s
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_timeoutControl.StopTimingRead();
|
||||
|
||||
// Tick at 4s, expected counted time is 4s (first tick after pause goes through), expected data rate is 150 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Tick at 6s, expected counted time is 4s, expected data rate is 150 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(2);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(2);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Resume at 6.5s
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
// Tick at 9s, expected counted time is 6s, expected data rate is 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1.5);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1.0);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(.5);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Tick at 10s, expected counted time is 7s, expected data rate drops below 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
|
|
@ -200,42 +212,43 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
[Fact]
|
||||
public void ReadTimingNotPausedWhenResumeCalledBeforeNextTick()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
// Initialize timestamp
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_timeoutControl.Initialize(_systemClock.UtcNow);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
// Tick at 2s, expected counted time is 2s, expected data rate is 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(2);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
_timeoutControl.BytesRead(200);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
|
||||
// Not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Pause at 2.25s
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.25);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(0.25);
|
||||
_timeoutControl.StopTimingRead();
|
||||
|
||||
// Resume at 2.5s
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.25);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(0.25);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
// Tick at 3s, expected counted time is 3s, expected data rate is 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(0.5);
|
||||
_timeoutControl.BytesRead(100);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Tick at 4s, expected counted time is 4s, expected data rate drops below 100 bytes/second
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
|
|
@ -244,14 +257,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
[Fact]
|
||||
public void ReadTimingNotEnforcedWhenTimeoutIsSet()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
var timeout = TimeSpan.FromSeconds(5);
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
var startTime = systemClock.UtcNow;
|
||||
var startTime = _systemClock.UtcNow;
|
||||
|
||||
// Initialize timestamp
|
||||
_timeoutControl.Tick(startTime);
|
||||
_timeoutControl.Initialize(startTime);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
|
@ -259,37 +271,122 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_timeoutControl.SetTimeout(timeout.Ticks, TimeoutReason.RequestBodyDrain);
|
||||
|
||||
// Tick beyond grace period with low data rate
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(3);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(3);
|
||||
_timeoutControl.BytesRead(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Tick just past timeout period, adjusted by Heartbeat.Interval
|
||||
systemClock.UtcNow = startTime + timeout + Heartbeat.Interval + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_systemClock.UtcNow = startTime + timeout + Heartbeat.Interval + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
// Timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.RequestBodyDrain), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTimingAbortsConnectionWhenWriteDoesNotCompleteWithMinimumDataRate()
|
||||
public void ReadTimingNotEnforcedWhenLowConnectionInputFlowControlAvailability()
|
||||
{
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
var flowControl = new InputFlowControl(initialWindowSize: 2, minWindowSizeIncrement: 1);
|
||||
|
||||
// Initialize timestamp
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
_timeoutControl.Initialize(now);
|
||||
_timeoutControl.InitializeHttp2(flowControl);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
// Tick past grace period
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(100);
|
||||
_timeoutControl.Tick(now);
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(100);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
// Induce low flow control availability
|
||||
flowControl.TryAdvance(2);
|
||||
|
||||
// Read 0 bytes in 1 second
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
// Not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Relieve low flow control availability
|
||||
flowControl.TryUpdateWindow(2, out _);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
// Still not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Read 0 bytes in 1 second
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(now);;
|
||||
|
||||
// Timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTimingOnlyCountsUpToOneHeartbeatIntervalPerTick()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
// Initialize timestamp
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
_timeoutControl.Initialize(now);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
// Tick past grace period
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(100);
|
||||
_timeoutControl.Tick(now);
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(100);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
// Read 100 bytes in 2 seconds with a single tick
|
||||
now += TimeSpan.FromSeconds(2);
|
||||
_timeoutControl.BytesRead(100);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
// Not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Read 100 bytes in 2 seconds in two ticks
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(100);
|
||||
_timeoutControl.Tick(now);
|
||||
now += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(now);
|
||||
|
||||
// Timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTimingAbortsConnectionWhenWriteDoesNotCompleteWithMinimumDataRate()
|
||||
{
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
// Initialize timestamp
|
||||
_timeoutControl.Initialize(_systemClock.UtcNow);
|
||||
|
||||
// Should complete within 4 seconds, but the timeout is adjusted by adding Heartbeat.Interval
|
||||
_timeoutControl.BytesWrittenToBuffer(minRate, 400);
|
||||
_timeoutControl.StartTimingWrite();
|
||||
|
||||
// Tick just past 4s plus Heartbeat.Interval
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(4) + Heartbeat.Interval + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(4) + Heartbeat.Interval + TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
}
|
||||
|
|
@ -297,40 +394,35 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
[Fact]
|
||||
public void WriteTimingAbortsConnectionWhenSmallWriteDoesNotCompleteWithinGracePeriod()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(5));
|
||||
|
||||
// Initialize timestamp
|
||||
var startTime = systemClock.UtcNow;
|
||||
_timeoutControl.Tick(startTime);
|
||||
var startTime = _systemClock.UtcNow;
|
||||
_timeoutControl.Initialize(startTime);
|
||||
|
||||
// Should complete within 1 second, but the timeout is adjusted by adding Heartbeat.Interval
|
||||
_timeoutControl.BytesWrittenToBuffer(minRate, 100);
|
||||
_timeoutControl.StartTimingWrite();
|
||||
|
||||
// Tick just past 1s plus Heartbeat.Interval
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(1) + Heartbeat.Interval + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1) + Heartbeat.Interval + TimeSpan.FromTicks(1));
|
||||
|
||||
// Still within grace period, not timed out
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// Tick just past grace period (adjusted by Heartbeat.Interval)
|
||||
systemClock.UtcNow = startTime + minRate.GracePeriod + Heartbeat.Interval + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
AdvanceClock(minRate.GracePeriod - TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void WriteTimingTimeoutPushedOnConcurrentWrite()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
// Initialize timestamp
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_timeoutControl.Initialize(_systemClock.UtcNow);
|
||||
|
||||
// Should complete within 5 seconds, but the timeout is adjusted by adding Heartbeat.Interval
|
||||
_timeoutControl.BytesWrittenToBuffer(minRate, 500);
|
||||
|
|
@ -341,8 +433,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_timeoutControl.StartTimingWrite();
|
||||
|
||||
// Tick just past 5s plus Heartbeat.Interval, when the first write should have completed
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(5) + Heartbeat.Interval + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(5) + Heartbeat.Interval + TimeSpan.FromTicks(1));
|
||||
|
||||
// Not timed out because the timeout was pushed by the second write
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
|
@ -351,8 +442,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_timeoutControl.StopTimingWrite();
|
||||
|
||||
// Tick just past +3s, when the second write should have completed
|
||||
systemClock.UtcNow += TimeSpan.FromSeconds(3) + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(3));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
}
|
||||
|
|
@ -360,14 +450,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
[Fact]
|
||||
public void WriteTimingAbortsConnectionWhenRepeatedSmallWritesDoNotCompleteWithMinimumDataRate()
|
||||
{
|
||||
var systemClock = new MockSystemClock();
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(5));
|
||||
var numWrites = 5;
|
||||
var writeSize = 100;
|
||||
|
||||
// Initialize timestamp
|
||||
var startTime = systemClock.UtcNow;
|
||||
_timeoutControl.Tick(startTime);
|
||||
var startTime = _systemClock.UtcNow;
|
||||
_timeoutControl.Initialize(startTime);
|
||||
|
||||
// 5 consecutive 100 byte writes.
|
||||
for (var i = 0; i < numWrites - 1; i++)
|
||||
|
|
@ -381,14 +470,37 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
// Move the clock forward Heartbeat.Interval + MinDataRate.GracePeriod + 4 seconds.
|
||||
// The grace period should only be added for the first write. The subsequent 4 100 byte writes should add 1 second each to the timeout given the 100 byte/s min rate.
|
||||
systemClock.UtcNow += Heartbeat.Interval + minRate.GracePeriod + TimeSpan.FromSeconds((numWrites - 1) * writeSize / minRate.BytesPerSecond);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
AdvanceClock(Heartbeat.Interval + minRate.GracePeriod + TimeSpan.FromSeconds((numWrites - 1) * writeSize / minRate.BytesPerSecond));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
// On more tick forward triggers the timeout.
|
||||
systemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(systemClock.UtcNow);
|
||||
_systemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTimingOnlyCountsUpToOneHeartbeatIntervalPerTick()
|
||||
{
|
||||
var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2));
|
||||
|
||||
// Initialize timestamp
|
||||
_timeoutControl.Initialize(_systemClock.UtcNow);
|
||||
|
||||
// Should complete within 4 seconds, but the timeout is adjusted by adding Heartbeat.Interval
|
||||
_timeoutControl.BytesWrittenToBuffer(minRate, 400);
|
||||
_timeoutControl.StartTimingWrite();
|
||||
|
||||
// Tick just past 4s plus Heartbeat.Interval at once
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(4) + Heartbeat.Interval + TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Never);
|
||||
|
||||
// The last Tick only accounted for one heartbeat interval. Try again with a tick per interval.
|
||||
AdvanceClock(TimeSpan.FromSeconds(4) + TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
}
|
||||
|
|
@ -400,16 +512,31 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
var minRate = new MinDataRate(bytesPerSecond, gracePeriod);
|
||||
|
||||
// Initialize timestamp
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
_timeoutControl.Tick(now);
|
||||
_timeoutControl.Initialize(_systemClock.UtcNow);
|
||||
|
||||
_timeoutControl.StartRequestBody(minRate);
|
||||
_timeoutControl.StartTimingRead();
|
||||
|
||||
AdvanceClock(gracePeriod);
|
||||
|
||||
// Tick after grace period w/ low data rate
|
||||
now += gracePeriod + TimeSpan.FromSeconds(1);
|
||||
_systemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.BytesRead(1);
|
||||
_timeoutControl.Tick(now);
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
}
|
||||
|
||||
private void AdvanceClock(TimeSpan timeSpan)
|
||||
{
|
||||
var endTime = _systemClock.UtcNow + timeSpan;
|
||||
|
||||
while (_systemClock.UtcNow + Heartbeat.Interval < endTime)
|
||||
{
|
||||
_systemClock.UtcNow += Heartbeat.Interval;
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
}
|
||||
|
||||
_systemClock.UtcNow = endTime;
|
||||
_timeoutControl.Tick(_systemClock.UtcNow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1160,6 +1160,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
}
|
||||
}
|
||||
|
||||
protected void AdvanceClock(TimeSpan timeSpan)
|
||||
{
|
||||
var clock = _serviceContext.MockSystemClock;
|
||||
var endTime = clock.UtcNow + timeSpan;
|
||||
|
||||
while (clock.UtcNow + Heartbeat.Interval < endTime)
|
||||
{
|
||||
clock.UtcNow += Heartbeat.Interval;
|
||||
_timeoutControl.Tick(clock.UtcNow);
|
||||
}
|
||||
|
||||
clock.UtcNow = endTime;
|
||||
_timeoutControl.Tick(clock.UtcNow);
|
||||
}
|
||||
|
||||
public class Http2FrameWithPayload : Http2Frame
|
||||
{
|
||||
public Http2FrameWithPayload() : base()
|
||||
|
|
|
|||
|
|
@ -30,13 +30,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
_connectionTask = _connection.ProcessRequestsAsync(new DummyApplication(_noopApplication));
|
||||
|
||||
mockSystemClock.UtcNow += limits.KeepAliveTimeout + Heartbeat.Interval;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(limits.KeepAliveTimeout + Heartbeat.Interval);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.KeepAlive), Times.Once);
|
||||
|
||||
|
|
@ -55,13 +53,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
await InitializeConnectionAsync(_noopApplication);
|
||||
|
||||
mockSystemClock.UtcNow += limits.KeepAliveTimeout + Heartbeat.Interval;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(limits.KeepAliveTimeout + Heartbeat.Interval);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.KeepAlive), Times.Once);
|
||||
|
||||
|
|
@ -80,8 +76,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
await InitializeConnectionAsync(_noopApplication);
|
||||
|
||||
mockSystemClock.UtcNow += limits.KeepAliveTimeout + Heartbeat.Interval;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(limits.KeepAliveTimeout + Heartbeat.Interval);
|
||||
|
||||
// keep-alive timeout set but not fired.
|
||||
_mockTimeoutControl.Verify(c => c.SetTimeout(It.IsAny<long>(), TimeoutReason.KeepAlive), Times.Once);
|
||||
|
|
@ -113,13 +108,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
await setTimeoutTcs.Task.DefaultTimeout();
|
||||
|
||||
mockSystemClock.UtcNow += limits.KeepAliveTimeout + Heartbeat.Interval;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(limits.KeepAliveTimeout + Heartbeat.Interval);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.KeepAlive), Times.Once);
|
||||
|
||||
|
|
@ -142,15 +135,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
await SendEmptyContinuationFrameAsync(1, Http2ContinuationFrameFlags.NONE);
|
||||
|
||||
mockSystemClock.UtcNow += limits.RequestHeadersTimeout + Heartbeat.Interval;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(limits.RequestHeadersTimeout + Heartbeat.Interval);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
await SendEmptyContinuationFrameAsync(1, Http2ContinuationFrameFlags.NONE);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.RequestHeaders), Times.Once);
|
||||
|
||||
|
|
@ -181,17 +172,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
await WaitForConnectionStopAsync(expectedLastStreamId: 0, ignoreNonGoAwayFrames: false);
|
||||
|
||||
mockSystemClock.UtcNow +=
|
||||
TimeSpan.FromSeconds(_bytesReceived / limits.MinResponseDataRate.BytesPerSecond) +
|
||||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(_bytesReceived / limits.MinResponseDataRate.BytesPerSecond) +
|
||||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
_mockConnectionContext.Verify(c => c.Abort(It.IsAny<ConnectionAbortedException>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
|
||||
|
|
@ -285,16 +272,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
|
||||
// Don't read data frame to induce "socket" backpressure.
|
||||
mockSystemClock.UtcNow +=
|
||||
TimeSpan.FromSeconds((_bytesReceived + _helloWorldBytes.Length) / limits.MinResponseDataRate.BytesPerSecond) +
|
||||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds((_bytesReceived + _helloWorldBytes.Length) / limits.MinResponseDataRate.BytesPerSecond) +
|
||||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
|
||||
|
|
@ -348,13 +331,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
|
||||
// Don't read data frame to induce "socket" backpressure.
|
||||
mockSystemClock.UtcNow += timeToWriteMaxData;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(timeToWriteMaxData);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
|
||||
|
|
@ -409,16 +390,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
|
||||
// Don't send WINDOW_UPDATE to induce flow-control backpressure
|
||||
mockSystemClock.UtcNow +=
|
||||
TimeSpan.FromSeconds(_bytesReceived / limits.MinResponseDataRate.BytesPerSecond) +
|
||||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(_bytesReceived / limits.MinResponseDataRate.BytesPerSecond) +
|
||||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
|
||||
|
|
@ -470,13 +447,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
|
||||
// Don't send WINDOW_UPDATE to induce flow-control backpressure
|
||||
mockSystemClock.UtcNow += timeToWriteMaxData;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(timeToWriteMaxData);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
|
||||
|
|
@ -540,14 +515,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
limits.MinResponseDataRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
|
||||
// Don't send WINDOW_UPDATE to induce flow-control backpressure
|
||||
mockSystemClock.UtcNow += timeToWriteMaxData;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(timeToWriteMaxData);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
//mockSystemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once);
|
||||
|
||||
|
|
@ -592,13 +564,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
withStreamId: 1);
|
||||
|
||||
// Don't send any more data and advance just to and then past the grace period.
|
||||
mockSystemClock.UtcNow += limits.MinRequestBodyDataRate.GracePeriod;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(limits.MinRequestBodyDataRate.GracePeriod);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
|
||||
|
|
@ -647,13 +617,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
var timeToReadMaxData = TimeSpan.FromSeconds(_maxData.Length / limits.MinRequestBodyDataRate.BytesPerSecond) - TimeSpan.FromSeconds(.5);
|
||||
|
||||
// Don't send any more data and advance just to and then past the rate timeout.
|
||||
mockSystemClock.UtcNow += timeToReadMaxData;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(timeToReadMaxData);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
|
||||
|
|
@ -718,13 +686,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
timeToReadMaxData -= TimeSpan.FromSeconds(.5);
|
||||
|
||||
// Don't send any more data and advance just to and then past the rate timeout.
|
||||
mockSystemClock.UtcNow += timeToReadMaxData;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(timeToReadMaxData);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
|
||||
|
|
@ -790,13 +756,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
var timeToReadMaxData = TimeSpan.FromSeconds(_maxData.Length / limits.MinRequestBodyDataRate.BytesPerSecond) - TimeSpan.FromSeconds(.5);
|
||||
|
||||
// Don't send any more data and advance just to and then past the rate timeout.
|
||||
mockSystemClock.UtcNow += timeToReadMaxData;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(timeToReadMaxData);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromSeconds(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
|
||||
|
|
@ -863,8 +827,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
withStreamId: 3);
|
||||
|
||||
// No matter how much time elapses there is no read timeout because the connection window is too small.
|
||||
mockSystemClock.UtcNow += TimeSpan.FromDays(365);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromDays(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
|
|
@ -885,13 +848,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
withFlags: (byte)Http2DataFrameFlags.NONE,
|
||||
withStreamId: 0);
|
||||
|
||||
mockSystemClock.UtcNow += limits.MinRequestBodyDataRate.GracePeriod;
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(limits.MinRequestBodyDataRate.GracePeriod);
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny<TimeoutReason>()), Times.Never);
|
||||
|
||||
mockSystemClock.UtcNow += TimeSpan.FromTicks(1);
|
||||
_timeoutControl.Tick(mockSystemClock.UtcNow);
|
||||
AdvanceClock(TimeSpan.FromTicks(1));
|
||||
|
||||
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,8 +71,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
|
||||
await appRunningEvent.Task.DefaultTimeout();
|
||||
|
||||
serviceContext.MockSystemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1);
|
||||
heartbeatManager.OnHeartbeat(serviceContext.SystemClock.UtcNow);
|
||||
// Advance the clock gracePeriod + TimeSpan.FromSeconds(1)
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
serviceContext.MockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
heartbeatManager.OnHeartbeat(serviceContext.SystemClock.UtcNow);
|
||||
}
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 408 Request Timeout",
|
||||
|
|
@ -184,8 +188,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
|
||||
await appRunningTcs.Task.DefaultTimeout();
|
||||
|
||||
serviceContext.MockSystemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1);
|
||||
heartbeatManager.OnHeartbeat(serviceContext.SystemClock.UtcNow);
|
||||
// Advance the clock gracePeriod + TimeSpan.FromSeconds(1)
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
serviceContext.MockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
heartbeatManager.OnHeartbeat(serviceContext.SystemClock.UtcNow);
|
||||
}
|
||||
|
||||
await exceptionSwallowedTcs.Task.DefaultTimeout();
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
// Wait for the drain timeout to be set.
|
||||
await outputBufferedTcs.Task.DefaultTimeout();
|
||||
|
||||
testContext.MockSystemClock.UtcNow += minRate.GracePeriod + Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
// Advance the clock to the grace period
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
testContext.MockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
|
||||
heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
|
||||
}
|
||||
|
||||
testContext.MockSystemClock.UtcNow += Heartbeat.Interval - TimeSpan.FromSeconds(.5);
|
||||
heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
|
||||
|
||||
Assert.Null(transportConnection.AbortReason);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ namespace Interop.FunctionalTests
|
|||
$"--no-sandbox " +
|
||||
$"--disable-gpu " +
|
||||
$"--allow-insecure-localhost " +
|
||||
$"--ignore-certificate-errors --enable-features=NetworkService " +
|
||||
$"--enable-logging " +
|
||||
$"--dump-dom " +
|
||||
$"--virtual-time-budget=10000 " +
|
||||
|
|
|
|||
Loading…
Reference in New Issue