Skip to content

Commit 1f9ffde

Browse files
committed
Compare queue entries by unique id
This avoids an exhaustable index and potentially famous last words.
1 parent 663b690 commit 1f9ffde

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

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

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import java.util.concurrent.ThreadFactory;
4242
import java.util.concurrent.ThreadPoolExecutor;
4343
import java.util.concurrent.atomic.AtomicInteger;
44-
import java.util.concurrent.atomic.AtomicLong;
4544
import java.util.function.BiFunction;
4645
import java.util.function.BooleanSupplier;
4746
import java.util.function.Consumer;
@@ -54,6 +53,7 @@
5453
import org.junit.platform.commons.util.Preconditions;
5554
import org.junit.platform.commons.util.ToStringBuilder;
5655
import org.junit.platform.engine.ConfigurationParameters;
56+
import org.junit.platform.engine.UniqueId;
5757
import org.junit.platform.engine.support.hierarchical.ParallelHierarchicalTestExecutorServiceFactory.ParallelExecutorServiceType;
5858

5959
/**
@@ -642,7 +642,6 @@ private enum BlockingMode {
642642
}
643643

644644
private static class WorkQueue implements Iterable<WorkQueue.Entry> {
645-
private final AtomicLong index = new AtomicLong();
646645
private final Set<Entry> queue = new ConcurrentSkipListSet<>();
647646

648647
Entry add(TestTask task) {
@@ -652,8 +651,8 @@ Entry add(TestTask task) {
652651
}
653652

654653
Entry createEntry(TestTask task) {
655-
int level = task.getTestDescriptor().getUniqueId().getSegments().size();
656-
return new Entry(task, new CompletableFuture<>(), level, index.getAndIncrement());
654+
var uniqueId = task.getTestDescriptor().getUniqueId();
655+
return new Entry(uniqueId, task, new CompletableFuture<>());
657656
}
658657

659658
void addAll(Collection<Entry> entries) {
@@ -686,7 +685,7 @@ public Iterator<Entry> iterator() {
686685
return queue.iterator();
687686
}
688687

689-
private record Entry(TestTask task, CompletableFuture<@Nullable Void> future, int level, long index)
688+
private record Entry(UniqueId id, TestTask task, CompletableFuture<@Nullable Void> future)
690689
implements Comparable<Entry> {
691690

692691
@SuppressWarnings("FutureReturnValueIgnored")
@@ -703,15 +702,43 @@ private record Entry(TestTask task, CompletableFuture<@Nullable Void> future, in
703702

704703
@Override
705704
public int compareTo(Entry that) {
706-
var result = Integer.compare(that.level, this.level);
705+
var result = Integer.compare(that.getLevel(), getLevel());
707706
if (result != 0) {
708707
return result;
709708
}
710709
result = Boolean.compare(this.isContainer(), that.isContainer());
711710
if (result != 0) {
712711
return result;
713712
}
714-
return Long.compare(that.index, this.index);
713+
return compareBy(that.id(), this.id());
714+
}
715+
716+
private int compareBy(UniqueId a, UniqueId b) {
717+
var aIterator = a.getSegments().iterator();
718+
var bIterator = b.getSegments().iterator();
719+
720+
// ids have the same length
721+
while (aIterator.hasNext()) {
722+
var aCurrent = aIterator.next();
723+
var bCurrent = bIterator.next();
724+
int result = compareBy(aCurrent, bCurrent);
725+
if (result != 0) {
726+
return result;
727+
}
728+
}
729+
return 0;
730+
}
731+
732+
private int compareBy(UniqueId.Segment a, UniqueId.Segment b) {
733+
int result = a.getType().compareTo(b.getType());
734+
if (result != 0) {
735+
return result;
736+
}
737+
return a.getValue().compareTo(b.getValue());
738+
}
739+
740+
private int getLevel() {
741+
return this.id.getSegments().size();
715742
}
716743

717744
private boolean isContainer() {

0 commit comments

Comments
 (0)