Use a random `${test:logging.path}` (#2954)
The `@TempLoggingDir` JUnit 5 extensions create a totally deterministic directory to hold the log files for tests.
Since the directory is deleted only if all the tests succeed, this causes a problem with test reruns.
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDirectory.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDirectory.java
index ef97ff2..1ba5a16 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDirectory.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDirectory.java
@@ -39,6 +39,7 @@
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.junit.jupiter.api.io.CleanupMode;
+import org.junit.platform.commons.PreconditionViolationException;
import org.junit.platform.commons.support.AnnotationSupport;
import org.junit.platform.commons.support.ModifierSupport;
@@ -51,8 +52,8 @@
Path loggingPath = null;
for (final Field field : fields) {
if (loggingPath != null) {
- StatusLogger.getLogger()
- .warn("Multiple static fields with @TempLoggingDir annotation are not supported.");
+ throw new PreconditionViolationException(
+ "Multiple static fields with @TempLoggingDir annotation are not supported.");
} else {
final CleanupMode cleanup = determineCleanupMode(field);
loggingPath = createLoggingPath(context, cleanup).getPath();
@@ -79,8 +80,8 @@
final Object instance = context.getRequiredTestInstance();
for (final Field field : fields) {
if (loggingPath != null) {
- StatusLogger.getLogger()
- .warn("Multiple instance fields with @TempLoggingDir annotation are not supported.");
+ throw new PreconditionViolationException(
+ "Multiple instance fields with @TempLoggingDir annotation are not supported.");
} else {
final CleanupMode cleanup = determineCleanupMode(field);
loggingPath = createLoggingPath(context, cleanup).getPath();
@@ -102,8 +103,11 @@
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
- final TempLoggingDir annotation =
- parameterContext.findAnnotation(TempLoggingDir.class).get();
+ final TempLoggingDir annotation = parameterContext
+ .findAnnotation(TempLoggingDir.class)
+ .orElseThrow(() -> new PreconditionViolationException(String.format(
+ "Missing `%s` annotation on parameter `%s`",
+ TempLoggingDir.class.getSimpleName(), parameterContext)));
// Get or create a temporary directory
PathHolder holder = ExtensionContextAnchor.getAttribute(PathHolder.class, PathHolder.class, extensionContext);
if (holder == null || !extensionContext.equals(holder.getMainContext())) {
@@ -142,12 +146,16 @@
final Path basePath = (baseDir != null ? Paths.get(baseDir, "target") : Paths.get(".")).resolve("logs");
final Class<?> clazz = context.getRequiredTestClass();
final Package pkg = clazz.getPackage();
- final String dir =
- pkg.getName().replaceAll("[.$]", File.separatorChar == '\\' ? "\\\\" : File.separator);
+ final String dir = pkg.getName()
+ .replaceAll("org\\.apache\\.(logging\\.)?log4j\\.", "")
+ .replaceAll("[.$]", File.separatorChar == '\\' ? "\\\\" : File.separator);
// Create a temporary directory that uses the simple class name as prefix
Path packagePath = basePath.resolve(dir);
Files.createDirectories(packagePath);
- return Files.createTempDirectory(packagePath, clazz.getSimpleName());
+ // Use a UNIX timestamp to (roughly) sort directories by execution time.
+ return Files.createTempDirectory(
+ packagePath,
+ String.format("%s_%08x_", clazz.getSimpleName(), System.currentTimeMillis() / 1000));
} catch (final IOException e) {
throw new ExtensionContextException("Failed to create temporary directory.", e);
}
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/test/junit/TempLoggingDirectoryTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/test/junit/TempLoggingDirectoryTest.java
index 0a1dd2f..61de955 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/test/junit/TempLoggingDirectoryTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/test/junit/TempLoggingDirectoryTest.java
@@ -27,7 +27,7 @@
@UsingTestProperties
public class TempLoggingDirectoryTest {
- private static final Pattern PER_CLASS_PATH = Pattern.compile("TempLoggingDirectoryTest\\d+");
+ private static final Pattern PER_CLASS_PATH = Pattern.compile("TempLoggingDirectoryTest_[0-9a-f]{8,}_\\d+");
private static final Path PER_TEST_PATH = Paths.get("testInjectedFields");
@TempLoggingDir