public async void TestCircuitClosedAfterSuccess()
        {
            String key = "cmd-G";

            try
            {
                int sleepWindow = 100;
                HystrixCommand <Boolean> cmd1 = new FailureCommand(key, 1, sleepWindow);
                IHystrixCircuitBreaker   cb   = cmd1.circuitBreaker;

                // this should start as allowing requests
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);

                cmd1.Execute();
                HystrixCommand <Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow);
                cmd2.Execute();
                HystrixCommand <Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow);
                cmd3.Execute();
                HystrixCommand <Boolean> cmd4 = new TimeoutCommand(key, sleepWindow);
                cmd4.Execute();

                // everything has failed in the test window so we should return false now
                Time.Wait(150);
                output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
                output.WriteLine("CircuitBreaker state 1 : " + cmd1.Metrics.Healthcounts);
                Assert.False(cb.AllowRequest);
                Assert.True(cb.IsOpen);

                // wait for sleepWindow to pass
                Time.Wait(sleepWindow + 50);

                // but the circuit should still be open
                Assert.True(cb.IsOpen);

                // we should now allow 1 request, and upon success, should cause the circuit to be closed
                HystrixCommand <bool> cmd5        = new SuccessCommand(key, 60, sleepWindow);
                IObservable <bool>    asyncResult = cmd5.Observe();

                // and further requests are still blocked while the singleTest command is in flight
                Assert.False(cb.AllowRequest);

                await asyncResult.SingleAsync();

                // all requests should be open again

                Time.Wait(150);
                output.WriteLine("CircuitBreaker state 2 : " + cmd1.Metrics.Healthcounts);
                Assert.True(cb.AllowRequest);
                Assert.True(cb.AllowRequest);
                Assert.True(cb.AllowRequest);
                // and the circuit should be closed again
                Assert.False(cb.IsOpen);
            }
            catch (Exception e)
            {
                output.WriteLine(e.ToString());
                Assert.False(true, "Error occurred: " + e.Message);
            }
        }
        public void TestLowVolumeDoesNotTripCircuit()
        {
            String key = "cmd-I";

            try
            {
                int sleepWindow = 200;
                int lowVolume   = 5;

                HystrixCommand <Boolean> cmd1 = new FailureCommand(key, 60, sleepWindow, lowVolume);
                IHystrixCircuitBreaker   cb   = cmd1.circuitBreaker;

                // this should start as allowing requests
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);

                cmd1.Execute();
                HystrixCommand <Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow, lowVolume);
                cmd2.Execute();
                HystrixCommand <Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow, lowVolume);
                cmd3.Execute();
                HystrixCommand <Boolean> cmd4 = new FailureCommand(key, 1, sleepWindow, lowVolume);
                cmd4.Execute();

                // even though it has all failed we won't trip the circuit because the volume is low
                Time.Wait(150);
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);
            }
            catch (Exception e)
            {
                output.WriteLine(e.ToString());
                Assert.False(true, "Error occurred: " + e.Message);
            }
        }
示例#3
0
        public void TestLowVolumeDoesNotTripCircuit()
        {
            String key = "cmd-I";

            int sleepWindow = 200;
            int lowVolume   = 5;

            HystrixCommand <Boolean> cmd1 = new FailureCommand(key, 60, sleepWindow, lowVolume);
            IHystrixCircuitBreaker   cb   = cmd1.circuitBreaker;

            // this should start as allowing requests
            Assert.True(cb.AllowRequest);
            Assert.False(cb.IsOpen);

            cmd1.Execute();
            HystrixCommand <Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow, lowVolume);

            cmd2.Execute();
            HystrixCommand <Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow, lowVolume);

            cmd3.Execute();
            HystrixCommand <Boolean> cmd4 = new FailureCommand(key, 1, sleepWindow, lowVolume);

            cmd4.Execute();

            // even though it has all failed we won't trip the circuit because the volume is low
            Time.Wait(150);
            Assert.True(cb.AllowRequest);
            Assert.False(cb.IsOpen);
        }
        public void TestGetErrorPercentage()
        {
            string key = "cmd-metrics-A";

            HystrixCommand <bool> cmd1    = new SuccessCommand(key, 1);
            HystrixCommandMetrics metrics = cmd1._metrics;

            cmd1.Execute();
            Time.Wait(200);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(0, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd2 = new FailureCommand(key, 1);

            cmd2.Execute();
            Time.Wait(200);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd3 = new SuccessCommand(key, 1);
            HystrixCommand <bool> cmd4 = new SuccessCommand(key, 1);

            cmd3.Execute();
            cmd4.Execute();
            Time.Wait(200);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(25, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd5 = new TimeoutCommand(key);
            HystrixCommand <bool> cmd6 = new TimeoutCommand(key);

            cmd5.Execute();
            cmd6.Execute();
            Time.Wait(200);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd7 = new SuccessCommand(key, 1);
            HystrixCommand <bool> cmd8 = new SuccessCommand(key, 1);
            HystrixCommand <bool> cmd9 = new SuccessCommand(key, 1);

            cmd7.Execute();
            cmd8.Execute();
            cmd9.Execute();
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());

            // latent
            HystrixCommand <bool> cmd10 = new SuccessCommand(key, 60);

            cmd10.Execute();

            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());

            // 6 success + 1 latent success + 1 failure + 2 timeout = 10 total
            // latent success not considered error
            // error percentage = 1 failure + 2 timeout / 10
            Time.Wait(200);
            Assert.Equal(30, metrics.Healthcounts.ErrorPercentage);
        }
        public void TestBadRequestsDoNotAffectErrorPercentage()
        {
            string key = "cmd-metrics-B";

            HystrixCommand <bool> cmd1    = new SuccessCommand(key, 0);
            HystrixCommandMetrics metrics = cmd1._metrics;

            Assert.True(WaitForHealthCountToUpdate(key, 1000), "Health count stream took to long");
            cmd1.Execute();
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(0, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd2 = new FailureCommand(key, 0);

            cmd2.Execute();
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd3 = new BadRequestCommand(key, 0);
            HystrixCommand <bool> cmd4 = new BadRequestCommand(key, 0);

            try
            {
                cmd3.Execute();
            }
            catch (HystrixBadRequestException)
            {
                output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + "Caught expected HystrixBadRequestException from cmd3");
            }

            try
            {
                cmd4.Execute();
            }
            catch (HystrixBadRequestException)
            {
                output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + "Caught expected HystrixBadRequestException from cmd4");
            }

            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd5 = new FailureCommand(key, 0);
            HystrixCommand <bool> cmd6 = new FailureCommand(key, 0);

            cmd5.Execute();
            cmd6.Execute();
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(75, metrics.Healthcounts.ErrorPercentage);
        }
        public void TestBadRequestsDoNotAffectErrorPercentage()
        {
            string key = "cmd-metrics-B";

            HystrixCommand <bool> cmd1    = new SuccessCommand(key, 1);
            HystrixCommandMetrics metrics = cmd1._metrics;

            cmd1.Execute();
            Time.Wait(200);

            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(0, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd2 = new FailureCommand(key, 1);

            cmd2.Execute();
            Time.Wait(200);

            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd3 = new BadRequestCommand(key, 1);
            HystrixCommand <bool> cmd4 = new BadRequestCommand(key, 1);

            try
            {
                cmd3.Execute();
            }
            catch (HystrixBadRequestException)
            {
                output.WriteLine("Caught expected HystrixBadRequestException from cmd3");
            }

            try
            {
                cmd4.Execute();
            }
            catch (HystrixBadRequestException)
            {
                output.WriteLine("Caught expected HystrixBadRequestException from cmd4");
            }

            Time.Wait(200);

            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd5 = new FailureCommand(key, 1);
            HystrixCommand <bool> cmd6 = new FailureCommand(key, 1);

            cmd5.Execute();
            cmd6.Execute();
            Time.Wait(200);

            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(75, metrics.Healthcounts.ErrorPercentage);
        }
        public void TestTripCircuit()
        {
            String key = "cmd-A";

            try
            {
                HystrixCommand <bool> cmd1 = new SuccessCommand(key, 1);
                HystrixCommand <bool> cmd2 = new SuccessCommand(key, 1);
                HystrixCommand <bool> cmd3 = new SuccessCommand(key, 1);
                HystrixCommand <bool> cmd4 = new SuccessCommand(key, 1);

                IHystrixCircuitBreaker cb = cmd1.circuitBreaker;

                cmd1.Execute();
                cmd2.Execute();
                cmd3.Execute();
                cmd4.Execute();

                // this should still allow requests as everything has been successful
                Time.Wait(150);
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);

                // fail
                HystrixCommand <bool> cmd5 = new FailureCommand(key, 1);
                HystrixCommand <bool> cmd6 = new FailureCommand(key, 1);
                HystrixCommand <bool> cmd7 = new FailureCommand(key, 1);
                HystrixCommand <bool> cmd8 = new FailureCommand(key, 1);
                Assert.False(cmd5.Execute());
                Assert.False(cmd6.Execute());
                Assert.False(cmd7.Execute());
                Assert.False(cmd8.Execute());

                // everything has failed in the test window so we should return false now
                Time.Wait(150);
                Assert.False(cb.AllowRequest);
                Assert.True(cb.IsOpen);
            }
            catch (Exception e)
            {
                output.WriteLine(e.ToString());
                Assert.False(true, "Error occurred: " + e.Message);
            }
        }
        public void TestSingleTestOnOpenCircuitAfterTimeWindow()
        {
            String key = "cmd-F";

            try
            {
                int sleepWindow = 200;
                HystrixCommand <Boolean> cmd1 = new FailureCommand(key, 60);
                IHystrixCircuitBreaker   cb   = cmd1.circuitBreaker;

                // this should start as allowing requests
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);

                cmd1.Execute();
                HystrixCommand <Boolean> cmd2 = new FailureCommand(key, 1);
                cmd2.Execute();
                HystrixCommand <Boolean> cmd3 = new FailureCommand(key, 1);
                cmd3.Execute();
                HystrixCommand <Boolean> cmd4 = new FailureCommand(key, 1);
                cmd4.Execute();

                // everything has failed in the test window so we should return false now
                Time.Wait(150);
                Assert.False(cb.AllowRequest);
                Assert.True(cb.IsOpen);

                // wait for sleepWindow to pass
                Time.Wait(sleepWindow + 50);

                // we should now allow 1 request
                Assert.True(cb.AllowRequest);
                // but the circuit should still be open
                Assert.True(cb.IsOpen);
                // and further requests are still blocked
                Assert.False(cb.AllowRequest);
            }
            catch (Exception e)
            {
                output.WriteLine(e.ToString());
                Assert.False(true, "Error occurred: " + e.Message);
            }
        }
        public void TestCircuitDoesNotTripOnFailuresBelowThreshold()
        {
            String key = "cmd-C";

            try
            {
                HystrixCommand <Boolean> cmd1 = new SuccessCommand(key, 60);
                IHystrixCircuitBreaker   cb   = cmd1.circuitBreaker;

                // this should start as allowing requests
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);

                // success with high latency
                cmd1.Execute();
                HystrixCommand <Boolean> cmd2 = new SuccessCommand(key, 1);
                cmd2.Execute();
                HystrixCommand <Boolean> cmd3 = new FailureCommand(key, 1);
                cmd3.Execute();
                HystrixCommand <Boolean> cmd4 = new SuccessCommand(key, 1);
                cmd4.Execute();
                HystrixCommand <Boolean> cmd5 = new SuccessCommand(key, 1);
                cmd5.Execute();
                HystrixCommand <Boolean> cmd6 = new FailureCommand(key, 1);
                cmd6.Execute();
                HystrixCommand <Boolean> cmd7 = new SuccessCommand(key, 1);
                cmd7.Execute();
                HystrixCommand <Boolean> cmd8 = new FailureCommand(key, 1);
                cmd8.Execute();

                // this should remain closed as the failure threshold is below the percentage limit
                Time.Wait(150);
                output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
                output.WriteLine("Current CircuitBreaker Status : " + cmd1.Metrics.Healthcounts);
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);
            }
            catch (Exception e)
            {
                output.WriteLine(e.ToString());
                Assert.False(true, "Error occurred: " + e.Message);
            }
        }
        public void TestTripCircuitOnFailuresAboveThreshold()
        {
            String key = "cmd-B";

            try
            {
                HystrixCommand <Boolean> cmd1 = new SuccessCommand(key, 60);
                IHystrixCircuitBreaker   cb   = cmd1.circuitBreaker;

                // this should start as allowing requests
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);

                // success with high latency
                cmd1.Execute();
                HystrixCommand <Boolean> cmd2 = new SuccessCommand(key, 1);
                cmd2.Execute();
                HystrixCommand <Boolean> cmd3 = new FailureCommand(key, 1);
                cmd3.Execute();
                HystrixCommand <Boolean> cmd4 = new SuccessCommand(key, 1);
                cmd4.Execute();
                HystrixCommand <Boolean> cmd5 = new FailureCommand(key, 1);
                cmd5.Execute();
                HystrixCommand <Boolean> cmd6 = new SuccessCommand(key, 1);
                cmd6.Execute();
                HystrixCommand <Boolean> cmd7 = new FailureCommand(key, 1);
                cmd7.Execute();
                HystrixCommand <Boolean> cmd8 = new FailureCommand(key, 1);
                cmd8.Execute();

                // this should trip the circuit as the error percentage is above the threshold
                Time.Wait(150);
                Assert.False(cb.AllowRequest);
                Assert.True(cb.IsOpen);
            }
            catch (Exception e)
            {
                output.WriteLine(e.ToString());
                Assert.False(true, "Error occurred: " + e.Message);
            }
        }
示例#11
0
        public void TestTripCircuitOnFailuresAboveThreshold()
        {
            string key = "cmd-B";

            HystrixCommand <bool>  cmd1 = new SuccessCommand(key, 60);
            IHystrixCircuitBreaker cb   = cmd1._circuitBreaker;

            // this should start as allowing requests
            Assert.True(cb.AllowRequest);
            Assert.False(cb.IsOpen);

            // success with high latency
            cmd1.Execute();
            HystrixCommand <bool> cmd2 = new SuccessCommand(key, 1);

            cmd2.Execute();
            HystrixCommand <bool> cmd3 = new FailureCommand(key, 1);

            cmd3.Execute();
            HystrixCommand <bool> cmd4 = new SuccessCommand(key, 1);

            cmd4.Execute();
            HystrixCommand <bool> cmd5 = new FailureCommand(key, 1);

            cmd5.Execute();
            HystrixCommand <bool> cmd6 = new SuccessCommand(key, 1);

            cmd6.Execute();
            HystrixCommand <bool> cmd7 = new FailureCommand(key, 1);

            cmd7.Execute();
            HystrixCommand <bool> cmd8 = new FailureCommand(key, 1);

            cmd8.Execute();

            // this should trip the circuit as the error percentage is above the threshold
            Time.Wait(150);
            Assert.False(cb.AllowRequest);
            Assert.True(cb.IsOpen);
        }
示例#12
0
        public void TestSingleTestOnOpenCircuitAfterTimeWindow()
        {
            string key = "cmd-F";

            int sleepWindow             = 200;
            HystrixCommand <bool>  cmd1 = new FailureCommand(key, 60);
            IHystrixCircuitBreaker cb   = cmd1._circuitBreaker;

            // this should start as allowing requests
            Assert.True(cb.AllowRequest);
            Assert.False(cb.IsOpen);

            cmd1.Execute();
            HystrixCommand <bool> cmd2 = new FailureCommand(key, 1);

            cmd2.Execute();
            HystrixCommand <bool> cmd3 = new FailureCommand(key, 1);

            cmd3.Execute();
            HystrixCommand <bool> cmd4 = new FailureCommand(key, 1);

            cmd4.Execute();

            // everything has failed in the test window so we should return false now
            Time.Wait(150);
            Assert.False(cb.AllowRequest);
            Assert.True(cb.IsOpen);

            // wait for sleepWindow to pass
            Time.Wait(sleepWindow + 50);

            // we should now allow 1 request
            Assert.True(cb.AllowRequest);

            // but the circuit should still be open
            Assert.True(cb.IsOpen);

            // and further requests are still blocked
            Assert.False(cb.AllowRequest);
        }
示例#13
0
        public void TestTripCircuit()
        {
            String key = "cmd-A";

            HystrixCommand <bool> cmd1 = new SuccessCommand(key, 1);
            HystrixCommand <bool> cmd2 = new SuccessCommand(key, 1);
            HystrixCommand <bool> cmd3 = new SuccessCommand(key, 1);
            HystrixCommand <bool> cmd4 = new SuccessCommand(key, 1);

            IHystrixCircuitBreaker cb = cmd1.circuitBreaker;

            cmd1.Execute();
            cmd2.Execute();
            cmd3.Execute();
            cmd4.Execute();

            // this should still allow requests as everything has been successful
            Time.Wait(150);
            Assert.True(cb.AllowRequest);
            Assert.False(cb.IsOpen);

            // fail
            HystrixCommand <bool> cmd5 = new FailureCommand(key, 1);
            HystrixCommand <bool> cmd6 = new FailureCommand(key, 1);
            HystrixCommand <bool> cmd7 = new FailureCommand(key, 1);
            HystrixCommand <bool> cmd8 = new FailureCommand(key, 1);

            Assert.False(cmd5.Execute());
            Assert.False(cmd6.Execute());
            Assert.False(cmd7.Execute());
            Assert.False(cmd8.Execute());

            // everything has failed in the test window so we should return false now
            Time.Wait(150);
            Assert.False(cb.AllowRequest);
            Assert.True(cb.IsOpen);
        }
示例#14
0
        public void TestGetErrorPercentage()
        {
            string key = "cmd-metrics-A";

            HystrixCommand <bool> cmd1    = new SuccessCommand(key, 0);
            HystrixCommandMetrics metrics = cmd1._metrics;

            Assert.True(WaitForHealthCountToUpdate(key, 1000), "Health count stream took to long");

            cmd1.Execute();
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(0, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd2 = new FailureCommand(key, 0);

            cmd2.Execute();
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd3 = new SuccessCommand(key, 0);
            HystrixCommand <bool> cmd4 = new SuccessCommand(key, 0);

            cmd3.Execute();
            cmd4.Execute();
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(25, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd5 = new TimeoutCommand(key);
            HystrixCommand <bool> cmd6 = new TimeoutCommand(key);

            cmd5.Execute();
            cmd6.Execute();
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");
            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(50, metrics.Healthcounts.ErrorPercentage);

            HystrixCommand <bool> cmd7 = new SuccessCommand(key, 0);
            HystrixCommand <bool> cmd8 = new SuccessCommand(key, 0);
            HystrixCommand <bool> cmd9 = new SuccessCommand(key, 0);

            cmd7.Execute();
            cmd8.Execute();
            cmd9.Execute();

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());

            // latent
            HystrixCommand <bool> cmd10 = new SuccessCommand(key, 60);

            cmd10.Execute();

            output.WriteLine("ReqLog" + "@ " + Time.CurrentTimeMillis + " : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());

            // 6 success + 1 latent success + 1 failure + 2 timeout = 10 total
            // latent success not considered error
            // error percentage = 1 failure + 2 timeout / 10
            Assert.True(WaitForHealthCountToUpdate(key, 250), "Health count stream took to long");
            Assert.Equal(30, metrics.Healthcounts.ErrorPercentage);
        }
        public async void TestMultipleTimeWindowRetriesBeforeClosingCircuit()
        {
            String key = "cmd-H";

            try
            {
                int sleepWindow = 200;
                HystrixCommand <Boolean> cmd1 = new FailureCommand(key, 60);
                IHystrixCircuitBreaker   cb   = cmd1.circuitBreaker;

                // this should start as allowing requests
                Assert.True(cb.AllowRequest);
                Assert.False(cb.IsOpen);

                cmd1.Execute();
                HystrixCommand <Boolean> cmd2 = new FailureCommand(key, 1);
                cmd2.Execute();
                HystrixCommand <Boolean> cmd3 = new FailureCommand(key, 1);
                cmd3.Execute();
                HystrixCommand <Boolean> cmd4 = new TimeoutCommand(key);
                cmd4.Execute();

                // everything has failed in the test window so we should return false now
                output.WriteLine("!!!! 1 4 failures, circuit will open on recalc");
                Time.Wait(150);

                Assert.False(cb.AllowRequest);
                Assert.True(cb.IsOpen);

                // wait for sleepWindow to pass
                output.WriteLine("!!!! 2 Sleep window starting where all commands fail-fast");
                Time.Wait(sleepWindow + 50);
                output.WriteLine("!!!! 3 Sleep window over, should allow singleTest()");

                // but the circuit should still be open
                Assert.True(cb.IsOpen);

                // we should now allow 1 request, and upon failure, should not affect the circuit breaker, which should remain open
                HystrixCommand <bool> cmd5         = new FailureCommand(key, 60);
                IObservable <bool>    asyncResult5 = cmd5.Observe();
                output.WriteLine("!!!! Kicked off the single-test");

                // and further requests are still blocked while the singleTest command is in flight
                Assert.False(cb.AllowRequest);
                output.WriteLine("!!!! Confirmed that no other requests go out during single-test");

                await asyncResult5.SingleAsync();

                output.WriteLine("!!!! SingleTest just completed");

                // all requests should still be blocked, because the singleTest failed
                Assert.False(cb.AllowRequest);
                Assert.False(cb.AllowRequest);
                Assert.False(cb.AllowRequest);

                // wait for sleepWindow to pass
                output.WriteLine("!!!! 2nd sleep window START");
                Time.Wait(sleepWindow + 50);
                output.WriteLine("!!!! 2nd sleep window over");

                // we should now allow 1 request, and upon failure, should not affect the circuit breaker, which should remain open
                HystrixCommand <bool> cmd6         = new FailureCommand(key, 60);
                IObservable <bool>    asyncResult6 = cmd6.Observe();
                output.WriteLine("2nd singleTest just kicked off");

                //and further requests are still blocked while the singleTest command is in flight
                Assert.False(cb.AllowRequest);
                output.WriteLine("confirmed that 2nd singletest only happened once");

                await asyncResult6.SingleAsync();

                output.WriteLine("2nd singleTest now over");

                // all requests should still be blocked, because the singleTest failed
                Assert.False(cb.AllowRequest);
                Assert.False(cb.AllowRequest);
                Assert.False(cb.AllowRequest);

                // wait for sleepWindow to pass
                Time.Wait(sleepWindow + 50);

                // but the circuit should still be open
                Assert.True(cb.IsOpen);

                // we should now allow 1 request, and upon success, should cause the circuit to be closed
                HystrixCommand <bool> cmd7         = new SuccessCommand(key, 60);
                IObservable <bool>    asyncResult7 = cmd7.Observe();

                // and further requests are still blocked while the singleTest command is in flight
                Assert.False(cb.AllowRequest);

                await asyncResult7.SingleAsync();

                // all requests should be open again
                Assert.True(cb.AllowRequest);
                Assert.True(cb.AllowRequest);
                Assert.True(cb.AllowRequest);
                // and the circuit should be closed again
                Assert.False(cb.IsOpen);

                // and the circuit should be closed again
                Assert.False(cb.IsOpen);
            }
            catch (Exception e)
            {
                output.WriteLine(e.ToString());
                Assert.False(true, "Error occurred: " + e.Message);
            }
        }