@Test
  public void testGetUnfinishedAllocations_multipleThreads()
      throws InterruptedException, ExecutionException, IOException {
    try (MultithreadedExecutor multithreadedExecutor = new MultithreadedExecutor()) {
      AllocationCompletionTracker allocationCompletionTracker = new AllocationCompletionTracker();

      // Adds root, child1, and child1Child.
      Assert.assertEquals(
          true,
          multithreadedExecutor.invoke(
              () -> allocationCompletionTracker.updateProgress(AllocationTree.root, 0L)));
      Assert.assertEquals(
          true,
          multithreadedExecutor.invoke(
              () -> allocationCompletionTracker.updateProgress(AllocationTree.child1, 0L)));
      Assert.assertEquals(
          true,
          multithreadedExecutor.invoke(
              () -> allocationCompletionTracker.updateProgress(AllocationTree.child1Child, 0L)));
      Assert.assertEquals(
          Arrays.asList(AllocationTree.root, AllocationTree.child1, AllocationTree.child1Child),
          allocationCompletionTracker.getUnfinishedAllocations());

      // Adds 50 to child1Child and 100 to child2.
      List<Callable<Boolean>> callables = new ArrayList<>(150);
      callables.addAll(
          Collections.nCopies(
              50,
              () -> allocationCompletionTracker.updateProgress(AllocationTree.child1Child, 1L)));
      callables.addAll(
          Collections.nCopies(
              100, () -> allocationCompletionTracker.updateProgress(AllocationTree.child2, 1L)));

      Assert.assertEquals(
          Collections.nCopies(150, true), multithreadedExecutor.invokeAll(callables));
      Assert.assertEquals(
          Arrays.asList(
              AllocationTree.root,
              AllocationTree.child1,
              AllocationTree.child1Child,
              AllocationTree.child2),
          allocationCompletionTracker.getUnfinishedAllocations());

      // 0 progress doesn't do anything.
      Assert.assertEquals(
          Collections.nCopies(100, false),
          multithreadedExecutor.invokeAll(
              Collections.nCopies(
                  100,
                  () -> allocationCompletionTracker.updateProgress(AllocationTree.child1, 0L))));
      Assert.assertEquals(
          Arrays.asList(
              AllocationTree.root,
              AllocationTree.child1,
              AllocationTree.child1Child,
              AllocationTree.child2),
          allocationCompletionTracker.getUnfinishedAllocations());

      // Adds 50 to child1Child and 100 to child2 to finish it up.
      Assert.assertEquals(
          Collections.nCopies(150, true), multithreadedExecutor.invokeAll(callables));
      Assert.assertEquals(
          Collections.emptyList(), allocationCompletionTracker.getUnfinishedAllocations());
    }
  }
Second child of the root node.
jib-core/src/test/java/com/google/cloud/tools/jib/event/progress/AllocationCompletionTrackerTest.java