@Test
@InSequence(3)
public void callCountedMethodOnce() throws InterruptedException, TimeoutException {

    Counter counter = registry.getCounter(counterMetricID);
    assertThat("Counter is not registered correctly", counter, notNullValue());
    // Call the counted method, block and assert it's been counted
    final Exchanger<Long> exchanger = new Exchanger<>();
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                exchanger.exchange(bean.countedMethod(new Callable<Long>() {
                    @Override
                    public Long call() throws Exception {
                        exchanger.exchange(0L);
                        return exchanger.exchange(0L);
                    }
                }));
            }
            catch (InterruptedException cause) {
                throw new RuntimeException(cause);
            }
        }
    });
    final AtomicInteger uncaught = new AtomicInteger();
    thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            e.printStackTrace();
            uncaught.incrementAndGet();
        }
    });
    thread.start();
    // Wait until the method is executing and make sure that the counter has been incremented
    exchanger.exchange(0L, 5L, TimeUnit.SECONDS);
    assertThat("Counter count is incorrect", counter.getCount(), is(equalTo(COUNTER_COUNT.incrementAndGet())));
    // Exchange the result and unblock the method execution
    Long random = 1 + Math.round(Math.random() * (Long.MAX_VALUE - 1));
    exchanger.exchange(random, 5L, TimeUnit.SECONDS);
    // Wait until the method has returned
    assertThat("Counted method return value is incorrect", exchanger.exchange(0L), is(equalTo(random)));
    // Then make sure that the counter has not been decremented
    assertThat("Counter count is incorrect", counter.getCount(), is(equalTo(COUNTER_COUNT.get())));
    // Finally make sure calling thread is returns correctly
    thread.join();
    assertThat("Exception thrown in method call thread", uncaught.get(), is(equalTo(0)));
}