@Test
  public void queueRejectionWithBlockingQueue() throws Exception {
    final int queueMaxSize = 5;
    final TenacityConfiguration exampleConfiguration =
        new TenacityConfiguration(
            new ThreadPoolConfiguration(1, 1, 10, queueMaxSize, 10000, 10),
            new CircuitBreakerConfiguration(20, 5000, 50, 10000, 10),
            5000);

    final TenacityPropertyRegister tenacityPropertyRegister =
        new TenacityPropertyRegister(
            ImmutableMap.<TenacityPropertyKey, TenacityConfiguration>of(
                DependencyKey.SLEEP, exampleConfiguration),
            new BreakerboxConfiguration(),
            mock(ArchaiusPropertyRegister.class));

    tenacityPropertyRegister.register();

    final ImmutableList.Builder<Future<Optional<String>>> sleepCommands = ImmutableList.builder();
    for (int i = 0; i < queueMaxSize * 2; i++) {
      sleepCommands.add(new SleepCommand(DependencyKey.SLEEP).queue());
    }

    for (Future<Optional<String>> future : sleepCommands.build()) {
      assertFalse(future.isCancelled());
      final Optional<String> result = future.get();
      if (result.isPresent()) {
        assertThat(result.get()).isEqualTo("sleep");
      } else {
        assertThat(result).isEqualTo(Optional.<String>absent());
      }
    }

    final HystrixCommandMetrics sleepCommandMetrics =
        new SleepCommand(DependencyKey.SLEEP).getCommandMetrics();
    assertThat(
            sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED))
        .isEqualTo(4);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.TIMEOUT))
        .isEqualTo(0);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS))
        .isEqualTo(4);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.SHORT_CIRCUITED))
        .isEqualTo(0);

    final HystrixThreadPoolProperties threadPoolProperties =
        new SleepCommand(DependencyKey.SLEEP).getThreadpoolProperties();

    final ThreadPoolConfiguration threadPoolConfiguration = exampleConfiguration.getThreadpool();
    assertEquals(
        threadPoolProperties.queueSizeRejectionThreshold().get().intValue(),
        threadPoolConfiguration.getQueueSizeRejectionThreshold());
    assertEquals(
        threadPoolProperties.maxQueueSize().get().intValue(),
        threadPoolConfiguration.getMaxQueueSize());

    assertEquals(
        TenacityPropertyStore.getTenacityConfiguration(DependencyKey.SLEEP), exampleConfiguration);
  }
  @Test
  public void queueRejectionWithSynchronousQueue() throws Exception {
    final ImmutableCollection.Builder<Future<Optional<String>>> futures = ImmutableList.builder();
    for (int i = 0; i < 50; i++) {
      futures.add(new SleepCommand(DependencyKey.EXAMPLE).queue());
    }

    for (Future<Optional<String>> future : futures.build()) {
      assertFalse(future.isCancelled());
      final Optional<String> result = future.get();
      if (result.isPresent()) {
        assertThat(result.get()).isEqualTo("sleep");
      } else {
        assertThat(result).isEqualTo(Optional.<String>absent());
      }
    }

    final HystrixCommandMetrics sleepCommandMetrics =
        new SleepCommand(DependencyKey.EXAMPLE).getCommandMetrics();
    assertThat(
            sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED))
        .isGreaterThan(15);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.TIMEOUT))
        .isEqualTo(0);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS))
        .isGreaterThanOrEqualTo(40);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.FALLBACK_FAILURE))
        .isEqualTo(0);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.FALLBACK_REJECTION))
        .isEqualTo(0);
    assertThat(sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.SHORT_CIRCUITED))
        .isEqualTo(
            sleepCommandMetrics.getCumulativeCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS)
                - sleepCommandMetrics.getCumulativeCount(
                    HystrixRollingNumberEvent.THREAD_POOL_REJECTED));

    final HystrixThreadPoolProperties threadPoolProperties =
        new SleepCommand(DependencyKey.EXAMPLE).getThreadpoolProperties();

    // -1 means no limit on the number of items in the queue, which uses the
    // SynchronousBlockingQueue
    assertEquals(threadPoolProperties.maxQueueSize().get().intValue(), -1);
    assertEquals(
        TenacityPropertyStore.getTenacityConfiguration(DependencyKey.EXAMPLE),
        new TenacityConfiguration());
  }
  @Test
  public void overriddenProperties() throws Exception {
    final TenacityConfiguration overrideConfiguration =
        new TenacityConfiguration(
            new ThreadPoolConfiguration(50, 3, 27, 57, 2000, 20),
            new CircuitBreakerConfiguration(1, 2, 3, 2000, 20),
            982);

    final TenacityPropertyRegister tenacityPropertyRegister =
        new TenacityPropertyRegister(
            ImmutableMap.<TenacityPropertyKey, TenacityConfiguration>of(
                DependencyKey.OVERRIDE, overrideConfiguration),
            new BreakerboxConfiguration(),
            mock(ArchaiusPropertyRegister.class));

    tenacityPropertyRegister.register();

    assertEquals(new TenacitySuccessCommand(DependencyKey.OVERRIDE).execute(), "value");
    assertEquals(new TenacitySuccessCommand(DependencyKey.OVERRIDE).queue().get(), "value");

    final TenacitySuccessCommand successCommand =
        new TenacitySuccessCommand(DependencyKey.OVERRIDE);

    assertNotEquals(
        new TenacitySuccessCommand()
            .getCommandProperties()
            .executionIsolationThreadTimeoutInMilliseconds(),
        overrideConfiguration.getExecutionIsolationThreadTimeoutInMillis());

    final HystrixCommandProperties commandProperties = successCommand.getCommandProperties();
    assertEquals(
        commandProperties.executionIsolationThreadTimeoutInMilliseconds().get().intValue(),
        overrideConfiguration.getExecutionIsolationThreadTimeoutInMillis());
    assertEquals(
        commandProperties.circuitBreakerErrorThresholdPercentage().get().intValue(),
        overrideConfiguration.getCircuitBreaker().getErrorThresholdPercentage());
    assertEquals(
        commandProperties.circuitBreakerRequestVolumeThreshold().get().intValue(),
        overrideConfiguration.getCircuitBreaker().getRequestVolumeThreshold());
    assertEquals(
        commandProperties.circuitBreakerSleepWindowInMilliseconds().get().intValue(),
        overrideConfiguration.getCircuitBreaker().getSleepWindowInMillis());
    assertEquals(
        commandProperties.metricsRollingStatisticalWindowBuckets().get().intValue(),
        overrideConfiguration.getCircuitBreaker().getMetricsRollingStatisticalWindowBuckets());
    assertEquals(
        commandProperties.metricsRollingStatisticalWindowInMilliseconds().get().intValue(),
        overrideConfiguration
            .getCircuitBreaker()
            .getMetricsRollingStatisticalWindowInMilliseconds());

    final HystrixThreadPoolProperties threadPoolProperties =
        successCommand.getThreadpoolProperties();
    final ThreadPoolConfiguration threadPoolConfiguration = overrideConfiguration.getThreadpool();
    assertEquals(
        threadPoolProperties.coreSize().get().intValue(),
        threadPoolConfiguration.getThreadPoolCoreSize());
    assertEquals(
        threadPoolProperties.keepAliveTimeMinutes().get().intValue(),
        threadPoolConfiguration.getKeepAliveTimeMinutes());
    assertEquals(
        threadPoolProperties.maxQueueSize().get().intValue(),
        threadPoolConfiguration.getMaxQueueSize());
    assertEquals(
        threadPoolProperties.metricsRollingStatisticalWindowBuckets().get().intValue(),
        threadPoolConfiguration.getMetricsRollingStatisticalWindowBuckets());
    assertEquals(
        threadPoolProperties.metricsRollingStatisticalWindowInMilliseconds().get().intValue(),
        threadPoolConfiguration.getMetricsRollingStatisticalWindowInMilliseconds());
    assertEquals(
        threadPoolProperties.queueSizeRejectionThreshold().get().intValue(),
        threadPoolConfiguration.getQueueSizeRejectionThreshold());

    assertEquals(
        TenacityPropertyStore.getTenacityConfiguration(DependencyKey.OVERRIDE),
        overrideConfiguration);
  }