@Test
public void testFallbackSemaphore() throws Exception {

    TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    // single thread should work
    TestSemaphoreCommandWithSlowFallback command1 = new TestSemaphoreCommandWithSlowFallback(circuitBreaker, 1, 200);
    boolean result = command1.queue().get();
    assertTrue(result);
    // 2 threads, the second should be rejected by the fallback semaphore
    boolean exceptionReceived = false;
    Future<Boolean> result2 = null;
    TestSemaphoreCommandWithSlowFallback command2 = null;
    TestSemaphoreCommandWithSlowFallback command3 = null;
    try {
        System.out.println("c2 start: " + System.currentTimeMillis());
        command2 = new TestSemaphoreCommandWithSlowFallback(circuitBreaker, 1, 800);
        result2 = command2.queue();
        System.out.println("c2 after queue: " + System.currentTimeMillis());
        // make sure that thread gets a chance to run before queuing the next one
        Thread.sleep(50);
        System.out.println("c3 start: " + System.currentTimeMillis());
        command3 = new TestSemaphoreCommandWithSlowFallback(circuitBreaker, 1, 200);
        Future<Boolean> result3 = command3.queue();
        System.out.println("c3 after queue: " + System.currentTimeMillis());
        result3.get();
    } catch (Exception e) {
        e.printStackTrace();
        exceptionReceived = true;
    }
    assertTrue(result2.get());
    if (!exceptionReceived) {
        fail("We expected an exception on the 2nd get");
    }
    assertCommandExecutionEvents(command1, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_SUCCESS);
    assertCommandExecutionEvents(command2, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_SUCCESS);
    assertCommandExecutionEvents(command3, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_REJECTION);
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(3);
}