/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package net.jodah.failsafe.internal;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import net.jodah.failsafe.CircuitBreaker;
import net.jodah.failsafe.Testing;
import net.jodah.failsafe.internal.HalfOpenState;
@Test
public class HalfOpenStateTest {
/**
* Asserts that the the circuit is opened after a single failure.
*/
public void testFailureWithDefaultConfig() {
// Given
CircuitBreaker breaker = new CircuitBreaker();
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
// When
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the the circuit is opened after the failure ratio is met.
*/
public void testFailureWithFailureRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(2, 3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
assertFalse(breaker.isOpen());
// When
state.recordFailure();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the the circuit is opened after the failure threshold is met.
*/
public void testFailureWithFailureThreshold() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
for (int i = 0; i < 3; i++) {
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordFailure();
}
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the circuit is opened after the success ratio fails to be met. The failure ratio is ignored.
*/
public void testFailureWithSuccessAndFailureRatios() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(3, 5).withSuccessThreshold(3, 4);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordSuccess();
state.recordFailure();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the circuit is opened after a single failure. The failure threshold is ignored.
*/
public void testFailureWithSuccessAndFailureThresholds() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(3).withFailureThreshold(2);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordSuccess();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the circuit is opened after the success ratio fails to be met.
*/
public void testFailureWithSuccessRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(2, 3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
assertFalse(breaker.isOpen());
// When
state.recordFailure();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the circuit is opened after the success ratio fails to be met. The failure threshold is ignored.
*/
public void testFailureWithSuccessRatioAndFailureThreshold() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(2, 4).withFailureThreshold(1);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordSuccess();
state.recordFailure();
state.recordFailure();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the circuit is opened after a single failure.
*/
public void testFailureWithSuccessThreshold() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
// When
state.recordSuccess();
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the circuit is opened after a single failure.
*/
public void testFailureWithSuccessThresholdAndFailureRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(3, 5).withSuccessThreshold(3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
// When
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the the circuit is closed after a single success.
*/
public void testSuccessWithDefaultConfig() {
// Given
CircuitBreaker breaker = new CircuitBreaker();
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
// When
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the the circuit is closed after the failure ratio fails to be met.
*/
public void testSuccessWithFailureRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(2, 3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordFailure();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the the circuit is closed after a single success.
*/
public void testSuccessWithFailureThreshold() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
// When
state.recordFailure();
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the circuit is closed after the success ratio is met. The failure ratio is ignored.
*/
public void testSuccessWithSuccessAndFailureRatios() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(3, 5).withSuccessThreshold(3, 4);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordSuccess();
state.recordFailure();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the circuit is closed after the success threshold is met. The failure threshold is ignored.
*/
public void testSuccessWithSuccessAndFailureThresholds() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(3).withFailureThreshold(2);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordSuccess();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the circuit is closed after the success ratio is met.
*/
public void testSuccessWithSuccessRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(2, 3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordFailure();
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the circuit is closed after the success ratio is met. The failure threshold is ignored.
*/
public void testSuccessWithSuccessRatioAndFailureThreshold() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(3, 4).withFailureThreshold(2);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
state.recordSuccess();
state.recordSuccess();
state.recordFailure();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the circuit is closed after the success threshold is met.
*/
public void testSuccessWithSuccessThreshold() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withSuccessThreshold(3);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When
for (int i = 0; i < 3; i++) {
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordSuccess();
}
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the circuit is closed after the success threshold is met. The failure ratio is ignored.
*/
public void testSuccessWithSuccessThresholdAndFailureRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker().withFailureThreshold(3, 5).withSuccessThreshold(2);
breaker.halfOpen();
HalfOpenState state = new HalfOpenState(breaker);
// When success threshold exceeded
state.recordSuccess();
assertFalse(breaker.isOpen());
assertFalse(breaker.isClosed());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
/**
* Asserts that the late configuration of a failure ratio is handled by resetting the state's internal tracking. Also
* asserts that executions from prior configurations are carried over to a new configuration.
*/
public void shouldHandleLateSetFailureRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker();
breaker.halfOpen();
HalfOpenState state = Testing.stateFor(breaker);
// When
breaker.withFailureThreshold(2);
state.recordFailure();
assertTrue(breaker.isHalfOpen());
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
// Given
breaker = new CircuitBreaker().withFailureThreshold(3);
breaker.halfOpen();
state = Testing.stateFor(breaker);
// When
state.recordFailure();
state.recordFailure();
breaker.withFailureThreshold(3, 5);
state.recordSuccess();
state.recordSuccess();
assertTrue(breaker.isHalfOpen());
state.recordFailure();
// Then
assertTrue(breaker.isOpen());
}
/**
* Asserts that the late configuration of a success ratio is handled by resetting the state's internal tracking. Also
* asserts that executions from prior configurations are carried over to a new configuration.
*/
public void shouldHandleLateSetSucessRatio() {
// Given
CircuitBreaker breaker = new CircuitBreaker();
breaker.halfOpen();
HalfOpenState state = Testing.stateFor(breaker);
// When
breaker.withSuccessThreshold(2);
state.recordSuccess();
assertTrue(breaker.isHalfOpen());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
// Given
breaker = new CircuitBreaker().withFailureThreshold(3);
breaker.halfOpen();
state = Testing.stateFor(breaker);
// When
state.recordFailure();
state.recordFailure();
breaker.withSuccessThreshold(2, 4);
state.recordSuccess();
assertTrue(breaker.isHalfOpen());
state.recordSuccess();
// Then
assertTrue(breaker.isClosed());
}
}