private CircuitBreakerMetrics(int slidingWindowSize,
        CircuitBreakerConfig.SlidingWindowType slidingWindowType,
        CircuitBreakerConfig circuitBreakerConfig,
        Clock clock) {
        if (slidingWindowType == CircuitBreakerConfig.SlidingWindowType.COUNT_BASED) {
            this.metrics = new FixedSizeSlidingWindowMetrics(slidingWindowSize);
            this.minimumNumberOfCalls = Math
                .min(circuitBreakerConfig.getMinimumNumberOfCalls(), slidingWindowSize);
        } else {
            this.metrics = new SlidingTimeWindowMetrics(slidingWindowSize, clock);
            this.minimumNumberOfCalls = circuitBreakerConfig.getMinimumNumberOfCalls();
        }
        this.failureRateThreshold = circuitBreakerConfig.getFailureRateThreshold();
        this.slowCallRateThreshold = circuitBreakerConfig.getSlowCallRateThreshold();
        this.slowCallDurationThresholdInNanos = circuitBreakerConfig.getSlowCallDurationThreshold()
            .toNanos();
        this.numberOfNotPermittedCalls = new LongAdder();
    }
@Test
    public void testCircuitBreakerMetrics() {
        CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
            .slidingWindow(10, 10, CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
            .build();

        CircuitBreakerMetrics circuitBreakerMetrics = CircuitBreakerMetrics
            .forClosed(circuitBreakerConfig, MockClock.at(2019, 1, 1, 12, 0, 0, ZoneId.of("UTC")));

        circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onError(0, TimeUnit.NANOSECONDS);
        Result result = circuitBreakerMetrics.onError(0, TimeUnit.NANOSECONDS);

        circuitBreakerMetrics.onCallNotPermitted();
        circuitBreakerMetrics.onCallNotPermitted();

        assertThat(circuitBreakerMetrics.getNumberOfBufferedCalls()).isEqualTo(4);
        assertThat(circuitBreakerMetrics.getNumberOfFailedCalls()).isEqualTo(2);
        assertThat(circuitBreakerMetrics.getNumberOfSuccessfulCalls()).isEqualTo(2);
        assertThat(circuitBreakerMetrics.getNumberOfNotPermittedCalls()).isEqualTo(2);

        // The failure rate must be -1, because the number of measured calls is below the buffer size of 10
        assertThat(circuitBreakerMetrics.getFailureRate()).isEqualTo(-1);
        assertThat(result)
            .isEqualTo(CircuitBreakerMetrics.Result.BELOW_MINIMUM_CALLS_THRESHOLD);

        circuitBreakerMetrics.onError(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onError(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onError(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onError(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        result = circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);

        // 12 calls have been recorded, but only 10 are stored in the sliding window. 4 successes and 6 failures.
        // The failure rate must be 60%, because the number of measured calls is above the minimum number of measured calls.
        assertThat(circuitBreakerMetrics.getNumberOfBufferedCalls()).isEqualTo(10);
        assertThat(circuitBreakerMetrics.getNumberOfFailedCalls()).isEqualTo(6);
        assertThat(circuitBreakerMetrics.getNumberOfSuccessfulCalls()).isEqualTo(4);
        assertThat(circuitBreakerMetrics.getFailureRate()).isEqualTo(60);
        assertThat(Result.hasExceededThresholds(result)).isTrue();

        circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        result = circuitBreakerMetrics.onSuccess(0, TimeUnit.NANOSECONDS);
        assertThat(result).isEqualTo(CircuitBreakerMetrics.Result.BELOW_THRESHOLDS);
        assertThat(circuitBreakerMetrics.getFailureRate()).isEqualTo(30);


    }