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/21 15:02:53 UTC
[logging-log4j2] branch main updated: Order test properties before status listener
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
The following commit(s) were added to refs/heads/main by this push:
new e3a49bdf0f Order test properties before status listener
e3a49bdf0f is described below
commit e3a49bdf0f5383da16eafbeb1fa7f661447a8cbe
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Thu Sep 21 16:50:43 2023 +0200
Order test properties before status listener
If the status listener extension is active, it will start the static
initialization of `StatusLogger`, which means that many constants (like
IS_WEB_APP) will receive their default value.
---
.../log4j/test/junit/StatusLoggerExtension.java | 60 +++++++++++++++++++---
.../log4j/test/junit/UsingStatusListener.java | 3 +-
2 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/StatusLoggerExtension.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/StatusLoggerExtension.java
index cdbc220b49..3cc54a386e 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/StatusLoggerExtension.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/StatusLoggerExtension.java
@@ -17,12 +17,15 @@
package org.apache.logging.log4j.test.junit;
import java.io.IOException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.status.StatusConsoleListener;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.message.ParameterizedNoReferenceMessageFactory;
+import org.apache.logging.log4j.simple.SimpleLogger;
import org.apache.logging.log4j.status.StatusData;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.test.ListStatusListener;
@@ -30,15 +33,17 @@ 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.TestExecutionExceptionHandler;
+import org.junit.platform.commons.support.HierarchyTraversalMode;
+import org.junit.platform.commons.support.ModifierSupport;
+import org.junit.platform.commons.support.ReflectionSupport;
class StatusLoggerExtension extends TypeBasedParameterResolver<ListStatusListener>
implements BeforeAllCallback, BeforeEachCallback, TestExecutionExceptionHandler {
- private static final StatusLogger LOGGER = StatusLogger.getLogger();
- private static final StatusConsoleListener CONSOLE_LISTENER = new StatusConsoleListener(Level.ALL);
private static final Object KEY = ListStatusListener.class;
public StatusLoggerExtension() {
@@ -51,6 +56,16 @@ class StatusLoggerExtension extends TypeBasedParameterResolver<ListStatusListene
// `beforeAll` methods and extensions.
final ListStatusListenerHolder holder = new ListStatusListenerHolder(context, null);
ExtensionContextAnchor.setAttribute(KEY, holder, context);
+ ReflectionSupport.findFields(context.getRequiredTestClass(),
+ f -> ModifierSupport.isStatic(f) && f.getType().equals(ListStatusListener.class),
+ HierarchyTraversalMode.TOP_DOWN).forEach(f -> {
+ try {
+ f.setAccessible(true);
+ f.set(null, holder.getStatusListener());
+ } catch (final ReflectiveOperationException e) {
+ throw new ExtensionContextException("Failed to inject field.", e);
+ }
+ });
}
@Override
@@ -61,12 +76,26 @@ class StatusLoggerExtension extends TypeBasedParameterResolver<ListStatusListene
final ListStatusListener parent = parentHolder != null ? parentHolder.getStatusListener() : null;
final ListStatusListenerHolder holder = new ListStatusListenerHolder(context, parent);
ExtensionContextAnchor.setAttribute(KEY, holder, context);
+ ReflectionSupport.findFields(context.getRequiredTestClass(),
+ f -> ModifierSupport.isNotStatic(f) && f.getType().equals(ListStatusListener.class),
+ HierarchyTraversalMode.TOP_DOWN).forEach(f -> {
+ try {
+ f.setAccessible(true);
+ f.set(context.getRequiredTestInstance(), holder.getStatusListener());
+ } catch (final ReflectiveOperationException e) {
+ throw new ExtensionContextException("Failed to inject field.", e);
+ }
+ });
}
@Override
public void handleTestExecutionException(final ExtensionContext context, final Throwable throwable) throws Throwable {
- final ListStatusListener statusListener = resolveParameter(null, context);
- statusListener.getStatusData().forEach(CONSOLE_LISTENER::log);
+ final ListStatusListenerHolder holder = ExtensionContextAnchor.getAttribute(KEY,
+ ListStatusListenerHolder.class,
+ context);
+ if (holder != null) {
+ holder.handleException(context, throwable);
+ }
throw throwable;
}
@@ -80,11 +109,13 @@ class StatusLoggerExtension extends TypeBasedParameterResolver<ListStatusListene
private static class ListStatusListenerHolder implements CloseableResource {
+ private final StatusLogger statusLogger;
private final ListStatusListener statusListener;
public ListStatusListenerHolder(final ExtensionContext context, final ListStatusListener parent) {
+ this.statusLogger = StatusLogger.getLogger();
this.statusListener = new JUnitListStatusListener(context, parent);
- LOGGER.registerListener(statusListener);
+ statusLogger.registerListener(statusListener);
}
public ListStatusListener getStatusListener() {
@@ -93,9 +124,24 @@ class StatusLoggerExtension extends TypeBasedParameterResolver<ListStatusListene
@Override
public void close() throws Throwable {
- LOGGER.removeListener(statusListener);
+ statusLogger.removeListener(statusListener);
}
+ public void handleException(final ExtensionContext context, final Throwable throwable) {
+ final Logger logger = new SimpleLogger("StatusLoggerExtension",
+ ParameterizedNoReferenceMessageFactory.INSTANCE,
+ System.err,
+ Level.ALL,
+ new SimpleDateFormat("HH:mm:ss.SSS"),
+ true);
+ logger.error("Test {} failed.\nDumping status data:", context.getDisplayName());
+ statusListener.getStatusData().forEach(data -> {
+ logger.atLevel(data.getLevel())
+ .withThrowable(data.getThrowable())
+ .withLocation(data.getStackTraceElement())
+ .log(data.getMessage());
+ });
+ }
}
private static class JUnitListStatusListener implements ListStatusListener {
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/UsingStatusListener.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/UsingStatusListener.java
index 14ed2e8bd8..a54951f32a 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/UsingStatusListener.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/UsingStatusListener.java
@@ -17,7 +17,6 @@
package org.apache.logging.log4j.test.junit;
import java.lang.annotation.Documented;
-import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -36,9 +35,9 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
*/
@Retention(RUNTIME)
@Target({ TYPE, METHOD })
-@Inherited
@Documented
@ExtendWith(ExtensionContextAnchor.class)
+@ExtendWith(TestPropertyResolver.class)
@ExtendWith(StatusLoggerExtension.class)
public @interface UsingStatusListener {
}