public async Task AttemptDeviceConnectionClearsConsecutiveFailuresOnSuccess()

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);
            }
        }