@@ -227,6 +227,80 @@ void runsTasksWithoutConflictingLocksConcurrently() throws Exception {
227227 assertThat (leaves ).allSatisfy (TestTaskStub ::assertExecutedSuccessfully );
228228 }
229229
230+ @ Test
231+ void processingQueueEntriesSkipsOverUnavailableResources () throws Exception {
232+ service = new ConcurrentHierarchicalTestExecutorService (configuration (2 ));
233+
234+ var resourceLock = new SingleLock (exclusiveResource (LockMode .READ_WRITE ), new ReentrantLock ());
235+
236+ var lockFreeChildrenStarted = new CountDownLatch (2 );
237+ var child1Started = new CountDownLatch (1 );
238+
239+ Executable child1Behaviour = () -> {
240+ child1Started .countDown ();
241+ lockFreeChildrenStarted .await ();
242+ };
243+ Executable child4Behaviour = () -> {
244+ lockFreeChildrenStarted .countDown ();
245+ child1Started .await ();
246+ };
247+
248+ var child1 = new TestTaskStub (ExecutionMode .CONCURRENT , child1Behaviour ) //
249+ .withResourceLock (resourceLock ) //
250+ .withName ("child1" );
251+ var child2 = new TestTaskStub (ExecutionMode .CONCURRENT , lockFreeChildrenStarted ::countDown ).withName ("child2" ); //
252+ var child3 = new TestTaskStub (ExecutionMode .CONCURRENT ).withResourceLock (resourceLock ) //
253+ .withName ("child3" );
254+ var child4 = new TestTaskStub (ExecutionMode .CONCURRENT , child4Behaviour ).withName ("child4" );
255+ var children = List .of (child1 , child2 , child3 , child4 );
256+ var root = new TestTaskStub (ExecutionMode .CONCURRENT , () -> requiredService ().invokeAll (children )) //
257+ .withName ("root" );
258+
259+ service .submit (root ).get ();
260+
261+ root .assertExecutedSuccessfully ();
262+ assertThat (children ).allSatisfy (TestTaskStub ::assertExecutedSuccessfully );
263+ assertThat (child4 .executionThread ).isEqualTo (child2 .executionThread );
264+ assertThat (child3 .startTime ).isAfterOrEqualTo (child2 .startTime );
265+ }
266+
267+ @ Test
268+ void invokeAllQueueEntriesSkipsOverUnavailableResources () throws Exception {
269+ service = new ConcurrentHierarchicalTestExecutorService (configuration (2 ));
270+
271+ var resourceLock = new SingleLock (exclusiveResource (LockMode .READ_WRITE ), new ReentrantLock ());
272+
273+ var lockFreeChildrenStarted = new CountDownLatch (2 );
274+ var child4Started = new CountDownLatch (1 );
275+
276+ Executable child1Behaviour = () -> {
277+ lockFreeChildrenStarted .countDown ();
278+ child4Started .await ();
279+ };
280+ Executable child4Behaviour = () -> {
281+ child4Started .countDown ();
282+ lockFreeChildrenStarted .await ();
283+ };
284+
285+ var child1 = new TestTaskStub (ExecutionMode .CONCURRENT , child1Behaviour ) //
286+ .withName ("child1" );
287+ var child2 = new TestTaskStub (ExecutionMode .CONCURRENT ).withResourceLock (resourceLock ) //
288+ .withName ("child2" ); //
289+ var child3 = new TestTaskStub (ExecutionMode .CONCURRENT , lockFreeChildrenStarted ::countDown ).withName ("child3" );
290+ var child4 = new TestTaskStub (ExecutionMode .CONCURRENT , child4Behaviour ).withResourceLock (resourceLock ) //
291+ .withName ("child4" );
292+ var children = List .of (child1 , child2 , child3 , child4 );
293+ var root = new TestTaskStub (ExecutionMode .CONCURRENT , () -> requiredService ().invokeAll (children )) //
294+ .withName ("root" );
295+
296+ service .submit (root ).get ();
297+
298+ root .assertExecutedSuccessfully ();
299+ assertThat (children ).allSatisfy (TestTaskStub ::assertExecutedSuccessfully );
300+ assertThat (child1 .executionThread ).isEqualTo (child3 .executionThread );
301+ assertThat (child2 .startTime ).isAfterOrEqualTo (child3 .startTime );
302+ }
303+
230304 @ Test
231305 void prioritizesChildrenOfStartedContainers () throws Exception {
232306 service = new ConcurrentHierarchicalTestExecutorService (configuration (2 ));
0 commit comments