Skip to content

Commit da404fe

Browse files
authored
Log nonexistent classpath roots in Console Launcher
To help diagnosing potentially invalid invocations, the Console Launcher now logs warnings for nonexistent classpath roots added via `--classpath` or `--scan-classpath` rather than silently ignoring them. Resolves #4772.
1 parent 304f42a commit da404fe

File tree

4 files changed

+65
-2
lines changed

4 files changed

+65
-2
lines changed

documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ repository on GitHub.
3737
names in JUnit Jupiter, `@SuiteDisplayName`, and any other test engines that subclass
3838
`AbstractTestDescriptor`. Please refer to the
3939
<<../user-guide/index.adoc#writing-tests-display-names, User Guide>> for details.
40+
* To help diagnosing potentially invalid invocations, the Console Launcher now logs
41+
warnings for nonexistent classpath roots added via `--classpath` or `--scan-classpath`
42+
rather than silently ignoring them.
4043

4144

4245
[[release-notes-6.0.0-RC1-junit-jupiter]]

junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@
2424
import static org.junit.platform.launcher.TagFilter.includeTags;
2525
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
2626

27+
import java.nio.file.Files;
2728
import java.nio.file.Path;
29+
import java.util.HashSet;
2830
import java.util.LinkedHashSet;
2931
import java.util.List;
3032
import java.util.Objects;
3133
import java.util.Set;
3234
import java.util.regex.Pattern;
3335
import java.util.stream.Stream;
3436

37+
import org.junit.platform.commons.logging.Logger;
38+
import org.junit.platform.commons.logging.LoggerFactory;
3539
import org.junit.platform.commons.util.ModuleUtils;
3640
import org.junit.platform.commons.util.Preconditions;
3741
import org.junit.platform.commons.util.ReflectionUtils;
@@ -49,6 +53,8 @@
4953
*/
5054
class DiscoveryRequestCreator {
5155

56+
private static final Logger logger = LoggerFactory.getLogger(DiscoveryRequestCreator.class);
57+
5258
static LauncherDiscoveryRequestBuilder toDiscoveryRequestBuilder(TestDiscoveryOptions options) {
5359
LauncherDiscoveryRequestBuilder requestBuilder = request();
5460
List<? extends DiscoverySelector> selectors = createDiscoverySelectors(options);
@@ -77,7 +83,7 @@ private static List<? extends DiscoverySelector> createDiscoverySelectors(TestDi
7783
}
7884

7985
private static List<ClasspathRootSelector> createClasspathRootSelectors(TestDiscoveryOptions options) {
80-
Set<Path> classpathRoots = determineClasspathRoots(options);
86+
Set<Path> classpathRoots = validateAndLogInvalidRoots(determineClasspathRoots(options));
8187
return selectClasspathRoots(classpathRoots);
8288
}
8389

@@ -86,12 +92,31 @@ private static Set<Path> determineClasspathRoots(TestDiscoveryOptions options) {
8692
() -> "No classpath entries selected");
8793
if (selectedClasspathEntries.isEmpty()) {
8894
Set<Path> rootDirs = new LinkedHashSet<>(ReflectionUtils.getAllClasspathRootDirectories());
89-
rootDirs.addAll(options.getExistingAdditionalClasspathEntries());
95+
rootDirs.addAll(options.getAdditionalClasspathEntries());
9096
return rootDirs;
9197
}
9298
return new LinkedHashSet<>(selectedClasspathEntries);
9399
}
94100

101+
private static Set<Path> validateAndLogInvalidRoots(Set<Path> roots) {
102+
LinkedHashSet<Path> valid = new LinkedHashSet<>();
103+
HashSet<Path> seen = new HashSet<>();
104+
105+
for (Path root : roots) {
106+
if (!seen.add(root)) {
107+
continue;
108+
}
109+
if (Files.exists(root)) {
110+
valid.add(root);
111+
}
112+
else {
113+
logger.warn(() -> "Ignoring nonexistent classpath root: %s".formatted(root));
114+
}
115+
}
116+
117+
return valid;
118+
}
119+
95120
private static void addFilters(LauncherDiscoveryRequestBuilder requestBuilder, TestDiscoveryOptions options,
96121
List<? extends DiscoverySelector> selectors) {
97122
requestBuilder.filters(includedClassNamePatterns(options, selectors));

platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@
3131
import java.util.List;
3232
import java.util.Map;
3333
import java.util.Map.Entry;
34+
import java.util.logging.LogRecord;
3435
import java.util.stream.Stream;
3536

3637
import org.junit.jupiter.api.Test;
38+
import org.junit.jupiter.api.fixtures.TrackLogRecords;
3739
import org.junit.platform.commons.PreconditionViolationException;
40+
import org.junit.platform.commons.logging.LogRecordListener;
3841
import org.junit.platform.console.options.TestDiscoveryOptions;
3942
import org.junit.platform.engine.Filter;
4043
import org.junit.platform.engine.UniqueId;
@@ -372,6 +375,36 @@ void convertsConfigurationParametersResources() {
372375
assertThat(configurationParameters.get("com.example.prop.second")).contains("second value");
373376
}
374377

378+
@Test
379+
void logsInvalidSearchPathRoots(@TrackLogRecords LogRecordListener listener) {
380+
var opts = new TestDiscoveryOptions();
381+
opts.setScanClasspath(true);
382+
var missingPath = Path.of("/does/not/exist");
383+
opts.setSelectedClasspathEntries(List.of(missingPath));
384+
385+
DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts);
386+
387+
assertThat(listener.stream(DiscoveryRequestCreator.class)) //
388+
.map(LogRecord::getMessage) //
389+
.filteredOn(message -> message.contains(missingPath.toString())) //
390+
.hasSize(1);
391+
}
392+
393+
@Test
394+
void logsInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListener listener) {
395+
var opts = new TestDiscoveryOptions();
396+
opts.setScanClasspath(true);
397+
var missingPath = Path.of("/also/does/not/exist");
398+
opts.setAdditionalClasspathEntries(List.of(missingPath));
399+
400+
DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts);
401+
402+
assertThat(listener.stream(DiscoveryRequestCreator.class)) //
403+
.map(LogRecord::getMessage) //
404+
.filteredOn(message -> message.contains(missingPath.toString())) //
405+
.hasSize(1);
406+
}
407+
375408
private LauncherDiscoveryRequest convert() {
376409
return DiscoveryRequestCreator.toDiscoveryRequestBuilder(options).build();
377410
}

platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/StandaloneTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ void execute(@FilePrefix("console-launcher") OutputFiles outputFiles) throws Exc
405405
.addArguments("-enableassertions") //
406406
.addArguments("-Djava.util.logging.config.file=logging.properties") //
407407
.addArguments("-Djunit.platform.launcher.interceptors.enabled=true") //
408+
.addArguments("-Duser.language=en", "-Duser.country=US") //
408409
.addArguments("-jar", MavenRepo.jar("junit-platform-console-standalone").toString()) //
409410
.addArguments("execute") //
410411
.addArguments("--scan-class-path") //
@@ -517,6 +518,7 @@ void executeWithJarredTestClasses(@FilePrefix("jar") OutputFiles jarOutputFiles,
517518
.addArguments("-enableassertions") //
518519
.addArguments("-Djava.util.logging.config.file=logging.properties") //
519520
.addArguments("-Djunit.platform.launcher.interceptors.enabled=true") //
521+
.addArguments("-Duser.language=en", "-Duser.country=US") //
520522
.addArguments("-jar", MavenRepo.jar("junit-platform-console-standalone").toString()) //
521523
.addArguments("execute") //
522524
.addArguments("--scan-class-path") //

0 commit comments

Comments
 (0)