/* * * Copyright 2017 Oleksandr Goldobin * * 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 io.github.resilience4j.prometheus; import org.junit.Test; import java.util.function.Supplier; import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException; import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; import io.github.resilience4j.circuitbreaker.internal.InMemoryCircuitBreakerRegistry; import io.prometheus.client.CollectorRegistry; import io.vavr.Tuple; import io.vavr.collection.HashMap; import io.vavr.collection.HashSet; import io.vavr.collection.Map; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; public class CircuitBreakerExportsTest { @Test public void testExportsCircuitBreakerStates() { // Given final CollectorRegistry registry = new CollectorRegistry(); final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("foo"); CircuitBreakerExports.ofIterable("boo_circuit_breaker", singletonList(circuitBreaker)).register(registry); final Supplier<Map<String, Double>> values = () -> HashSet .of("closed", "open", "half_open") .map(state -> Tuple.of(state, registry.getSampleValue( "boo_circuit_breaker_states", new String[]{ "name", "state" }, new String[]{ "foo", state}))) .toMap(t -> t); // When final Map<String, Double> closedStateValues = values.get(); circuitBreaker.transitionToOpenState(); final Map<String, Double> openStateValues = values.get(); circuitBreaker.transitionToHalfOpenState(); final Map<String, Double> halfOpenStateValues = values.get(); circuitBreaker.transitionToClosedState(); final Map<String, Double> closedStateValues2 = values.get(); // Then assertThat(closedStateValues).isEqualTo(HashMap.of( "closed", 1.0, "open", 0.0, "half_open", 0.0)); assertThat(openStateValues).isEqualTo(HashMap.of( "closed", 0.0, "open", 1.0, "half_open", 0.0)); assertThat(halfOpenStateValues).isEqualTo(HashMap.of( "closed", 0.0, "open", 0.0, "half_open", 1.0)); assertThat(closedStateValues2).isEqualTo(HashMap.of( "closed", 1.0, "open", 0.0, "half_open", 0.0)); } @Test public void testExportsCircuitBreakerMetrics() { // Given final CollectorRegistry registry = new CollectorRegistry(); final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("foo"); CircuitBreakerExports.ofIterable("boo_circuit_breaker", singletonList(circuitBreaker)).register(registry); final Supplier<Map<String, Double>> values = () -> HashSet .of("successful", "failed", "not_permitted", "buffered", "buffered_max") .map(callType -> Tuple.of(callType, registry.getSampleValue( "boo_circuit_breaker_calls", new String[]{ "name", "call_result" }, new String[]{ "foo", callType}))) .toMap(t -> t); // When final Map<String, Double> initialValues = values.get(); circuitBreaker.executeRunnable(() -> {}); final Map<String, Double> afterSuccessValues = values.get(); try { circuitBreaker.executeRunnable(() -> { throw new SomeAppException("Some exception"); }); } catch (RuntimeException e) { // expected } final Map<String, Double> afterFailureValues = values.get(); circuitBreaker.transitionToOpenState(); try { circuitBreaker.executeRunnable(() -> {}); } catch (CircuitBreakerOpenException e) { // expected } final Map<String, Double> afterDeclinedValues = values.get(); // Then assertThat(initialValues).isEqualTo(HashMap.of( "successful", 0.0, "failed", 0.0, "not_permitted", 0.0, "buffered", 0.0, "buffered_max", 100.0)); assertThat(afterSuccessValues).isEqualTo(HashMap.of( "successful", 1.0, "failed", 0.0, "not_permitted", 0.0, "buffered", 1.0, "buffered_max", 100.0)); assertThat(afterFailureValues).isEqualTo(HashMap.of( "successful", 1.0, "failed", 1.0, "not_permitted", 0.0, "buffered", 2.0, "buffered_max", 100.0)); assertThat(afterDeclinedValues).isEqualTo(HashMap.of( "successful", 1.0, "failed", 1.0, "not_permitted", 1.0, "buffered", 2.0, "buffered_max", 100.0)); } @Test public void testConstructors() { final CircuitBreakerRegistry registry = new InMemoryCircuitBreakerRegistry(); CircuitBreakerExports.ofIterable("boo_breakers", singleton(CircuitBreaker.ofDefaults("foo"))); CircuitBreakerExports.ofCircuitBreakerRegistry("boo_breakers", registry); CircuitBreakerExports.ofSupplier("boo_breakers", () -> singleton(CircuitBreaker.ofDefaults("foo"))); CircuitBreakerExports.ofIterable(singleton(CircuitBreaker.ofDefaults("foo"))); CircuitBreakerExports.ofCircuitBreakerRegistry(registry); CircuitBreakerExports.ofSupplier(() -> singleton(CircuitBreaker.ofDefaults("foo"))); } @Test(expected = NullPointerException.class) public void testConstructorWithNullName() { CircuitBreakerExports.ofCircuitBreaker(null, CircuitBreaker.ofDefaults("foo")); } @Test(expected = NullPointerException.class) public void testConstructorWithNullSupplier() { CircuitBreakerExports.ofCircuitBreaker("boo_breakers", null); } private static class SomeAppException extends RuntimeException { SomeAppException(String message) { super(message); } } }