@Test
  public void testAccept() throws ExecutionException, InterruptedException, IOException {
    try (MultithreadedExecutor multithreadedExecutor = new MultithreadedExecutor()) {
      DoubleAccumulator maxProgress = new DoubleAccumulator(Double::max, 0);

      ProgressEventHandler progressEventHandler =
          new ProgressEventHandler(update -> maxProgress.accumulate(update.getProgress()));
      EventHandlers eventHandlers =
          EventHandlers.builder().add(ProgressEvent.class, progressEventHandler).build();

      // Adds root, child1, and child1Child.
      multithreadedExecutor.invoke(
          () -> {
            eventHandlers.dispatch(new ProgressEvent(AllocationTree.root, 0L));
            return null;
          });
      multithreadedExecutor.invoke(
          () -> {
            eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1, 0L));
            return null;
          });
      multithreadedExecutor.invoke(
          () -> {
            eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1Child, 0L));
            return null;
          });
      Assert.assertEquals(0.0, maxProgress.get(), DOUBLE_ERROR_MARGIN);

      // Adds 50 to child1Child and 100 to child2.
      List<Callable<Void>> callables = new ArrayList<>(150);
      callables.addAll(
          Collections.nCopies(
              50,
              () -> {
                eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1Child, 1L));
                return null;
              }));
      callables.addAll(
          Collections.nCopies(
              100,
              () -> {
                eventHandlers.dispatch(new ProgressEvent(AllocationTree.child2, 1L));
                return null;
              }));

      multithreadedExecutor.invokeAll(callables);

      Assert.assertEquals(
          1.0 / 2 / 100 * 50 + 1.0 / 2 / 200 * 100, maxProgress.get(), DOUBLE_ERROR_MARGIN);

      // 0 progress doesn't do anything.
      multithreadedExecutor.invokeAll(
          Collections.nCopies(
              100,
              () -> {
                eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1, 0L));
                return null;
              }));
      Assert.assertEquals(
          1.0 / 2 / 100 * 50 + 1.0 / 2 / 200 * 100, maxProgress.get(), DOUBLE_ERROR_MARGIN);

      // Adds 50 to child1Child and 100 to child2 to finish it up.
      multithreadedExecutor.invokeAll(callables);
      Assert.assertEquals(1.0, maxProgress.get(), DOUBLE_ERROR_MARGIN);
    }
  }
Second child of the root node.
jib-core/src/test/java/com/google/cloud/tools/jib/event/progress/ProgressEventHandlerTest.java