Skip to content

Commit 8d1ec79

Browse files
committed
Track dynamic children by index
1 parent 86af266 commit 8d1ec79

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/WorkerThreadPoolHierarchicalTestExecutorService.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,15 @@ public void close() {
142142

143143
var workerThread = WorkerThread.get();
144144
if (workerThread == null) {
145-
return enqueue(testTask).future();
145+
return enqueue(testTask, 0).future();
146146
}
147147

148148
if (testTask.getExecutionMode() == SAME_THREAD) {
149149
workerThread.executeTask(testTask);
150150
return completedFuture(null);
151151
}
152152

153-
var entry = enqueue(testTask);
153+
var entry = enqueue(testTask, workerThread.nextChildIndex());
154154
workerThread.trackSubmittedChild(entry);
155155
return new WorkStealingFuture(entry);
156156
}
@@ -172,8 +172,8 @@ public void invokeAll(List<? extends TestTask> testTasks) {
172172
workerThread.invokeAll(testTasks);
173173
}
174174

175-
private WorkQueue.Entry enqueue(TestTask testTask) {
176-
var entry = workQueue.add(testTask);
175+
private WorkQueue.Entry enqueue(TestTask testTask, int index) {
176+
var entry = workQueue.add(testTask, index);
177177
maybeStartWorker();
178178
return entry;
179179
}
@@ -548,6 +548,10 @@ private static CompletableFuture<?> toCombinedFuture(List<WorkQueue.Entry> entri
548548
return CompletableFuture.allOf(futures);
549549
}
550550

551+
private int nextChildIndex() {
552+
return stateStack.element().nextChildIndex();
553+
}
554+
551555
private void trackSubmittedChild(WorkQueue.Entry entry) {
552556
stateStack.element().trackSubmittedChild(entry);
553557
}
@@ -571,6 +575,8 @@ private void tryToStealWorkFromSubmittedChildren() {
571575

572576
private static class State {
573577

578+
private int nextChildIndex = 0;
579+
574580
@Nullable
575581
private List<WorkQueue.Entry> submittedChildren;
576582

@@ -586,6 +592,10 @@ private void clearIfEmpty() {
586592
submittedChildren = null;
587593
}
588594
}
595+
596+
private int nextChildIndex() {
597+
return nextChildIndex++;
598+
}
589599
}
590600

591601
private enum WorkStealResult {
@@ -645,8 +655,8 @@ private enum BlockingMode {
645655
private static class WorkQueue implements Iterable<WorkQueue.Entry> {
646656
private final Set<Entry> queue = new ConcurrentSkipListSet<>();
647657

648-
Entry add(TestTask task) {
649-
Entry entry = createEntry(task, 0);
658+
Entry add(TestTask task, int index) {
659+
Entry entry = createEntry(task, index);
650660
LOGGER.trace(() -> "forking: " + entry.task);
651661
return doAdd(entry);
652662
}

platform-tests/src/test/java/org/junit/platform/engine/support/hierarchical/WorkerThreadPoolHierarchicalTestExecutorServiceTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,41 @@ void stealsDynamicChildren() throws Exception {
586586
assertThat(child2.executionThread).isEqualTo(root.executionThread).isNotEqualTo(child1.executionThread);
587587
}
588588

589+
@Test
590+
void executesDynamicChildrenInSubmitOrder() throws Exception {
591+
service = new WorkerThreadPoolHierarchicalTestExecutorService(configuration(1, 1));
592+
593+
var child1 = new TestTaskStub(ExecutionMode.CONCURRENT) //
594+
.withName("child1").withLevel(2);
595+
var child2 = new TestTaskStub(ExecutionMode.CONCURRENT) //
596+
.withName("child2").withLevel(2);
597+
var child3 = new TestTaskStub(ExecutionMode.CONCURRENT) //
598+
.withName("child3").withLevel(2);
599+
var child4 = new TestTaskStub(ExecutionMode.CONCURRENT) //
600+
.withName("child3").withLevel(2);
601+
602+
List<TestTaskStub> children = List.of(child1, child2, child3, child4);
603+
Collections.shuffle(children);
604+
605+
var root = new TestTaskStub(ExecutionMode.SAME_THREAD, () -> {
606+
var executor = requiredService();
607+
var features = children.stream().map(executor::submit).toList();
608+
for (var future : features) {
609+
future.get();
610+
}
611+
}) //
612+
.withName("root").withLevel(1);
613+
614+
service.submit(root).get();
615+
616+
assertThat(Stream.of(root, child1, child2)) //
617+
.allSatisfy(TestTaskStub::assertExecutedSuccessfully);
618+
619+
assertThat(children) //
620+
.extracting(TestTaskStub::startTime) //
621+
.isSorted();
622+
}
623+
589624
@Test
590625
void stealsNestedDynamicChildren() throws Exception {
591626
service = new WorkerThreadPoolHierarchicalTestExecutorService(configuration(2, 2));

0 commit comments

Comments
 (0)