public async Task RunScalingLogic_AtMinimumSize_NoChange()
        {
            // Arrange

            var connectionPool = CreateMockConnectionPool(
                2, 2, 5, 0,
                Enumerable.Range(1, 2).Select(_ => CreateMockConnection(TimeSpan.Zero)));

            var controller = new MockController();

            // Act

            await controller.RunScalingLogicPublic(connectionPool.Object);

            // Assert

            connectionPool.Verify(
                m => m.ScaleAsync(It.IsAny <int>()),
                Times.Never);
        }
        public async Task RunScalingLogic_AboveBackPressureThreshold_ScaleUp()
        {
            // Arrange

            var connectionPool = CreateMockConnectionPool(
                2, 2, 5, 5,
                Enumerable.Range(1, 2).Select(_ => CreateMockConnection(TimeSpan.Zero)));

            var controller = new MockController
            {
                BackPressureThreshold = 4
            };

            // Act

            await controller.RunScalingLogicPublic(connectionPool.Object);

            // Assert

            connectionPool.Verify(
                m => m.ScaleAsync(1),
                Times.Once);
        }
        public async Task RunScalingLogic_AtOrBelowBackPressureThreshold_NoChange(int backPressure)
        {
            // Arrange

            var connectionPool = CreateMockConnectionPool(
                5, 2, 5, backPressure,
                Enumerable.Range(1, 2).Select(_ => CreateMockConnection(TimeSpan.Zero)));

            var controller = new MockController
            {
                BackPressureThreshold = 4
            };

            // Act

            await controller.RunScalingLogicPublic(connectionPool.Object);

            // Assert

            connectionPool.Verify(
                m => m.ScaleAsync(It.IsAny <int>()),
                Times.Never);
        }
        public async Task RunScalingLogic_AllConnectionsBelowTimeout_NoChange(int lastActivitySeconds)
        {
            // Arrange

            var connectionPool = CreateMockConnectionPool(
                2, 2, 5, 0,
                Enumerable.Range(1, 2).Select(_ => CreateMockConnection(TimeSpan.FromSeconds(lastActivitySeconds))));

            var controller = new MockController
            {
                IdleConnectionTimeout = TimeSpan.FromSeconds(60)
            };

            // Act

            await controller.RunScalingLogicPublic(connectionPool.Object);

            // Assert

            connectionPool.Verify(
                m => m.ScaleAsync(It.IsAny <int>()),
                Times.Never);
        }
        public async Task RunScalingLogic_BelowMinimumSize_ScaleUp()
        {
            // Arrange
            const int minConnectionPoolSize = 2;
            var       connectionPool        = CreateMockConnectionPool(
                0, minConnectionPoolSize, 5, 0,
                Enumerable.Range(1, 1).Select(_ => CreateMockConnection(TimeSpan.Zero)));

            var controller = new MockController
            {
                BackPressureThreshold = 4
            };

            // Act

            await controller.RunScalingLogicPublic(connectionPool.Object);

            // Assert

            connectionPool.Verify(
                m => m.ScaleAsync(minConnectionPoolSize),
                Times.Once);
        }
        public async Task RunScalingLogic_OneConnectionAboveTimeout_ScaleDown()
        {
            // Arrange

            var connectionPool = CreateMockConnectionPool(
                5, 2, 5, 0,
                Enumerable.Range(1, 5).Select(i =>
                                              CreateMockConnection(i < 5 ? TimeSpan.Zero : TimeSpan.FromSeconds(60))));

            var controller = new MockController
            {
                IdleConnectionTimeout = TimeSpan.FromSeconds(60)
            };

            // Act

            await controller.RunScalingLogicPublic(connectionPool.Object);

            // Assert

            connectionPool.Verify(
                m => m.ScaleAsync(-1),
                Times.Once);
        }