public void BlockedHeartbeatDoesntCauseOverlapsAndIsLoggedAsError() { var systemClock = new MockSystemClock(); var heartbeatHandler = new Mock <IHeartbeatHandler>(); var debugger = new Mock <IDebugger>(); var kestrelTrace = new Mock <IKestrelTrace>(); var handlerMre = new ManualResetEventSlim(); var traceMre = new ManualResetEventSlim(); var onHeartbeatTasks = new Task[2]; heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() => handlerMre.Wait()); debugger.Setup(d => d.IsAttached).Returns(false); 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)) { onHeartbeatTasks[0] = Task.Run(() => heartbeat.OnHeartbeat()); onHeartbeatTasks[1] = Task.Run(() => heartbeat.OnHeartbeat()); Assert.True(traceMre.Wait(TimeSpan.FromSeconds(10))); } handlerMre.Set(); Task.WaitAll(onHeartbeatTasks); heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once()); kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Once()); }
public async Task GetDateHeaderValue_ReturnsUpdatedValueAfterIdle() { var now = DateTimeOffset.UtcNow; var future = now.AddSeconds(10); var systemClock = new MockSystemClock { UtcNow = now }; var timeWithoutRequestsUntilIdle = TimeSpan.FromMilliseconds(250); var timerInterval = TimeSpan.FromMilliseconds(100); var dateHeaderValueManager = new DateHeaderValueManager(systemClock, timeWithoutRequestsUntilIdle, timerInterval); string result1; string result2; try { result1 = dateHeaderValueManager.GetDateHeaderValue(); systemClock.UtcNow = future; // Wait for longer than the idle timeout to ensure the timer is stopped await Task.Delay(TimeSpan.FromSeconds(1)); result2 = dateHeaderValueManager.GetDateHeaderValue(); } finally { dateHeaderValueManager.Dispose(); } Assert.Equal(now.ToString(Constants.RFC1123DateFormat), result1); Assert.Equal(future.ToString(Constants.RFC1123DateFormat), result2); Assert.True(systemClock.UtcNowCalled >= 2); }
public void ReadTimingNotPausedWhenResumeCalledBeforeNextTick() { var systemClock = new MockSystemClock(); _httpConnectionContext.ServiceContext.ServerOptions.Limits.MinRequestBodyDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2)); _httpConnectionContext.ServiceContext.SystemClock = systemClock; var mockLogger = new Mock <IKestrelTrace>(); _httpConnectionContext.ServiceContext.Log = mockLogger.Object; _httpConnection.Initialize(_httpConnectionContext.Transport); _httpConnection.Http1Connection.Reset(); // Initialize timestamp _httpConnection.Tick(systemClock.UtcNow); _httpConnection.StartTimingReads(); // Tick at 2s, expected counted time is 2s, expected data rate is 100 bytes/second systemClock.UtcNow += TimeSpan.FromSeconds(2); _httpConnection.BytesRead(200); _httpConnection.Tick(systemClock.UtcNow); // Not timed out Assert.False(_httpConnection.RequestTimedOut); mockLogger.Verify( logger => logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <double>()), Times.Never); // Pause at 2.25s systemClock.UtcNow += TimeSpan.FromSeconds(0.25); _httpConnection.PauseTimingReads(); // Resume at 2.5s systemClock.UtcNow += TimeSpan.FromSeconds(0.25); _httpConnection.ResumeTimingReads(); // Tick at 3s, expected counted time is 3s, expected data rate is 100 bytes/second systemClock.UtcNow += TimeSpan.FromSeconds(0.5); _httpConnection.BytesRead(100); _httpConnection.Tick(systemClock.UtcNow); // Not timed out Assert.False(_httpConnection.RequestTimedOut); mockLogger.Verify( logger => logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <double>()), Times.Never); // Tick at 4s, expected counted time is 4s, expected data rate drops below 100 bytes/second systemClock.UtcNow += TimeSpan.FromSeconds(1); _httpConnection.Tick(systemClock.UtcNow); // Timed out Assert.True(_httpConnection.RequestTimedOut); mockLogger.Verify( logger => logger.RequestBodyMininumDataRateNotSatisfied(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <double>()), Times.Once); }
public async Task WriteTimingAbortsConnectionWhenWriteDoesNotCompleteWithMinimumDataRate() { var systemClock = new MockSystemClock(); var aborted = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); _httpConnectionContext.ServiceContext.ServerOptions.Limits.MinResponseDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2)); _httpConnectionContext.ServiceContext.SystemClock = systemClock; var mockLogger = new Mock <IKestrelTrace>(); _httpConnectionContext.ServiceContext.Log = mockLogger.Object; _httpConnection.Initialize(_httpConnectionContext.Transport); _httpConnection.Http1Connection.Reset(); _httpConnection.Http1Connection.RequestAborted.Register(() => { aborted.SetResult(null); }); // Initialize timestamp _httpConnection.Tick(systemClock.UtcNow); // Should complete within 4 seconds, but the timeout is adjusted by adding Heartbeat.Interval _httpConnection.StartTimingWrite(400); // Tick just past 4s plus Heartbeat.Interval systemClock.UtcNow += TimeSpan.FromSeconds(4) + Heartbeat.Interval + TimeSpan.FromTicks(1); _httpConnection.Tick(systemClock.UtcNow); Assert.True(_httpConnection.RequestTimedOut); await aborted.Task.DefaultTimeout(); }
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); // 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); // 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); _mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once); }
public void WriteTimingAbortsConnectionWhenWriteDoesNotCompleteWithMinimumDataRate() { var systemClock = new MockSystemClock(); var aborted = new ManualResetEventSlim(); _httpConnectionContext.ServiceContext.ServerOptions.Limits.MinResponseDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2)); _httpConnectionContext.ServiceContext.SystemClock = systemClock; var mockLogger = new Mock <IKestrelTrace>(); _httpConnectionContext.ServiceContext.Log = mockLogger.Object; _httpConnection.Initialize(_httpConnectionContext.Transport, _httpConnectionContext.Application); _httpConnection.Http1Connection.Reset(); _httpConnection.Http1Connection.RequestAborted.Register(() => { aborted.Set(); }); // Initialize timestamp _httpConnection.Tick(systemClock.UtcNow); // Should complete within 4 seconds, but the timeout is adjusted by adding Heartbeat.Interval _httpConnection.StartTimingWrite(400); // Tick just past 4s plus Heartbeat.Interval systemClock.UtcNow += TimeSpan.FromSeconds(4) + Heartbeat.Interval + TimeSpan.FromTicks(1); _httpConnection.Tick(systemClock.UtcNow); Assert.True(_httpConnection.RequestTimedOut); Assert.True(aborted.Wait(TimeSpan.FromSeconds(10))); }
public void WriteTimingTimeoutPushedOnConcurrentWrite() { var systemClock = new MockSystemClock(); var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2)); // Initialize timestamp _timeoutControl.Tick(systemClock.UtcNow); // Should complete within 5 seconds, but the timeout is adjusted by adding Heartbeat.Interval _timeoutControl.BytesWrittenToBuffer(minRate, 500); _timeoutControl.StartTimingWrite(); // Start a concurrent write after 3 seconds, which should complete within 3 seconds (adjusted by Heartbeat.Interval) _timeoutControl.BytesWrittenToBuffer(minRate, 300); _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); // Not timed out because the timeout was pushed by the second write _mockTimeoutHandler.Verify(h => h.OnTimeout(It.IsAny <TimeoutReason>()), Times.Never); // Complete the first write, this should have no effect on the timeout _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); _mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once); }
public void GetDateHeaderValue_ReturnsUpdatedValueAfterHeartbeat() { var now = DateTimeOffset.UtcNow; var future = now.AddSeconds(10); var systemClock = new MockSystemClock { UtcNow = now }; var dateHeaderValueManager = new DateHeaderValueManager(); dateHeaderValueManager.OnHeartbeat(now); var testKestrelTrace = new KestrelTrace(NullLoggerFactory.Instance); var mockHeartbeatHandler = new Mock <IHeartbeatHandler>(); using (var heartbeat = new Heartbeat(new[] { dateHeaderValueManager, mockHeartbeatHandler.Object }, systemClock, DebuggerWrapper.Singleton, testKestrelTrace)) { heartbeat.OnHeartbeat(); Assert.Equal(now.ToString(Rfc1123DateFormat), dateHeaderValueManager.GetDateHeaderValues().String); // Wait for the next heartbeat before verifying GetDateHeaderValues picks up new time. systemClock.UtcNow = future; heartbeat.OnHeartbeat(); Assert.Equal(future.ToString(Rfc1123DateFormat), dateHeaderValueManager.GetDateHeaderValues().String); Assert.Equal(4, systemClock.UtcNowCalled); } }
public void BlockedHeartbeatIsNotLoggedAsErrorIfDebuggerAttached() { var systemClock = new MockSystemClock(); var heartbeatHandler = new Mock <IHeartbeatHandler>(); var debugger = new Mock <IDebugger>(); var kestrelTrace = new Mock <IKestrelTrace>(); var handlerMre = new ManualResetEventSlim(); var traceMre = new ManualResetEventSlim(); heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() => handlerMre.Wait()); 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)) { Task.Run(() => heartbeat.OnHeartbeat()); Task.Run(() => heartbeat.OnHeartbeat()); Assert.False(traceMre.Wait(TimeSpan.FromSeconds(10))); } handlerMre.Set(); heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once()); kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Never()); }
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); // 5 consecutive 100 byte writes. for (var i = 0; i < numWrites - 1; i++) { _timeoutControl.BytesWrittenToBuffer(minRate, writeSize); } // Stall the last write. _timeoutControl.BytesWrittenToBuffer(minRate, writeSize); _timeoutControl.StartTimingWrite(); // 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); _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); _mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.WriteDataRate), Times.Once); }
public async Task SuccessiveTryAdd() { var clock = new MockSystemClock(); var store = new DefaultMemoryQosCounterStore(clock); var result = await store.TryAddAsync("a", 3, 6, TimeSpan.FromSeconds(1)); Assert.True(result.Success); Assert.Equal(3, result.NewCounter); result = await store.TryAddAsync("a", 2, 6, TimeSpan.FromSeconds(500)); // The period must be ignored Assert.True(result.Success); Assert.Equal(5, result.NewCounter); result = await store.TryAddAsync("a", 1, 6, TimeSpan.FromSeconds(500)); Assert.True(result.Success); Assert.Equal(6, result.NewCounter); result = await store.TryAddAsync("a", 1, 6, TimeSpan.FromSeconds(500)); Assert.False(result.Success); Assert.Equal(6, result.NewCounter); clock.UtcNow += TimeSpan.FromSeconds(100); result = await store.TryAddAsync("a", 3, 6, TimeSpan.FromSeconds(1)); Assert.True(result.Success); Assert.Equal(3, result.NewCounter); }
public async Task BlockedHeartbeatIsNotLoggedAsErrorIfDebuggerAttached() { var systemClock = new MockSystemClock(); var heartbeatHandler = new Mock <IHeartbeatHandler>(); var debugger = new Mock <IDebugger>(); var kestrelTrace = new Mock <IKestrelTrace>(); var handlerMre = new ManualResetEventSlim(); var handlerStartedTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() => { handlerStartedTcs.SetResult(null); handlerMre.Wait(); }); 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(); await blockedHeartbeatTask.DefaultTimeout(); heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once()); kestrelTrace.Verify(t => t.HeartbeatSlow(TimeSpan.Zero, Heartbeat.Interval, systemClock.UtcNow), Times.Never()); }
public async Task CleanObsoleteEntries() { var clock = new MockSystemClock(); var store = new DefaultMemoryQosCounterStore(clock); for (int i = 0; i < 30; i++) { await store.AddAsync(i.ToString(), 3, TimeSpan.FromSeconds(i)); } Assert.Equal(30, store.Count); clock.Callbacks.First().Invoke(); Assert.Equal(30, store.Count); clock.UtcNow += TimeSpan.FromSeconds(14); clock.Callbacks.First().Invoke(); Assert.Equal(16, store.Count); clock.UtcNow += TimeSpan.FromSeconds(5); clock.Callbacks.First().Invoke(); Assert.Equal(11, store.Count); }
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; // Initialize timestamp _timeoutControl.Tick(startTime); _timeoutControl.StartRequestBody(minRate); _timeoutControl.StartTimingRead(); _timeoutControl.SetTimeout(timeout.Ticks, TimeoutReason.RequestBodyDrain); // Tick beyond grace period with low data rate systemClock.UtcNow += TimeSpan.FromSeconds(3); _timeoutControl.BytesRead(1); _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); // Timed out _mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.RequestBodyDrain), Times.Once); }
public void GetDateHeaderValue_ReturnsCachedValueBetweenTimerTicks() { var now = DateTimeOffset.UtcNow; var future = now.AddSeconds(10); var systemClock = new MockSystemClock { UtcNow = now }; var timeWithoutRequestsUntilIdle = TimeSpan.FromSeconds(1); var timerInterval = TimeSpan.FromSeconds(10); var dateHeaderValueManager = new DateHeaderValueManager(systemClock, timeWithoutRequestsUntilIdle, timerInterval); string result1; string result2; try { result1 = dateHeaderValueManager.GetDateHeaderValue(); systemClock.UtcNow = future; result2 = dateHeaderValueManager.GetDateHeaderValue(); } finally { dateHeaderValueManager.Dispose(); } Assert.Equal(now.ToString(Constants.RFC1123DateFormat), result1); Assert.Equal(now.ToString(Constants.RFC1123DateFormat), result2); Assert.Equal(1, systemClock.UtcNowCalled); }
public async Task ConnectionClosedEvenIfAppSwallowsException() { var gracePeriod = TimeSpan.FromSeconds(5); var systemClock = new MockSystemClock(); var serviceContext = new TestServiceContext { SystemClock = systemClock, DateHeaderValueManager = new DateHeaderValueManager(systemClock) }; var appRunningEvent = new ManualResetEventSlim(); var exceptionSwallowedEvent = new ManualResetEventSlim(); using (var server = new TestServer(async context => { context.Features.Get <IHttpMinRequestBodyDataRateFeature>().MinDataRate = new MinDataRate(bytesPerSecond: 1, gracePeriod: gracePeriod); appRunningEvent.Set(); try { await context.Request.Body.ReadAsync(new byte[1], 0, 1); } catch (BadHttpRequestException ex) when(ex.StatusCode == 408) { exceptionSwallowedEvent.Set(); } var response = "hello, world"; context.Response.ContentLength = response.Length; await context.Response.WriteAsync("hello, world"); }, serviceContext)) { using (var connection = server.CreateConnection()) { await connection.Send( "POST / HTTP/1.1", "Host:", "Content-Length: 1", "", ""); Assert.True(appRunningEvent.Wait(TimeSpan.FromSeconds(10))); systemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1); Assert.True(exceptionSwallowedEvent.Wait(TimeSpan.FromSeconds(10))); await connection.Receive( "HTTP/1.1 200 OK", ""); await connection.ReceiveForcedEnd( $"Date: {serviceContext.DateHeaderValue}", "Content-Length: 12", "", "hello, world"); } } }
public async Task SendToSingleRecipientAsync_first_email_sent_on_first_day() { // Arrange var poolName = "mypool"; var dailyVolumePerIpAddress = new[] { 3, 6, 9, 12 }; var resetDays = 1; var ipAddresses = new[] { "192.168.77.1", "192.168.77.2" }; var recipient = new MailAddress("*****@*****.**", "Bob Smith"); var warmupSettings = new WarmupSettings(poolName, dailyVolumePerIpAddress, resetDays); var mockSystemClock = new MockSystemClock(2017, 11, 18, 13, 0, 0, 0); var mockMailResource = new Mock <IMail>(MockBehavior.Strict); mockMailResource .Setup(r => r.SendAsync(It.Is <MailPersonalization[]>(p => p.Length == 1), It.IsAny <string>(), It.IsAny <IEnumerable <MailContent> >(), It.IsAny <MailAddress>(), It.IsAny <MailAddress>(), It.IsAny <IEnumerable <Attachment> >(), It.IsAny <string>(), It.IsAny <IEnumerable <KeyValuePair <string, string> > >(), It.IsAny <IEnumerable <KeyValuePair <string, string> > >(), It.IsAny <IEnumerable <string> >(), It.IsAny <IEnumerable <KeyValuePair <string, string> > >(), It.IsAny <DateTime?>(), It.IsAny <string>(), It.IsAny <UnsubscribeOptions>(), It.IsAny <string>(), It.IsAny <MailSettings>(), It.IsAny <TrackingSettings>(), It.IsAny <CancellationToken>())) .ReturnsAsync("message_id_on_pool"); var mockClient = new Mock <IClient>(MockBehavior.Strict); mockClient.SetupGet(c => c.Mail).Returns(mockMailResource.Object); var mockRepository = new Mock <IWarmupProgressRepository>(MockBehavior.Strict); mockRepository .Setup(repo => repo.GetWarmupStatusAsync(poolName, It.IsAny <CancellationToken>())) .ReturnsAsync(new WarmupStatus() { Completed = false, DateLastSent = DateTime.MinValue, EmailsSentLastDay = 0, IpAddresses = ipAddresses, PoolName = poolName, WarmupDay = 0 }); mockRepository .Setup(repo => repo.UpdateStatusAsync(It.Is <WarmupStatus>( s => s.Completed == false && s.DateLastSent.Date == (new DateTime(2017, 11, 18)).Date && s.EmailsSentLastDay == 1 && s.WarmupDay == 1 ), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(true)); var warmupEngine = new WarmupEngine(warmupSettings, mockClient.Object, mockRepository.Object, mockSystemClock.Object); // Act var result = await warmupEngine.SendToSingleRecipientAsync(recipient, null, null, null, null, null, null, false, false, null, null, null, null, null, null, null, null, null, null, null, CancellationToken.None).ConfigureAwait(false); // Assert mockClient.VerifyAll(); mockRepository.VerifyAll(); result.Completed.ShouldBeFalse(); result.MessageIdOnPool.ShouldBe("message_id_on_pool"); result.MessageIdNotOnPool.ShouldBeNull(); }
public async Task GetUnknownKey() { var clock = new MockSystemClock(); var store = new DefaultMemoryQosCounterStore(clock); var result = await store.GetAsync("a"); Assert.Equal(0, result); }
public Http3InMemory(ServiceContext serviceContext, MockSystemClock mockSystemClock, ITimeoutHandler timeoutHandler, ILoggerFactory loggerFactory) { _serviceContext = serviceContext; _timeoutControl = new TimeoutControl(new TimeoutControlConnectionInvoker(this, timeoutHandler)); _timeoutControl.Debugger = new TestDebugger(); _mockSystemClock = mockSystemClock; _serverReceivedSettings = Channel.CreateUnbounded <KeyValuePair <Http3SettingType, long> >(); Logger = loggerFactory.CreateLogger <Http3InMemory>(); }
public void GetDateHeaderValue_ReturnsDateValueInRFC1123Format() { var now = DateTimeOffset.UtcNow; var systemClock = new MockSystemClock { UtcNow = now }; var dateHeaderValueManager = new DateHeaderValueManager(systemClock); Assert.Equal(now.ToString(Rfc1123DateFormat), dateHeaderValueManager.GetDateHeaderValues().String); }
public async Task Remove() { var clock = new MockSystemClock(); var store = new DefaultMemoryQosCounterStore(clock); await store.AddAsync("a", 3, TimeSpan.FromSeconds(1)); await store.AddAsync("b", 4, TimeSpan.FromSeconds(1)); await store.RemoveAsync("b"); Assert.Equal(1, store.Count); }
public async Task AddAndGetExistingKey() { var clock = new MockSystemClock(); var store = new DefaultMemoryQosCounterStore(clock); var result = await store.AddAsync("a", 3, null); Assert.Equal(3, result); result = await store.GetAsync("a"); Assert.Equal(3, result); }
public async Task WriteTimingAbortsConnectionWhenRepeadtedSmallWritesDoNotCompleteWithMinimumDataRate() { var systemClock = new MockSystemClock(); var minResponseDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(5)); var numWrites = 5; var writeSize = 100; var aborted = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); _httpConnectionContext.ServiceContext.ServerOptions.Limits.MinResponseDataRate = minResponseDataRate; _httpConnectionContext.ServiceContext.SystemClock = systemClock; var mockLogger = new Mock <IKestrelTrace>(); _httpConnectionContext.ServiceContext.Log = mockLogger.Object; _httpConnection.Initialize(_httpConnectionContext.Transport); _httpConnection.Http1Connection.Reset(); _httpConnection.Http1Connection.RequestAborted.Register(() => { aborted.SetResult(null); }); // Initialize timestamp var startTime = systemClock.UtcNow; _httpConnection.Tick(startTime); // 5 consecutive 100 byte writes. for (var i = 0; i < numWrites - 1; i++) { _httpConnection.StartTimingWrite(writeSize); _httpConnection.StopTimingWrite(); } // Stall the last write. _httpConnection.StartTimingWrite(writeSize); // 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 + minResponseDataRate.GracePeriod + TimeSpan.FromSeconds((numWrites - 1) * writeSize / minResponseDataRate.BytesPerSecond); _httpConnection.Tick(systemClock.UtcNow); Assert.False(_httpConnection.RequestTimedOut); // On more tick forward triggers the timeout. systemClock.UtcNow += TimeSpan.FromTicks(1); _httpConnection.Tick(systemClock.UtcNow); Assert.True(_httpConnection.RequestTimedOut); await aborted.Task.TimeoutAfter(TimeSpan.FromSeconds(10)); }
public void CalculateDelay_without_XRateLimitReset() { // Arrange var maxAttempts = 5; var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0); var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object); var response = new HttpResponseMessage((HttpStatusCode)428); // Act var result = sendGridRetryStrategy.GetDelay(1, response); // Assert result.ShouldBe(TimeSpan.FromSeconds(1)); }
public void GetSharedAccessSignatureUri_throws_when_blob_is_null() { // Arrange var cancellationToken = CancellationToken.None; var permission = SharedAccessBlobPermissions.Read; var duration = TimeSpan.FromMinutes(1); var systemClock = new MockSystemClock(new DateTime(2016, 8, 12, 15, 0, 0, 0, DateTimeKind.Utc)).Object; // Act Should.Throw <ArgumentNullException>(() => { var result = ((CloudBlob)null).GetSharedAccessSignatureUri(permission, duration, systemClock); }); }
public void ShouldRetry_returns_false_when_statuscode_not_429() { // Arrange var maxAttempts = 5; var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0); var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object); var response = new HttpResponseMessage(HttpStatusCode.BadGateway); // Act var result = sendGridRetryStrategy.ShouldRetry(response); // Assert result.ShouldBeFalse(); }
public void ShouldRetry_returns_false_when_previous_response_is_null() { // Arrange var maxAttempts = 5; var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0); var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object); var response = (HttpResponseMessage)null; // Act var result = sendGridRetryStrategy.ShouldRetry(response); // Assert result.ShouldBeFalse(); }
public void GetNextDelay_with_null_HttpHeaders() { // Arrange var maxAttempts = 5; var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0); var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object); var response = (HttpResponseMessage)null; // Act var result = sendGridRetryStrategy.GetDelay(1, response); // Assert result.ShouldBe(TimeSpan.FromSeconds(1)); }
public void RequestBodyDataRateNotComputedOnPausedTime() { var systemClock = new MockSystemClock(); var minRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(2)); // Initialize timestamp _timeoutControl.Tick(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); _timeoutControl.BytesRead(600); _timeoutControl.Tick(systemClock.UtcNow); // Pause at 3.5s 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); // Tick at 6s, expected counted time is 4s, expected data rate is 150 bytes/second 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); _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); // 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); // Timed out _mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once); }
public async Task RequestTimesOutWhenNotDrainedWithinDrainTimeoutPeriod() { // This test requires a real clock since we can't control when the drain timeout is set var serviceContext = new TestServiceContext(LoggerFactory); serviceContext.InitializeHeartbeat(); // Ensure there's still a constant date header value. var clock = new MockSystemClock(); var date = new DateHeaderValueManager(); date.OnHeartbeat(clock.UtcNow); serviceContext.DateHeaderValueManager = date; var appRunningEvent = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); using (var server = new TestServer(context => { context.Features.Get <IHttpMinRequestBodyDataRateFeature>().MinDataRate = null; appRunningEvent.SetResult(null); return(Task.CompletedTask); }, serviceContext)) { using (var connection = server.CreateConnection()) { await connection.Send( "POST / HTTP/1.1", "Host:", "Content-Length: 1", "", ""); await appRunningEvent.Task.DefaultTimeout(); // Disconnects after response completes due to the timeout await connection.ReceiveEnd( "HTTP/1.1 200 OK", $"Date: {serviceContext.DateHeaderValue}", "Content-Length: 0", "", ""); } await server.StopAsync(); } Assert.Contains(TestSink.Writes, w => w.EventId.Id == 32 && w.LogLevel == LogLevel.Information); Assert.Contains(TestSink.Writes, w => w.EventId.Id == 33 && w.LogLevel == LogLevel.Information); }