You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2023/09/15 06:34:35 UTC

[logging-log4j2] branch main updated (f59aa67cf9 -> 488c808d82)

This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


    from f59aa67cf9 Improve cleanup of @TempLoggingDir
     new 01ea73e990 Add instance field and parameter support to @TempLoggingDir
     new 488c808d82 Order @TempLoggingDir before context instantiation

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../logging/log4j/test/junit/TempLoggingDir.java   |  5 +-
 .../log4j/test/junit/TempLoggingDirectory.java     | 71 +++++++++++++++++++---
 .../log4j/test/junit/TempLoggingDirectoryTest.java | 48 +++++++++++++++
 .../log4j/core/test/junit/LoggerContextSource.java |  2 +
 4 files changed, 117 insertions(+), 9 deletions(-)
 create mode 100644 log4j-api-test/src/test/java/org/apache/logging/log4j/test/junit/TempLoggingDirectoryTest.java


[logging-log4j2] 02/02: Order @TempLoggingDir before context instantiation

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 488c808d820adf6452d8386518ea51818a729728
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Fri Sep 15 08:33:37 2023 +0200

    Order @TempLoggingDir before context instantiation
---
 .../org/apache/logging/log4j/core/test/junit/LoggerContextSource.java   | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextSource.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextSource.java
index 3eca9c35fa..60747acd6f 100644
--- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextSource.java
+++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextSource.java
@@ -29,6 +29,7 @@ import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.AbstractManager;
 import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.test.junit.TempLoggingDirectory;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.extension.ExtendWith;
 
@@ -56,6 +57,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
 @Documented
 @Inherited
 @Tag("functional")
+@ExtendWith(TempLoggingDirectory.class)
 @ExtendWith(LoggerContextResolver.class)
 @ExtendWith(ConfigurationResolver.class)
 @ExtendWith(AppenderResolver.class)


[logging-log4j2] 01/02: Add instance field and parameter support to @TempLoggingDir

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 01ea73e990e6c1e4ae14a19f099768e84f969ddf
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Fri Sep 15 08:29:41 2023 +0200

    Add instance field and parameter support to @TempLoggingDir
---
 .../logging/log4j/test/junit/TempLoggingDir.java   |  5 +-
 .../log4j/test/junit/TempLoggingDirectory.java     | 71 +++++++++++++++++++---
 .../log4j/test/junit/TempLoggingDirectoryTest.java | 48 +++++++++++++++
 3 files changed, 115 insertions(+), 9 deletions(-)

diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDir.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDir.java
index 586e4cb4c4..78c70f7912 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDir.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/TempLoggingDir.java
@@ -17,7 +17,6 @@
 package org.apache.logging.log4j.test.junit;
 
 import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
 import java.lang.annotation.Inherited;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
@@ -25,6 +24,8 @@ import java.lang.annotation.Target;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.io.CleanupMode;
 
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 /**
@@ -34,7 +35,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
  * </p>
  */
 @Retention(RUNTIME)
-@Target({ ElementType.FIELD })
+@Target({ FIELD, PARAMETER })
 @Inherited
 @Documented
 @ExtendWith(ExtensionContextAnchor.class)
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 010ce90f60..a4087db2bb 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
@@ -33,6 +33,10 @@ import org.junit.jupiter.api.extension.BeforeAllCallback;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.api.extension.ExtensionContext.Store.CloseableResource;
+import org.junit.jupiter.api.extension.ExtensionContextException;
+import org.junit.jupiter.api.extension.ParameterContext;
+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.support.AnnotationSupport;
 import org.junit.platform.commons.support.ModifierSupport;
@@ -40,7 +44,7 @@ import org.junit.platform.commons.support.ModifierSupport;
 import static org.junit.jupiter.api.io.CleanupMode.NEVER;
 import static org.junit.jupiter.api.io.CleanupMode.ON_SUCCESS;
 
-public class TempLoggingDirectory implements BeforeAllCallback, BeforeEachCallback {
+public class TempLoggingDirectory implements BeforeAllCallback, BeforeEachCallback, ParameterResolver {
 
     private static final Logger LOGGER = StatusLogger.getLogger();
 
@@ -65,21 +69,68 @@ public class TempLoggingDirectory implements BeforeAllCallback, BeforeEachCallba
     public void beforeEach(ExtensionContext context) throws Exception {
         // JUnit 5 does not set an error on the parent context if one of the children
         // fail. We record the list of children.
-        final PathHolder holder = ExtensionContextAnchor.getAttribute(PathHolder.class, PathHolder.class, context);
-        if (holder != null) {
-            holder.addContext(context);
+        context.getParent().ifPresent(c -> {
+            final PathHolder holder = ExtensionContextAnchor.getAttribute(PathHolder.class, PathHolder.class, c);
+            if (holder != null) {
+                holder.addContext(context);
+            }
+        });
+        // Inject fields
+        final List<Field> fields = AnnotationSupport.findAnnotatedFields(context.getRequiredTestClass(),
+                TempLoggingDir.class, ModifierSupport::isNotStatic);
+        Path loggingPath = null;
+        final Object instance = context.getRequiredTestInstance();
+        for (final Field field : fields) {
+            if (loggingPath != null) {
+                LOGGER.warn("Multiple fields with @TempLoggingDir annotation are not supported.");
+            } else {
+                final CleanupMode cleanup = determineCleanupMode(field);
+                loggingPath = createLoggingPath(context, cleanup).getPath();
+            }
+            field.setAccessible(true);
+            field.set(instance, loggingPath);
         }
     }
 
-    private PathHolder createLoggingPath(final ExtensionContext context, final CleanupMode cleanup) throws IOException {
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
+            throws ParameterResolutionException {
+        if (parameterContext.getParameter().getType().isAssignableFrom(Path.class)) {
+            return parameterContext.findAnnotation(TempLoggingDir.class).isPresent();
+        }
+        return false;
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
+            throws ParameterResolutionException {
+        final TempLoggingDir annotation = parameterContext.findAnnotation(TempLoggingDir.class).get();
+        // Get or create temporary directory
+        PathHolder holder = ExtensionContextAnchor.getAttribute(PathHolder.class, PathHolder.class, extensionContext);
+        if (holder == null || !extensionContext.equals(holder.getMainContext())) {
+            final CleanupMode mode = determineCleanupMode(annotation);
+            holder = createLoggingPath(extensionContext, mode);
+        }
+        return holder.getPath();
+    }
+
+    private PathHolder createLoggingPath(final ExtensionContext context, final CleanupMode cleanup) {
         final TestProperties props = TestPropertySource.createProperties(context);
         // Create temporary directory
         final String baseDir = System.getProperty("basedir");
         final Path basePath = (baseDir != null ? Paths.get(baseDir, "target") : Paths.get(".")).resolve("logs");
         final Class<?> clazz = context.getRequiredTestClass();
         final String dir = clazz.getName().replaceAll("[.$]", File.separatorChar == '\\' ? "\\\\" : File.separator);
-        final Path loggingPath = basePath.resolve(dir);
-        Files.createDirectories(loggingPath);
+        final Path perClassPath = basePath.resolve(dir);
+        // Per test subfolder
+        final Path loggingPath = context.getTestMethod()
+                .map(m -> perClassPath.resolve(m.getName()))
+                .orElse(perClassPath);
+        try {
+            Files.createDirectories(loggingPath);
+        } catch (final IOException e) {
+            throw new ExtensionContextException("Failed to create temporary directory.", e);
+        }
         props.setProperty(TestProperties.LOGGING_PATH, loggingPath.toString());
         // Register deletion
         final PathHolder holder = new PathHolder(loggingPath, cleanup, context);
@@ -101,12 +152,14 @@ public class TempLoggingDirectory implements BeforeAllCallback, BeforeEachCallba
 
         private final Path path;
         private final CleanupMode cleanupMode;
+        private final ExtensionContext mainContext;
         private final Map<ExtensionContext, Boolean> contexts = new ConcurrentHashMap<>();
 
         public PathHolder(final Path path, final CleanupMode cleanup, final ExtensionContext context) {
             this.path = path;
             this.cleanupMode = cleanup;
             this.contexts.put(context, Boolean.TRUE);
+            this.mainContext = context;
         }
 
         public void addContext(final ExtensionContext context) {
@@ -117,6 +170,10 @@ public class TempLoggingDirectory implements BeforeAllCallback, BeforeEachCallba
             return path;
         }
 
+        public ExtensionContext getMainContext() {
+            return mainContext;
+        }
+
         @Override
         public void close() throws IOException {
             if (cleanupMode == NEVER || (cleanupMode == ON_SUCCESS
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
new file mode 100644
index 0000000000..12834077f1
--- /dev/null
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/test/junit/TempLoggingDirectoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.test.junit;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.apache.logging.log4j.test.TestProperties;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@UsingTestProperties
+public class TempLoggingDirectoryTest {
+
+    private static final Path PER_CLASS_PATH = Paths.get("TempLoggingDirectoryTest");
+    private static final Path PER_TEST_PATH = Paths.get("testInjectedFields");
+
+    @TempLoggingDir
+    private static Path staticLoggingPath;
+    @TempLoggingDir
+    private Path instanceLoggingPath;
+
+    @Test
+    void testInjectedFields(final @TempLoggingDir Path parameterLoggingPath, final TestProperties props) {
+        assertThat(staticLoggingPath).exists()
+                .endsWith(PER_CLASS_PATH);
+        assertThat(instanceLoggingPath).exists()
+                .startsWith(staticLoggingPath)
+                .endsWith(PER_TEST_PATH);
+        assertThat(parameterLoggingPath).isEqualTo(instanceLoggingPath);
+        assertThat(props.getProperty(TestProperties.LOGGING_PATH)).isEqualTo(instanceLoggingPath.toString());
+    }
+}