Skip to content

Commit

Permalink
Log all discovered configuration files to assist in problem resolution
Browse files Browse the repository at this point in the history
Resolves #3898.
  • Loading branch information
marcphilipp committed Jul 25, 2024
1 parent 0ca1754 commit adf6d43
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

package org.junit.platform.launcher.core;

import static java.util.stream.Collectors.joining;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
Expand All @@ -25,6 +27,7 @@
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
Expand Down Expand Up @@ -272,13 +275,21 @@ private static Properties loadClasspathResource(String configFileName) {
Set<URL> resources = new LinkedHashSet<>(Collections.list(classLoader.getResources(configFileName)));

if (!resources.isEmpty()) {

URL configFileUrl = CollectionUtils.getFirstElement(resources).get();

if (resources.size() > 1) {
logger.warn(() -> String.format(
"Discovered %d '%s' configuration files in the classpath; only the first will be used.",
resources.size(), configFileName));
logger.warn(() -> {
String formattedResourceList = Stream.concat( //
Stream.of(configFileUrl + " (*)"), //
resources.stream().skip(1).map(URL::toString) //
).collect(joining("\n- ", "\n- ", ""));
return String.format(
"Discovered %d '%s' configuration files on the classpath (see below); only the first (*) will be used.%s",
resources.size(), configFileName, formattedResourceList);
});
}

URL configFileUrl = resources.iterator().next(); // same as List#get(0)
logger.config(() -> String.format(
"Loading JUnit Platform configuration parameters from classpath resource [%s].", configFileUrl));
URLConnection urlConnection = configFileUrl.openConnection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.LogRecord;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
import org.junit.jupiter.api.fixtures.TrackLogRecords;
import org.junit.jupiter.api.io.TempDir;
import org.junit.platform.commons.JUnitException;
import org.junit.platform.commons.PreconditionViolationException;
import org.junit.platform.commons.logging.LogRecordListener;
import org.junit.platform.engine.ConfigurationParameters;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
Expand Down Expand Up @@ -190,6 +201,40 @@ void ignoresSystemPropertyAndConfigFileWhenImplicitLookupsAreDisabled() {
assertThat(configParams.get(KEY)).isEmpty();
}

@Test
void warnsOnMultiplePropertyResources(@TempDir Path tempDir, @TrackLogRecords LogRecordListener logRecordListener)
throws Exception {
Properties properties = new Properties();
properties.setProperty(KEY, "from second config file");
try (var out = Files.newOutputStream(tempDir.resolve(CONFIG_FILE_NAME))) {
properties.store(out, "");
}
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try (var customClassLoader = new URLClassLoader(new URL[] { tempDir.toUri().toURL() }, originalClassLoader)) {
Thread.currentThread().setContextClassLoader(customClassLoader);
ConfigurationParameters configParams = fromMapAndFile(Map.of(), CONFIG_FILE_NAME);

assertThat(configParams.get(KEY)).contains(CONFIG_FILE);

List<String> loggedWarnings = logRecordListener.stream(Level.WARNING) //
.map(LogRecord::getMessage) //
.toList();
assertThat(loggedWarnings) //
.hasSize(1);
assertThat(loggedWarnings.getFirst()) //
.contains("Discovered 2 '" + CONFIG_FILE_NAME
+ "' configuration files on the classpath (see below); only the first (*) will be used.") //
.contains("- "
+ Path.of(
"build/resources/test/test-junit-platform.properties").toAbsolutePath().toUri().toURL()
+ " (*)") //
.contains("- " + tempDir.resolve(CONFIG_FILE_NAME).toUri().toURL());
}
finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
}

private static LauncherConfigurationParameters fromMap(Map<String, String> map) {
return LauncherConfigurationParameters.builder().explicitParameters(map).build();
}
Expand Down

0 comments on commit adf6d43

Please sign in to comment.