public void GivenCircuitBreakerClose_WhenOpenAndStateChangeSubscribed_ThenCallEventStateChangeOnce()
        {
            // Arrange
            int       changeStateCount = 0;
            const int THRESHOLD        = 2;
            var       circuitBreaker   = new DotNetCircuitBreaker.CircuitBreaker(THRESHOLD, TimeSpan.FromMinutes(5));

            circuitBreaker.OnStateChange += (o, state) => { changeStateCount++; };
            Assert.True(circuitBreaker.IsClosed);

            // Act
            circuitBreaker.Open();

            // Assert
            Assert.Equal(1, changeStateCount);
        }
        public void GivenCircuitBreakerOpen_WhenManuallyClose_ThenClosed()
        {
            // Arrange
            const int THRESHOLD      = 2;
            Action    protectedCode  = () => { throw new Exception(); };
            var       circuitBreaker = new DotNetCircuitBreaker.CircuitBreaker(THRESHOLD, TimeSpan.FromMinutes(5));

            CallXAmountOfTimes(() => circuitBreaker.AttemptCall(protectedCode), THRESHOLD);
            Assert.True(circuitBreaker.IsOpen);

            // Act
            circuitBreaker.Close();

            // Assert
            Assert.True(circuitBreaker.IsClosed);
        }
        public void GivenCircuitBreakerHalfOpen_WhenNoException_ThenFailureCountZero()
        {
            // Arrange
            const int THRESHOLD      = 2;
            Action    protectedCode  = () => { throw new Exception(); };
            var       circuitBreaker = new DotNetCircuitBreaker.CircuitBreaker(THRESHOLD, TimeSpan.FromMilliseconds(10));

            CallXAmountOfTimes(() => circuitBreaker.AttemptCall(protectedCode), THRESHOLD);
            Thread.Sleep(25);             //This set is back to HalfOpen
            Assert.True(circuitBreaker.IsHalfOpen);

            // Act
            circuitBreaker.AttemptCall(() => { });

            // Act
            Assert.Equal(0, circuitBreaker.Failures);
        }
        public void GivenCircuitBreakerClose_WhenOpenTwiceAndStateChangeSubscribed_ThenCallEventStateChangeOnce()
        {
            // Arrange
            int       changeStateCount = 0;
            const int THRESHOLD        = 2;
            Action    protectedCode    = () => { throw new Exception(); };
            var       circuitBreaker   = new DotNetCircuitBreaker.CircuitBreaker(THRESHOLD, TimeSpan.FromMinutes(5));

            circuitBreaker.OnStateChange += (o, state) => { changeStateCount++; };
            Assert.True(circuitBreaker.IsClosed);

            // Act
            CallXAmountOfTimes(() => circuitBreaker.AttemptCall(protectedCode), THRESHOLD);
            CallXAmountOfTimes(() => circuitBreaker.AttemptCall(protectedCode), THRESHOLD);

            // Assert
            Assert.Equal(1, changeStateCount);
        }
        public void GivenCircuitBreakerClose_WhenOpenAndCloseAndStateChangeSubscribed_ThenCallEventStateChangeTwice()
        {
            // Arrange
            int       changeStateCount = 0;
            const int THRESHOLD        = 2;
            Action    protectedCode    = () => { throw new Exception(); };
            var       circuitBreaker   = new DotNetCircuitBreaker.CircuitBreaker(THRESHOLD, TimeSpan.FromMilliseconds(10));

            circuitBreaker.OnStateChange += (o, state) => { changeStateCount++; };
            Assert.True(circuitBreaker.IsClosed);

            // Act
            CallXAmountOfTimes(() => circuitBreaker.AttemptCall(protectedCode), THRESHOLD);
            Thread.Sleep(25); //This set is back to HalfOpen
            circuitBreaker.AttemptCall(() => { });

            // Assert
            Assert.Equal(3, changeStateCount); //Close->Open, Open->Half, Half->Close
        }
        public void GivenCircuitBreakerOpen_WhenCallAgain_ThenNotCallNotExecuted()
        {
            // Arrange
            const int THRESHOLD_INVOCATION = 10;
            int       countInvocation      = 0;
            Action    protectedCode        = () =>
            {
                countInvocation++;
                throw new Exception();
            };
            var circuitBreaker = new DotNetCircuitBreaker.CircuitBreaker(THRESHOLD_INVOCATION, TimeSpan.FromMinutes(5));

            CallXAmountOfTimes(() => circuitBreaker.AttemptCall(protectedCode), THRESHOLD_INVOCATION);

            // Act
            Assert.Equal(THRESHOLD_INVOCATION, countInvocation);
            circuitBreaker.AttemptCall(protectedCode);

            // Assert
            Assert.Equal(THRESHOLD_INVOCATION, countInvocation);
        }