AwaitedLocksCollection { public AsyncResult<Void> getExistingOrAwait( UUID requestId, Supplier<AsyncResult<Void>> lockAwaiter) { AsyncResult<Void> result = requestsById.computeIfAbsent( requestId, ignored -> lockAwaiter.get()); registerCompletionHandler(requestId, result); return result; }  AsyncResult<Void> getExistingOrAwait(
            UUID requestId,
            Supplier<AsyncResult<Void>> lockAwaiter);  }
@Test public void callsSupplierForNewRequests() { Supplier<AsyncResult<Void>> supplier = mock(Supplier.class); when(supplier.get()).thenReturn(new AsyncResult<>()); awaitedLocks.getExistingOrAwait(REQUEST_1, supplier); awaitedLocks.getExistingOrAwait(REQUEST_2, supplier); verify(supplier, times(2)).get(); }
@Test public void doesNotCallSupplierForExistingRequest() { awaitedLocks.getExistingOrAwait(REQUEST_1, () -> new AsyncResult<>()); Supplier<AsyncResult<Void>> supplier = mock(Supplier.class); awaitedLocks.getExistingOrAwait(REQUEST_1, supplier); verifyNoMoreInteractions(supplier); }
@Test public void removesRequestWhenComplete() { AsyncResult<Void> result = new AsyncResult<>(); awaitedLocks.getExistingOrAwait(REQUEST_1, () -> result); assertThat(awaitedLocks.requestsById).containsKey(REQUEST_1); result.complete(null); assertRequestsWereRemoved(REQUEST_1); }
@Test public void removesRequestIfCompleteSynchronously() { AsyncResult<Void> result = AsyncResult.completedResult(); awaitedLocks.getExistingOrAwait(REQUEST_1, () -> result); assertRequestsWereRemoved(REQUEST_1); }
@Test public void removesRequestIfSupplierThrows() { assertThatThrownBy(() -> awaitedLocks.getExistingOrAwait(REQUEST_1, () -> { throw new RuntimeException("foo"); })).isInstanceOf(RuntimeException.class); assertRequestsWereRemoved(REQUEST_1); }
@Test public void removesRequestWhenFailedOrTimesOut() { AsyncResult<Void> result1 = new AsyncResult<>(); AsyncResult<Void> result2 = new AsyncResult<>(); awaitedLocks.getExistingOrAwait(REQUEST_1, () -> result1); awaitedLocks.getExistingOrAwait(REQUEST_1, () -> result2); result1.fail(new RuntimeException("test")); result2.timeout(); assertRequestsWereRemoved(REQUEST_1, REQUEST_2); }