in DeviceBridgeTests/Services/SubscriptionSchedulerTests.cs [369:404]
public async Task AttemptDeviceConnectionClearsConsecutiveFailuresOnSuccess()
{
using (ShimsContext.Create())
{
// Make random(min, max) always return max so we always schedule the connection at the maximum offset.
System.Fakes.ShimRandom.AllInstances.NextInt32Int32 = (@this, min, max) => max;
// Make connection fail once so it will be rescheduled for 5 minutes.
_storageProviderMock.Setup(p => p.ListAllSubscriptionsOrderedByDeviceId(It.IsAny<Logger>())).Returns(Task.FromResult(new List<DeviceSubscription>() { }));
_storageProviderMock.Setup(p => p.ListDeviceSubscriptions(It.IsAny<Logger>(), "test-device")).Returns(Task.FromResult(new List<DeviceSubscription>() { TestUtils.GetTestSubscription("test-device", DeviceSubscriptionType.C2DMessages) }));
var subscriptionCallbackFactory = new SubscriptionCallbackFactory(LogManager.GetCurrentClassLogger(), _httpClientFactoryMock.Object);
var subscriptionScheduler = new SubscriptionScheduler(LogManager.GetCurrentClassLogger(), _connectionManagerMock.Object, _storageProviderMock.Object, subscriptionCallbackFactory, 2, 10);
await subscriptionScheduler.SynchronizeDeviceDbAndEngineDataSubscriptionsAsync("test-device", false);
_connectionManagerMock.Setup(p => p.AssertDeviceConnectionOpenAsync("test-device", false, null)).Returns(Task.FromException(new Exception("Open failed")));
await RunSchedulerOnceAndWaitConnectionAttempts(subscriptionScheduler, 1, 10);
// Attempt connections forwarding the clock 4 and 5 minutes, to make sure it only attempts to connect after 5 minutes (making the connection succeed).
TestUtils.ShimUtcNowAhead(4);
await RunSchedulerOnceAndWaitConnectionAttempts(subscriptionScheduler, 0, 10);
_connectionManagerMock.Setup(p => p.AssertDeviceConnectionOpenAsync("test-device", false, null)).Returns(Task.CompletedTask);
TestUtils.ShimUtcNowAhead(5);
await RunSchedulerOnceAndWaitConnectionAttempts(subscriptionScheduler, 1, 10);
// Make the connection fail again so it's rescheduled.
TestUtils.UnshimUtcNow();
await subscriptionScheduler.SynchronizeDeviceDbAndEngineDataSubscriptionsAsync("test-device", false);
_connectionManagerMock.Setup(p => p.AssertDeviceConnectionOpenAsync("test-device", false, null)).Returns(Task.FromException(new Exception("Open failed")));
await RunSchedulerOnceAndWaitConnectionAttempts(subscriptionScheduler, 1, 10);
// Check that the connection was rescheduled for 5 minutes and not 10, as the previous successful connection cleared the consecutive failed attempt count.
TestUtils.ShimUtcNowAhead(4);
await RunSchedulerOnceAndWaitConnectionAttempts(subscriptionScheduler, 0, 10);
TestUtils.ShimUtcNowAhead(5);
await RunSchedulerOnceAndWaitConnectionAttempts(subscriptionScheduler, 1, 10);
}
}