ParallelJobsFuture implements JobFuture { @Override public void waitUntilComplete() { forEachFuture(JobFuture::waitUntilComplete); } ParallelJobsFuture(JobFuture... jobs);  ParallelJobsFuture(List<JobFuture> jobs);  ParallelJobsFuture(List<JobInfo> jobInfoList, QueueClient queueClient); @Override void waitUntilComplete(); @Override void waitUntilComplete(Duration timeout); @Override CompletableFuture<Void> waitAsync();  }
@Test(timeOut = 1000L) public void testWaitUntilComplete() throws Exception { new ParallelJobsFuture(successJobFutures(4)).waitUntilComplete(); }
@Test public void testWaitUntilComplete_failed() throws Exception { try { new ParallelJobsFuture(failedJobFutures(2)) .waitUntilComplete(); fail("Parallel future must throw exception"); } catch (JobFailedException ex) { assertEquals(ex.getSubExceptions().size(), 2); } }
@Test public void testWaitUntilCompleteWithDuration_failed() throws Exception { try { new ParallelJobsFuture(failedJobFutures(3)) .waitUntilComplete(Duration.of(10, MINUTES)); fail("Parallel future must throw exception"); } catch (JobFailedException ex) { assertEquals(ex.getSubExceptions().size(), 3); } }
@Test public void testWaitUntilCompleteWithDuration_timedOut() throws Exception { try { new ParallelJobsFuture(failedJobFutures(3)) .waitUntilComplete(Duration.of(10, MINUTES)); fail("Parallel future must throw exception"); } catch (JobFailedException ex) { assertEquals(ex.getSubExceptions().size(), 3); } }