public void CommandMetrics_GetErrorPercentage()
        {
            HystrixCommandPropertiesSetter properties = UnitTestSetterFactory.GetCommandPropertiesSetter();
            HystrixCommandMetrics          metrics    = GetMetrics(properties);

            metrics.MarkSuccess(100);
            Assert.AreEqual(0, metrics.GetHealthCounts().ErrorPercentage);

            metrics.MarkFailure(1000);
            Assert.AreEqual(50, metrics.GetHealthCounts().ErrorPercentage);

            metrics.MarkSuccess(100);
            metrics.MarkSuccess(100);
            Assert.AreEqual(25, metrics.GetHealthCounts().ErrorPercentage);

            metrics.MarkTimeout(5000);
            metrics.MarkTimeout(5000);
            Assert.AreEqual(50, metrics.GetHealthCounts().ErrorPercentage);

            metrics.MarkSuccess(100);
            metrics.MarkSuccess(100);
            metrics.MarkSuccess(100);

            // latent
            metrics.MarkSuccess(5000);

            // 6 success + 1 latent success + 1 failure + 2 timeout = 10 total
            // latent success not considered error
            // error percentage = 1 failure + 2 timeout / 10
            Assert.AreEqual(30, metrics.GetHealthCounts().ErrorPercentage);
        }
        public void CircuitBreaker_TripCircuitOnTimeoutsAboveThreshold()
        {
            try
            {
                HystrixCommandPropertiesSetter properties = UnitTestSetterFactory.GetCommandPropertiesSetter();
                HystrixCommandMetrics          metrics    = GetMetrics(properties);
                IHystrixCircuitBreaker         cb         = GetCircuitBreaker(key, CommandGroupForUnitTest.OwnerTwo, metrics, properties);

                // this should start as allowing requests
                Assert.IsTrue(cb.AllowRequest());
                Assert.IsFalse(cb.IsOpen());

                // success with high latency
                metrics.MarkSuccess(400);
                metrics.MarkSuccess(400);
                metrics.MarkTimeout(10);
                metrics.MarkSuccess(400);
                metrics.MarkTimeout(10);
                metrics.MarkTimeout(10);
                metrics.MarkSuccess(400);
                metrics.MarkTimeout(10);
                metrics.MarkTimeout(10);

                // this should trip the circuit as the error percentage is above the threshold
                Assert.IsFalse(cb.AllowRequest());
                Assert.IsTrue(cb.IsOpen());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Assert.Fail("Error occurred: " + e.Message);
            }
        }
        public void CircuitBreaker_TripCircuitOnTimeouts()
        {
            try
            {
                HystrixCommandPropertiesSetter properties = UnitTestSetterFactory.GetCommandPropertiesSetter();
                HystrixCommandMetrics          metrics    = GetMetrics(properties);
                IHystrixCircuitBreaker         cb         = GetCircuitBreaker(key, CommandGroupForUnitTest.OwnerTwo, metrics, properties);

                // this should start as allowing requests
                Assert.IsTrue(cb.AllowRequest());
                Assert.IsFalse(cb.IsOpen());

                // timeouts
                metrics.MarkTimeout(2000);
                metrics.MarkTimeout(2000);
                metrics.MarkTimeout(2000);
                metrics.MarkTimeout(2000);

                // everything has been a timeout so we should not allow any requests
                Assert.IsFalse(cb.AllowRequest());
                Assert.IsTrue(cb.IsOpen());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Assert.Fail("Error occurred: " + e.Message);
            }
        }
        public void CircuitBreaker_CircuitClosedAfterSuccess()
        {
            try
            {
                int sleepWindow = 200;
                HystrixCommandPropertiesSetter properties = UnitTestSetterFactory.GetCommandPropertiesSetter().WithCircuitBreakerSleepWindowInMilliseconds(sleepWindow);
                HystrixCommandMetrics          metrics    = GetMetrics(properties);
                IHystrixCircuitBreaker         cb         = GetCircuitBreaker(key, CommandGroupForUnitTest.OwnerTwo, metrics, properties);

                // fail
                metrics.MarkFailure(1000);
                metrics.MarkFailure(1000);
                metrics.MarkFailure(1000);
                metrics.MarkTimeout(1000);

                // everything has failed in the test window so we should return false now
                Assert.IsFalse(cb.AllowRequest());
                Assert.IsTrue(cb.IsOpen());

                // wait for sleepWindow to pass
                Thread.Sleep(sleepWindow + 50);

                // we should now allow 1 request
                Assert.IsTrue(cb.AllowRequest());
                // but the circuit should still be open
                Assert.IsTrue(cb.IsOpen());
                // and further requests are still blocked
                Assert.IsFalse(cb.AllowRequest());

                // the 'singleTest' succeeds so should cause the circuit to be closed
                metrics.MarkSuccess(500);
                cb.MarkSuccess();

                // all requests should be open again
                Assert.IsTrue(cb.AllowRequest());
                Assert.IsTrue(cb.AllowRequest());
                Assert.IsTrue(cb.AllowRequest());
                // and the circuit should be closed again
                Assert.IsFalse(cb.IsOpen());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Assert.Fail("Error occurred: " + e.Message);
            }
        }