From 9d5c59cbc8aaacb008ebe2ce0574a322fbe6ff04 Mon Sep 17 00:00:00 2001 From: currenjin Date: Sat, 9 Aug 2025 20:51:14 +0900 Subject: [PATCH 01/18] feat: log invalid search path roots (#4772) --- .../tasks/DiscoveryRequestCreator.java | 38 ++++++++++++++++++- .../tasks/DiscoveryRequestCreatorTests.java | 24 ++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index 67a74a9179b7..598e0331ecde 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -24,7 +24,9 @@ import static org.junit.platform.launcher.TagFilter.includeTags; import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; @@ -32,6 +34,8 @@ import java.util.regex.Pattern; import java.util.stream.Stream; +import org.junit.platform.commons.logging.Logger; +import org.junit.platform.commons.logging.LoggerFactory; import org.junit.platform.commons.util.ModuleUtils; import org.junit.platform.commons.util.Preconditions; import org.junit.platform.commons.util.ReflectionUtils; @@ -49,6 +53,8 @@ */ class DiscoveryRequestCreator { + private static final Logger logger = LoggerFactory.getLogger(DiscoveryRequestCreator.class); + static LauncherDiscoveryRequestBuilder toDiscoveryRequestBuilder(TestDiscoveryOptions options) { LauncherDiscoveryRequestBuilder requestBuilder = request(); List selectors = createDiscoverySelectors(options); @@ -87,9 +93,37 @@ private static Set determineClasspathRoots(TestDiscoveryOptions options) { if (selectedClasspathEntries.isEmpty()) { Set rootDirs = new LinkedHashSet<>(ReflectionUtils.getAllClasspathRootDirectories()); rootDirs.addAll(options.getExistingAdditionalClasspathEntries()); - return rootDirs; + return validateAndLogInvalidRoots(rootDirs); + } + return validateAndLogInvalidRoots(new LinkedHashSet<>(selectedClasspathEntries)); + } + + private static Set validateAndLogInvalidRoots(Set roots) { + LinkedHashSet valid = new LinkedHashSet<>(); + HashSet seen = new HashSet<>(); + + for (Path root : roots) { + if (!seen.add(root)) + continue; + + boolean exists = Files.exists(root); + boolean readable = Files.isReadable(root); + boolean dirOrJar = isDirOrJar(root); + + if (!exists || !readable || !dirOrJar) { + logger.info( + () -> "Ignoring invalid search path root: %s (exists=%s, readable=%s, dirOrJar=%s)".formatted(root, + exists, readable, dirOrJar)); + continue; + } + valid.add(root); } - return new LinkedHashSet<>(selectedClasspathEntries); + + return valid; + } + + private static boolean isDirOrJar(Path root) { + return Files.isDirectory(root) || root.toString().endsWith(".jar"); } private static void addFilters(LauncherDiscoveryRequestBuilder requestBuilder, TestDiscoveryOptions options, diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index fdef039fe467..7089b2d9294e 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -28,6 +28,7 @@ import java.io.File; import java.net.URI; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -35,6 +36,8 @@ import org.junit.jupiter.api.Test; import org.junit.platform.commons.PreconditionViolationException; +import org.junit.platform.commons.logging.LogRecordListener; +import org.junit.platform.commons.logging.LoggerFactory; import org.junit.platform.console.options.TestDiscoveryOptions; import org.junit.platform.engine.Filter; import org.junit.platform.engine.UniqueId; @@ -372,6 +375,27 @@ void convertsConfigurationParametersResources() { assertThat(configurationParameters.get("com.example.prop.second")).contains("second value"); } + @Test + void logs_when_invalid_search_path_present() { + LogRecordListener listener = new LogRecordListener(); + LoggerFactory.addListener(listener); + try { + var opts = new TestDiscoveryOptions(); + opts.setScanClasspath(true); + opts.setSelectedClasspathEntries(List.of(Paths.get("/does/not/exist"))); + + DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); + + boolean saw = listener.stream(DiscoveryRequestCreator.class).anyMatch( + r -> String.valueOf(r.getMessage()).contains("/does/not/exist")); + + assertThat(saw).as("should log about invalid search path root").isTrue(); + } + finally { + LoggerFactory.removeListener(listener); + } + } + private LauncherDiscoveryRequest convert() { return DiscoveryRequestCreator.toDiscoveryRequestBuilder(options).build(); } From 648a9cdebf2a2dacec472228e3098b9830970508 Mon Sep 17 00:00:00 2001 From: currenjin Date: Sun, 10 Aug 2025 08:46:19 +0900 Subject: [PATCH 02/18] feat: change log level to WARN for invalid classpath roots (#4772) --- .../junit/platform/console/tasks/DiscoveryRequestCreator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index 598e0331ecde..b3a92fc6d6e7 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -111,7 +111,7 @@ private static Set validateAndLogInvalidRoots(Set roots) { boolean dirOrJar = isDirOrJar(root); if (!exists || !readable || !dirOrJar) { - logger.info( + logger.warn( () -> "Ignoring invalid search path root: %s (exists=%s, readable=%s, dirOrJar=%s)".formatted(root, exists, readable, dirOrJar)); continue; From cb782d962bb6778c520fbcd15f8366c4e0848555 Mon Sep 17 00:00:00 2001 From: currenjin Date: Sun, 10 Aug 2025 19:39:19 +0900 Subject: [PATCH 03/18] test: force English locale in execute* tests to match expected logs --- .../java/platform/tooling/support/tests/StandaloneTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/StandaloneTests.java b/platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/StandaloneTests.java index e2c2bbc1f85b..e8120109e0ac 100644 --- a/platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/StandaloneTests.java +++ b/platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/StandaloneTests.java @@ -405,6 +405,7 @@ void execute(@FilePrefix("console-launcher") OutputFiles outputFiles) throws Exc .addArguments("-enableassertions") // .addArguments("-Djava.util.logging.config.file=logging.properties") // .addArguments("-Djunit.platform.launcher.interceptors.enabled=true") // + .addArguments("-Duser.language=en", "-Duser.country=US") // .addArguments("-jar", MavenRepo.jar("junit-platform-console-standalone").toString()) // .addArguments("execute") // .addArguments("--scan-class-path") // @@ -517,6 +518,7 @@ void executeWithJarredTestClasses(@FilePrefix("jar") OutputFiles jarOutputFiles, .addArguments("-enableassertions") // .addArguments("-Djava.util.logging.config.file=logging.properties") // .addArguments("-Djunit.platform.launcher.interceptors.enabled=true") // + .addArguments("-Duser.language=en", "-Duser.country=US") // .addArguments("-jar", MavenRepo.jar("junit-platform-console-standalone").toString()) // .addArguments("execute") // .addArguments("--scan-class-path") // From 230c429968a01c7700b3f8d214893cea17f48a4c Mon Sep 17 00:00:00 2001 From: currenjin Date: Thu, 14 Aug 2025 22:46:41 +0900 Subject: [PATCH 04/18] test: logsInvalidSearchPathRoots using TrackLogRecords --- .../tasks/DiscoveryRequestCreatorTests.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index 7089b2d9294e..660e70d6847c 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -32,9 +32,11 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.logging.LogRecord; import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.fixtures.TrackLogRecords; import org.junit.platform.commons.PreconditionViolationException; import org.junit.platform.commons.logging.LogRecordListener; import org.junit.platform.commons.logging.LoggerFactory; @@ -376,24 +378,17 @@ void convertsConfigurationParametersResources() { } @Test - void logs_when_invalid_search_path_present() { - LogRecordListener listener = new LogRecordListener(); - LoggerFactory.addListener(listener); - try { - var opts = new TestDiscoveryOptions(); - opts.setScanClasspath(true); - opts.setSelectedClasspathEntries(List.of(Paths.get("/does/not/exist"))); - - DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); - - boolean saw = listener.stream(DiscoveryRequestCreator.class).anyMatch( - r -> String.valueOf(r.getMessage()).contains("/does/not/exist")); - - assertThat(saw).as("should log about invalid search path root").isTrue(); - } - finally { - LoggerFactory.removeListener(listener); - } + void logsInvalidSearchPathRoots(@TrackLogRecords LogRecordListener listener) { + var opts = new TestDiscoveryOptions(); + opts.setScanClasspath(true); + opts.setSelectedClasspathEntries(List.of(Paths.get("/does/not/exist"))); + + DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); + + assertThat(listener.stream(DiscoveryRequestCreator.class)) // + .map(LogRecord::getMessage) // + .filteredOn(message -> message.contains("/does/not/exist")) // + .hasSize(1); } private LauncherDiscoveryRequest convert() { From eadc9b748af9f424f69f4ae5d3d950cd17a7a986 Mon Sep 17 00:00:00 2001 From: currenjin Date: Thu, 14 Aug 2025 23:12:30 +0900 Subject: [PATCH 05/18] feat: log and skip only non-existent classpath roots --- .../console/tasks/DiscoveryRequestCreator.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index b3a92fc6d6e7..b8c8daec71dc 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -107,13 +107,9 @@ private static Set validateAndLogInvalidRoots(Set roots) { continue; boolean exists = Files.exists(root); - boolean readable = Files.isReadable(root); - boolean dirOrJar = isDirOrJar(root); - if (!exists || !readable || !dirOrJar) { - logger.warn( - () -> "Ignoring invalid search path root: %s (exists=%s, readable=%s, dirOrJar=%s)".formatted(root, - exists, readable, dirOrJar)); + if (!exists) { + logger.warn(() -> "Ignoring invalid search path root: %s (exists=%s)".formatted(root, exists)); continue; } valid.add(root); @@ -122,10 +118,6 @@ private static Set validateAndLogInvalidRoots(Set roots) { return valid; } - private static boolean isDirOrJar(Path root) { - return Files.isDirectory(root) || root.toString().endsWith(".jar"); - } - private static void addFilters(LauncherDiscoveryRequestBuilder requestBuilder, TestDiscoveryOptions options, List selectors) { requestBuilder.filters(includedClassNamePatterns(options, selectors)); From d3317a3053690e11888c84e048382d3f9cfac313 Mon Sep 17 00:00:00 2001 From: currenjin Date: Thu, 14 Aug 2025 23:12:45 +0900 Subject: [PATCH 06/18] test: add doesNotLogInvalidAdditionalClasspathRoots --- .../tasks/DiscoveryRequestCreatorTests.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index 660e70d6847c..a456ccce7ad4 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -391,6 +391,20 @@ void logsInvalidSearchPathRoots(@TrackLogRecords LogRecordListener listener) { .hasSize(1); } + @Test + void doesNotLogInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListener listener) { + var opts = new TestDiscoveryOptions(); + opts.setScanClasspath(true); + opts.setAdditionalClasspathEntries(List.of(Paths.get("/also/does/not/exist"))); + + DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); + + assertThat(listener.stream(DiscoveryRequestCreator.class)) + .map(LogRecord::getMessage) + .filteredOn(msg -> msg.contains("/also/does/not/exist")) + .isEmpty(); + } + private LauncherDiscoveryRequest convert() { return DiscoveryRequestCreator.toDiscoveryRequestBuilder(options).build(); } From 62243dd3d6fadd5074be686874607c44812ec4b5 Mon Sep 17 00:00:00 2001 From: currenjin Date: Thu, 14 Aug 2025 23:19:07 +0900 Subject: [PATCH 07/18] fix: remove unused import --- .../platform/console/tasks/DiscoveryRequestCreatorTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index a456ccce7ad4..8b61f1ef6ff2 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -39,7 +39,6 @@ import org.junit.jupiter.api.fixtures.TrackLogRecords; import org.junit.platform.commons.PreconditionViolationException; import org.junit.platform.commons.logging.LogRecordListener; -import org.junit.platform.commons.logging.LoggerFactory; import org.junit.platform.console.options.TestDiscoveryOptions; import org.junit.platform.engine.Filter; import org.junit.platform.engine.UniqueId; From 9974ad35f61860e8a6be497f7e0219a270ecf509 Mon Sep 17 00:00:00 2001 From: currenjin Date: Thu, 14 Aug 2025 23:37:55 +0900 Subject: [PATCH 08/18] fix: lint --- .../console/tasks/DiscoveryRequestCreatorTests.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index 8b61f1ef6ff2..9f0a72453737 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -398,10 +398,8 @@ void doesNotLogInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListene DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); - assertThat(listener.stream(DiscoveryRequestCreator.class)) - .map(LogRecord::getMessage) - .filteredOn(msg -> msg.contains("/also/does/not/exist")) - .isEmpty(); + assertThat(listener.stream(DiscoveryRequestCreator.class)).map(LogRecord::getMessage).filteredOn( + msg -> msg.contains("/also/does/not/exist")).isEmpty(); } private LauncherDiscoveryRequest convert() { From 41b397f26be76f0252e1ea41040a712976674988 Mon Sep 17 00:00:00 2001 From: currenjin Date: Thu, 14 Aug 2025 23:53:04 +0900 Subject: [PATCH 09/18] refactor: validate additional classpath entries directly instead of using filtered list --- .../platform/console/tasks/DiscoveryRequestCreator.java | 2 +- .../console/tasks/DiscoveryRequestCreatorTests.java | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index b8c8daec71dc..14a85398667d 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -92,7 +92,7 @@ private static Set determineClasspathRoots(TestDiscoveryOptions options) { () -> "No classpath entries selected"); if (selectedClasspathEntries.isEmpty()) { Set rootDirs = new LinkedHashSet<>(ReflectionUtils.getAllClasspathRootDirectories()); - rootDirs.addAll(options.getExistingAdditionalClasspathEntries()); + rootDirs.addAll(options.getAdditionalClasspathEntries()); return validateAndLogInvalidRoots(rootDirs); } return validateAndLogInvalidRoots(new LinkedHashSet<>(selectedClasspathEntries)); diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index 9f0a72453737..09f23eed286c 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -391,15 +391,17 @@ void logsInvalidSearchPathRoots(@TrackLogRecords LogRecordListener listener) { } @Test - void doesNotLogInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListener listener) { + void logsInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListener listener) { var opts = new TestDiscoveryOptions(); opts.setScanClasspath(true); opts.setAdditionalClasspathEntries(List.of(Paths.get("/also/does/not/exist"))); DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); - assertThat(listener.stream(DiscoveryRequestCreator.class)).map(LogRecord::getMessage).filteredOn( - msg -> msg.contains("/also/does/not/exist")).isEmpty(); + assertThat(listener.stream(DiscoveryRequestCreator.class)) + .map(LogRecord::getMessage) + .filteredOn(msg -> msg.contains("/also/does/not/exist")) + .hasSize(1); } private LauncherDiscoveryRequest convert() { From 0a6ba3d083d3cb507f83336c7f3e0c4a1788eca7 Mon Sep 17 00:00:00 2001 From: currenjin Date: Thu, 14 Aug 2025 23:56:05 +0900 Subject: [PATCH 10/18] fix: lint --- .../console/tasks/DiscoveryRequestCreatorTests.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index 09f23eed286c..81b8897d3be8 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -398,10 +398,8 @@ void logsInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListener list DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); - assertThat(listener.stream(DiscoveryRequestCreator.class)) - .map(LogRecord::getMessage) - .filteredOn(msg -> msg.contains("/also/does/not/exist")) - .hasSize(1); + assertThat(listener.stream(DiscoveryRequestCreator.class)).map(LogRecord::getMessage).filteredOn( + msg -> msg.contains("/also/does/not/exist")).hasSize(1); } private LauncherDiscoveryRequest convert() { From 060a399bcc7dd275ebe4dad49f426ed9163d50a6 Mon Sep 17 00:00:00 2001 From: currenjin Date: Fri, 15 Aug 2025 23:58:35 +0900 Subject: [PATCH 11/18] refactor: simplify classpath root validation logic --- .../console/tasks/DiscoveryRequestCreator.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index 14a85398667d..31e8c4207bf5 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -103,16 +103,14 @@ private static Set validateAndLogInvalidRoots(Set roots) { HashSet seen = new HashSet<>(); for (Path root : roots) { - if (!seen.add(root)) - continue; - - boolean exists = Files.exists(root); - - if (!exists) { - logger.warn(() -> "Ignoring invalid search path root: %s (exists=%s)".formatted(root, exists)); + if (!seen.add(root)) { continue; } - valid.add(root); + if (Files.exists(root)) { + valid.add(root); + } else { + logger.warn(() -> "Ignoring non-existing classpath root: %s".formatted(root)); + } } return valid; From ccf18ce6e8e4e9daa04db9886191276a1b6b386d Mon Sep 17 00:00:00 2001 From: currenjin Date: Fri, 15 Aug 2025 23:58:52 +0900 Subject: [PATCH 12/18] test: reformat assertion in DiscoveryRequestCreatorTests --- .../console/tasks/DiscoveryRequestCreatorTests.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index 81b8897d3be8..5c6f9e35f317 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -398,8 +398,10 @@ void logsInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListener list DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); - assertThat(listener.stream(DiscoveryRequestCreator.class)).map(LogRecord::getMessage).filteredOn( - msg -> msg.contains("/also/does/not/exist")).hasSize(1); + assertThat(listener.stream(DiscoveryRequestCreator.class)) // + .map(LogRecord::getMessage) // + .filteredOn(message -> message.contains("/also/does/not/exist")) // + .hasSize(1); } private LauncherDiscoveryRequest convert() { From 83201a1985e16e5e77524e0dfaaec906281a62c9 Mon Sep 17 00:00:00 2001 From: currenjin Date: Sat, 16 Aug 2025 00:01:09 +0900 Subject: [PATCH 13/18] refactor: validate classpath roots once in createClasspathRootSelectors --- .../platform/console/tasks/DiscoveryRequestCreator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index 31e8c4207bf5..ba3951f783a8 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -83,7 +83,7 @@ private static List createDiscoverySelectors(TestDi } private static List createClasspathRootSelectors(TestDiscoveryOptions options) { - Set classpathRoots = determineClasspathRoots(options); + Set classpathRoots = validateAndLogInvalidRoots(determineClasspathRoots(options)); return selectClasspathRoots(classpathRoots); } @@ -93,9 +93,9 @@ private static Set determineClasspathRoots(TestDiscoveryOptions options) { if (selectedClasspathEntries.isEmpty()) { Set rootDirs = new LinkedHashSet<>(ReflectionUtils.getAllClasspathRootDirectories()); rootDirs.addAll(options.getAdditionalClasspathEntries()); - return validateAndLogInvalidRoots(rootDirs); + return rootDirs; } - return validateAndLogInvalidRoots(new LinkedHashSet<>(selectedClasspathEntries)); + return new LinkedHashSet<>(selectedClasspathEntries); } private static Set validateAndLogInvalidRoots(Set roots) { From e086c3d519cf7314b4af9f0e024940fb5ab7eccf Mon Sep 17 00:00:00 2001 From: currenjin Date: Sat, 16 Aug 2025 00:09:58 +0900 Subject: [PATCH 14/18] docs: add release notes entry for improved additional classpath root validation --- .../docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc b/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc index 01591fa288da..c423e8d11e95 100644 --- a/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc +++ b/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc @@ -82,4 +82,7 @@ repository on GitHub. [[release-notes-6.0.0-RC1-junit-vintage-new-features-and-improvements]] ==== New Features and Improvements +* Improved validation of additional classpath roots in the Console Launcher. +Now logs and skips only non-existent entries, ensuring more consistent behavior. + * ❓ From 81574468355ddf7e6865fe31d6fb9e0b794b5cdf Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Mon, 18 Aug 2025 10:41:23 +0200 Subject: [PATCH 15/18] Polish wording of logged message --- .../junit/platform/console/tasks/DiscoveryRequestCreator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index ba3951f783a8..85a8c5b87404 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -109,7 +109,7 @@ private static Set validateAndLogInvalidRoots(Set roots) { if (Files.exists(root)) { valid.add(root); } else { - logger.warn(() -> "Ignoring non-existing classpath root: %s".formatted(root)); + logger.warn(() -> "Ignoring nonexistent classpath root: %s".formatted(root)); } } From 52d31b6245e7ef252db7b376b104abffae671a11 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Mon, 18 Aug 2025 10:41:38 +0200 Subject: [PATCH 16/18] Polish release notes entry and move it to the right section --- .../asciidoc/release-notes/release-notes-6.0.0-RC1.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc b/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc index c37bdeac7ee1..a0185022d202 100644 --- a/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc +++ b/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc @@ -37,6 +37,9 @@ repository on GitHub. names in JUnit Jupiter, `@SuiteDisplayName`, and any other test engines that subclass `AbstractTestDescriptor`. Please refer to the <<../user-guide/index.adoc#writing-tests-display-names, User Guide>> for details. +* 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. [[release-notes-6.0.0-RC1-junit-jupiter]] @@ -90,7 +93,4 @@ repository on GitHub. [[release-notes-6.0.0-RC1-junit-vintage-new-features-and-improvements]] ==== New Features and Improvements -* Improved validation of additional classpath roots in the Console Launcher. -Now logs and skips only non-existent entries, ensuring more consistent behavior. - * ❓ From 35c99ceabe98a94d6531a4d1366b562eb7658d1d Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Mon, 18 Aug 2025 10:45:14 +0200 Subject: [PATCH 17/18] Fix formatting --- .../junit/platform/console/tasks/DiscoveryRequestCreator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java index 85a8c5b87404..233a7169ef6f 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/tasks/DiscoveryRequestCreator.java @@ -108,7 +108,8 @@ private static Set validateAndLogInvalidRoots(Set roots) { } if (Files.exists(root)) { valid.add(root); - } else { + } + else { logger.warn(() -> "Ignoring nonexistent classpath root: %s".formatted(root)); } } From eed3f070419940e778b9973c99ca5059169a15b1 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Mon, 18 Aug 2025 11:18:16 +0200 Subject: [PATCH 18/18] Fix tests on Windows --- .../console/tasks/DiscoveryRequestCreatorTests.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java index 5c6f9e35f317..5a673668c4ad 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/tasks/DiscoveryRequestCreatorTests.java @@ -28,7 +28,6 @@ import java.io.File; import java.net.URI; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -380,13 +379,14 @@ void convertsConfigurationParametersResources() { void logsInvalidSearchPathRoots(@TrackLogRecords LogRecordListener listener) { var opts = new TestDiscoveryOptions(); opts.setScanClasspath(true); - opts.setSelectedClasspathEntries(List.of(Paths.get("/does/not/exist"))); + var missingPath = Path.of("/does/not/exist"); + opts.setSelectedClasspathEntries(List.of(missingPath)); DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); assertThat(listener.stream(DiscoveryRequestCreator.class)) // .map(LogRecord::getMessage) // - .filteredOn(message -> message.contains("/does/not/exist")) // + .filteredOn(message -> message.contains(missingPath.toString())) // .hasSize(1); } @@ -394,13 +394,14 @@ void logsInvalidSearchPathRoots(@TrackLogRecords LogRecordListener listener) { void logsInvalidAdditionalClasspathRoots(@TrackLogRecords LogRecordListener listener) { var opts = new TestDiscoveryOptions(); opts.setScanClasspath(true); - opts.setAdditionalClasspathEntries(List.of(Paths.get("/also/does/not/exist"))); + var missingPath = Path.of("/also/does/not/exist"); + opts.setAdditionalClasspathEntries(List.of(missingPath)); DiscoveryRequestCreator.toDiscoveryRequestBuilder(opts); assertThat(listener.stream(DiscoveryRequestCreator.class)) // .map(LogRecord::getMessage) // - .filteredOn(message -> message.contains("/also/does/not/exist")) // + .filteredOn(message -> message.contains(missingPath.toString())) // .hasSize(1); }