@Test @Timeout(1000L) void enqueue_blocksOnCompletion() throws InterruptedException {
    CountDownLatch callsLatch = new CountDownLatch(10);
    ExecutorService exec = Executors.newFixedThreadPool(10);

    class LatchCall extends Call.Base<Void> {
      final boolean fail;

      LatchCall(boolean fail) {
        this.fail = fail;
      }

      @Override protected Void doExecute() {
        throw new UnsupportedOperationException();
      }

      @Override protected void doEnqueue(Callback<Void> callback) {
        exec.submit(() -> {
          try {
            callsLatch.await();
          } catch (InterruptedException e) {
            callback.onError(e);
          }
          if (fail) {
            callback.onError(new IOException());
          } else {
            callback.onSuccess(null);
          }
        });
      }

      @Override public Call<Void> clone() {
        return new LatchCall(fail);
      }
    }

    List<Call<Void>> calls = new ArrayList<>();
    for (int i = 0; i < 10; i++) calls.add(new LatchCall(i % 2 == 0));
    Call<Void> call = AggregateCall.newVoidCall(calls);

    AtomicReference<Object> result = new AtomicReference<>();
    call.enqueue(new Callback<Void>() {
      @Override public void onSuccess(Void value) {
        result.set("foo");
      }

      @Override public void onError(Throwable t) {
        result.set(t);
      }
    });

    assertThat(result).hasValue(null);
    callsLatch.countDown(); // one down
    assertThat(result).hasValue(null);
    callsLatch.countDown(); // two down
    assertThat(result).hasValue(null);
    for (int i = 0; i < 8; i++) callsLatch.countDown();

    // wait for threads to finish
    exec.shutdown();
    exec.awaitTermination(1, TimeUnit.SECONDS);

    assertThat(result.get()).isNotNull();
  }
This shows that regardless of success or error, we block on completion
zipkin/src/test/java/zipkin2/internal/AggregateCallTest.java