public virtual void testCircuitClosedAfterSuccessAndClearsStatisticalWindow() { int statisticalWindow = 200; int sleepWindow = 10; // this is set very low so that returning from a retry still ends up having data in the buckets for the statisticalWindow var properties = GetCommandConfig(); properties.CircuitBreakerSleepWindowInMilliseconds = sleepWindow; properties.MetricsRollingStatisticalWindowInMilliseconds = statisticalWindow; ICommandMetrics metrics = GetMetrics(properties); var cb = new TestCircuitBreaker(properties, metrics); // fail metrics.MarkFailure(); metrics.MarkFailure(); metrics.MarkFailure(); metrics.MarkFailure(); // 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(); 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()); }
public void TestMultipleTimeWindowRetriesBeforeClosingCircuit() { int sleepWindow = 200; var properties = GetCommandConfig(); properties.CircuitBreakerSleepWindowInMilliseconds = sleepWindow; ICommandMetrics metrics = GetMetrics(properties); var cb = new TestCircuitBreaker(properties, metrics); // fail metrics.MarkFailure(); metrics.MarkFailure(); metrics.MarkFailure(); metrics.MarkFailure(); // 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' fails so it should go back to sleep and not allow any requests again until another 'singleTest' after the sleep metrics.MarkFailure(); Assert.IsFalse(cb.AllowRequest()); Assert.IsFalse(cb.AllowRequest()); Assert.IsFalse(cb.AllowRequest()); // 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' fails again so it should go back to sleep and not allow any requests again until another 'singleTest' after the sleep metrics.MarkFailure(); Assert.IsFalse(cb.AllowRequest()); Assert.IsFalse(cb.AllowRequest()); Assert.IsFalse(cb.AllowRequest()); // 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()); // now it finally succeeds metrics.MarkSuccess(); 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()); }