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

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

commit 42768fbc70687c152ff227947cda1e80c984ec67
Author: Matt Sicker <[email protected]>
AuthorDate: Mon Jan 1 18:06:50 2024 -0600

    Refactor ThreadContextDataInjectorTest to use reflection
    
    This ensures portability of this test while some internal details of 
initialization are changed.
    
    Signed-off-by: Matt Sicker <[email protected]>
---
 .../core/impl/ThreadContextDataInjectorTest.java   | 113 +++++++++++++--------
 1 file changed, 71 insertions(+), 42 deletions(-)

diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
index 0e1f4362e5..16953436b7 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
@@ -16,26 +16,35 @@
  */
 package org.apache.logging.log4j.core.impl;
 
-import static java.util.Arrays.asList;
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.apache.logging.log4j.ThreadContext.getThreadContextMap;
 import static 
org.apache.logging.log4j.core.impl.ContextDataInjectorFactory.createInjector;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
-
-import java.util.Collection;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.lang.reflect.Constructor;
 import java.util.concurrent.ExecutionException;
+import java.util.function.Function;
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.ContextDataInjector;
-import org.apache.logging.log4j.spi.LoggingSystemProperty;
+import org.apache.logging.log4j.spi.DefaultThreadContextMap;
+import org.apache.logging.log4j.spi.LoggingSystem;
 import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap;
-import org.apache.logging.log4j.test.ThreadContextUtilityClass;
-import org.apache.logging.log4j.util.PropertiesUtil;
+import org.apache.logging.log4j.spi.ThreadContextMap;
 import org.apache.logging.log4j.util.SortedArrayStringMap;
 import org.apache.logging.log4j.util.StringMap;
 import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
+import org.junit.platform.commons.function.Try;
+import org.junit.platform.commons.support.ReflectionSupport;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameter;
@@ -43,38 +52,37 @@ import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
 public class ThreadContextDataInjectorTest {
-    @Parameters(name = "{0}")
-    public static Collection<String[]> threadContextMapClassNames() {
-        return asList(new String[][] {
+
+    public static final String THREAD_LOCAL_MAP_CLASS_NAME =
+            
"org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap";
+    public static final String GARBAGE_FREE_MAP_CLASS_NAME =
+            
"org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap";
+
+    @Parameters(name = "{1}")
+    public static Object[][] threadContextMapConstructorsAndReadOnlyNames() {
+        return new Object[][] {
             {
-                
"org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap",
-                
"org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap"
+                (Function<Boolean, ThreadContextMap>) 
ThreadContextDataInjectorTest::createThreadLocalMap,
+                THREAD_LOCAL_MAP_CLASS_NAME
             },
             {
-                
"org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap",
-                
"org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap"
+                (Function<Boolean, ThreadContextMap>) 
ThreadContextDataInjectorTest::createGarbageFreeMap,
+                GARBAGE_FREE_MAP_CLASS_NAME
             },
-            {"org.apache.logging.log4j.spi.DefaultThreadContextMap", null}
-        });
+            {(Function<Boolean, ThreadContextMap>) 
ThreadContextDataInjectorTest::createDefaultMap, null}
+        };
     }
 
-    @Parameter
-    public String threadContextMapClassName;
+    @Parameter(0)
+    public Function<Boolean, ThreadContextMap> threadContextMapConstructor;
 
-    @Parameter(value = 1)
-    public String readOnlythreadContextMapClassName;
-
-    @Before
-    public void before() {
-        
System.setProperty(LoggingSystemProperty.Constant.THREAD_CONTEXT_MAP_CLASS, 
threadContextMapClassName);
-    }
+    @Parameter(1)
+    public String readOnlyThreadContextMapClassName;
 
     @After
     public void after() {
         ThreadContext.remove("foo");
         ThreadContext.remove("baz");
-        
System.clearProperty(LoggingSystemProperty.Constant.THREAD_CONTEXT_MAP_CLASS);
-        
System.clearProperty(LoggingSystemProperty.Constant.THREAD_CONTEXT_MAP_INHERITABLE);
     }
 
     private void testContextDataInjector() {
@@ -84,7 +92,7 @@ public class ThreadContextDataInjectorTest {
                 (readOnlythreadContextMap == null)
                         ? null
                         : readOnlythreadContextMap.getClass().getName(),
-                is(equalTo(readOnlythreadContextMapClassName)));
+                is(equalTo(readOnlyThreadContextMapClassName)));
 
         final ContextDataInjector contextDataInjector = createInjector();
         final StringMap stringMap = 
contextDataInjector.injectContextData(null, new SortedArrayStringMap());
@@ -116,11 +124,9 @@ public class ThreadContextDataInjectorTest {
     }
 
     private void prepareThreadContext(final boolean 
isThreadContextMapInheritable) {
-        System.setProperty(
-                LoggingSystemProperty.Constant.THREAD_CONTEXT_MAP_INHERITABLE,
-                Boolean.toString(isThreadContextMapInheritable));
-        ((PropertiesUtil) PropertiesUtil.getProperties()).reload();
-        ThreadContextUtilityClass.reset();
+        LoggingSystem.getInstance()
+                .setThreadContextMapFactory(() -> 
threadContextMapConstructor.apply(isThreadContextMapInheritable));
+        ThreadContext.init();
         ThreadContext.remove("baz");
         ThreadContext.put("foo", "bar");
     }
@@ -135,16 +141,39 @@ public class ThreadContextDataInjectorTest {
     public void testInheritableThreadContextImmutability() throws Throwable {
         prepareThreadContext(true);
         try {
-            newSingleThreadExecutor()
-                    .submit(new Runnable() {
-                        @Override
-                        public void run() {
-                            testContextDataInjector();
-                        }
-                    })
-                    .get();
+            
newSingleThreadExecutor().submit(this::testContextDataInjector).get();
         } catch (ExecutionException ee) {
             throw ee.getCause();
         }
     }
+
+    private static ThreadContextMap createThreadLocalMap(final boolean 
inheritable) {
+        final Try<Class<?>> loadedClass = 
ReflectionSupport.tryToLoadClass(THREAD_LOCAL_MAP_CLASS_NAME);
+        final Class<? extends ThreadContextMap> mapClass =
+                
assertDoesNotThrow(loadedClass::get).asSubclass(ThreadContextMap.class);
+        return newInstanceWithCapacityArg(mapClass, inheritable);
+    }
+
+    private static ThreadContextMap createGarbageFreeMap(final boolean 
inheritable) {
+        final Try<Class<?>> loadedClass = 
ReflectionSupport.tryToLoadClass(GARBAGE_FREE_MAP_CLASS_NAME);
+        final Class<? extends ThreadContextMap> mapClass =
+                
assertDoesNotThrow(loadedClass::get).asSubclass(ThreadContextMap.class);
+        return newInstanceWithCapacityArg(mapClass, inheritable);
+    }
+
+    private static ThreadContextMap newInstanceWithCapacityArg(
+            final Class<? extends ThreadContextMap> mapClass, final boolean 
inheritable) {
+        final Constructor<? extends ThreadContextMap> constructor =
+                assertDoesNotThrow(() -> 
mapClass.getDeclaredConstructor(Boolean.TYPE, Integer.TYPE));
+        assertTrue(constructor.trySetAccessible(), () -> "Unable to access 
constructor for " + mapClass);
+        return assertDoesNotThrow(
+                () -> constructor.newInstance(inheritable, 
LoggingSystem.THREAD_CONTEXT_DEFAULT_INITIAL_CAPACITY));
+    }
+
+    private static ThreadContextMap createDefaultMap(final boolean 
inheritable) {
+        final Constructor<DefaultThreadContextMap> constructor = 
assertDoesNotThrow(
+                () -> 
DefaultThreadContextMap.class.getDeclaredConstructor(Boolean.TYPE, 
Boolean.TYPE));
+        assertTrue(constructor.trySetAccessible(), "Unable to construct 
DefaultThreadContextMap");
+        return assertDoesNotThrow(() -> constructor.newInstance(true, 
inheritable));
+    }
 }

Reply via email to