@Test
public void testFailedTasks()
        throws Exception
{

    AsyncSemaphore<Runnable> asyncSemaphore = new AsyncSemaphore<>(2, executor, executor::submit);
    final AtomicInteger successCount = new AtomicInteger();
    final AtomicInteger failureCount = new AtomicInteger();
    final AtomicInteger concurrency = new AtomicInteger();
    final CountDownLatch completionLatch = new CountDownLatch(1000);
    List<ListenableFuture<?>> futures = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        ListenableFuture<?> future = asyncSemaphore.submit(() -> assertFailedConcurrency(concurrency));
        addCallback(future, completionCallback(successCount, failureCount, completionLatch), directExecutor());
        futures.add(future);
    }
    // Wait for all tasks and callbacks to complete
    completionLatch.await(1, TimeUnit.MINUTES);
    for (ListenableFuture<?> future : futures) {
        try {
            future.get();
            Assert.fail();
        }
        catch (Exception ignored) {
        }
    }
    Assert.assertEquals(successCount.get(), 0);
    Assert.assertEquals(failureCount.get(), 1000);
}