public void TestTripCircuitOnTimeouts()
        {
            var             properties = GetCommandConfig();
            ICommandMetrics metrics    = GetMetrics(properties);
            var             cb         = new TestCircuitBreaker(properties, metrics);

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

            metrics.MarkTimeout();
            metrics.MarkTimeout();
            metrics.MarkTimeout();
            metrics.MarkTimeout();
            Thread.Sleep(properties.MetricsHealthSnapshotIntervalInMilliseconds);


            // this should remain open as the failure threshold is below the percentage limit
            Assert.IsFalse(cb.AllowRequest());
            Assert.IsTrue(cb.IsOpen());
        }
        public void TestGetErrorPercentage()
        {
            var config = GetCommandConfig();

            ICommandMetrics metrics = GetMetrics(config);

            metrics.MarkSuccess(1000);
            Thread.Sleep(config.MetricsHealthSnapshotIntervalInMilliseconds);
            Assert.AreEqual(0, metrics.GetErrorPercentage());

            metrics.MarkFailure();
            Thread.Sleep(config.MetricsHealthSnapshotIntervalInMilliseconds);

            Assert.AreEqual(50, metrics.GetErrorPercentage());

            metrics.MarkSuccess(100);
            metrics.MarkSuccess(100);
            Thread.Sleep(config.MetricsHealthSnapshotIntervalInMilliseconds);
            Assert.AreEqual(25, metrics.GetErrorPercentage());

            metrics.MarkTimeout(5000);
            metrics.MarkTimeout(5000);
            Thread.Sleep(config.MetricsHealthSnapshotIntervalInMilliseconds);
            Assert.AreEqual(50, metrics.GetErrorPercentage());

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

            // latent
            Thread.Sleep(config.MetricsHealthSnapshotIntervalInMilliseconds);
            metrics.MarkSuccess(5000);
            Thread.Sleep(config.MetricsHealthSnapshotIntervalInMilliseconds);

            // 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.GetErrorPercentage());
        }
        public void TestTripCircuitOnTimeoutsAboveThreshold()
        {
            var             properties = GetCommandConfig();
            ICommandMetrics metrics    = GetMetrics(properties);
            var             cb         = new TestCircuitBreaker(properties, metrics);

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


            metrics.MarkSuccess();
            metrics.MarkSuccess();
            metrics.MarkSuccess();
            metrics.MarkTimeout();
            metrics.MarkTimeout();
            metrics.MarkTimeout();
            metrics.MarkTimeout();

            Thread.Sleep(properties.MetricsHealthSnapshotIntervalInMilliseconds);
            // this should trip the circuit as the error percentage is above the threshold
            Assert.IsFalse(cb.AllowRequest());
            Assert.IsTrue(cb.IsOpen());
        }