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