You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/09/27 22:36:13 UTC

[1/2] logging-log4j2 git commit: LOG4J2-1349 better gc-free test

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 7fafa3cd8 -> b679156b2


LOG4J2-1349 better gc-free test


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/ae887b32
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/ae887b32
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/ae887b32

Branch: refs/heads/master
Commit: ae887b32b5dfe63d1f0f6c70ca6e0833e056f46c
Parents: 7fafa3c
Author: rpopma <rp...@apache.org>
Authored: Wed Sep 28 07:33:39 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Wed Sep 28 07:33:39 2016 +0900

----------------------------------------------------------------------
 .../apache/logging/log4j/core/GcFreeLoggingTestUtil.java    | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ae887b32/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java
index aa6801a..51a0b96 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java
@@ -58,7 +58,6 @@ public class GcFreeLoggingTestUtil {
 
         // initialize LoggerContext etc.
         // This is not steady-state logging and will allocate objects.
-
         ThreadContext.put("aKey", "value1");
         ThreadContext.put("key2", "value2");
 
@@ -70,6 +69,8 @@ public class GcFreeLoggingTestUtil {
         for (int i = 0; i < 256; i++) {
             logger.debug("ensure all ringbuffer slots have been used once"); // allocate MutableLogEvent.messageText
         }
+        ThreadContext.remove("aKey");
+        ThreadContext.remove("key2");
 
         // BlockingWaitStrategy uses ReentrantLock which allocates Node objects. Ignore this.
         final String[] exclude = new String[] {
@@ -102,6 +103,10 @@ public class GcFreeLoggingTestUtil {
         AllocationRecorder.addSampler(sampler);
 
         // now do some steady-state logging
+
+        ThreadContext.put("aKey", "value1");
+        ThreadContext.put("key2", "value2");
+
         final int ITERATIONS = 5;
         for (int i = 0; i < ITERATIONS; i++) {
             logger.error(myCharSeq);
@@ -110,6 +115,8 @@ public class GcFreeLoggingTestUtil {
             logger.error("Test parameterized message {}", "param");
             logger.error("Test parameterized message {}{}", "param", "param2");
             logger.error("Test parameterized message {}{}{}", "param", "param2", "abc");
+            ThreadContext.remove("aKey");
+            ThreadContext.put("aKey", "value1");
         }
         Thread.sleep(50);
         samplingEnabled.set(false); // reliably ignore all allocations from now on


[2/2] logging-log4j2 git commit: LOG4J2-1010 LOG4J2-1447 ContextInjector tests cannot be parameterized: values are cached in static final fields. Must fork new JVM for each different ThreadContextMap implementation.

Posted by rp...@apache.org.
LOG4J2-1010 LOG4J2-1447 ContextInjector tests cannot be parameterized: values are cached in static final fields. Must fork new JVM for each different ThreadContextMap implementation.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/b679156b
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b679156b
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b679156b

Branch: refs/heads/master
Commit: b679156b2959759da68d7c2f452232481736b982
Parents: ae887b3
Author: rpopma <rp...@apache.org>
Authored: Wed Sep 28 07:36:09 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Wed Sep 28 07:36:09 2016 +0900

----------------------------------------------------------------------
 .../AbstractAsyncThreadContextTestBase.java     | 188 ++++++++++++++++++
 ...ggerAllThreadContextImplementationsTest.java | 196 -------------------
 ...nfigAllThreadContextImplementationsTest.java | 167 ----------------
 ...oggerConfigThreadContextCopyOnWriteTest.java |  26 +++
 ...yncLoggerConfigThreadContextDefaultTest.java |  26 +++
 ...oggerConfigThreadContextGarbageFreeTest.java |  26 +++
 ...AsyncLoggerThreadContextCopyOnWriteTest.java |  40 ++++
 .../AsyncLoggerThreadContextDefaultTest.java    |  40 ++++
 ...AsyncLoggerThreadContextGarbageFreeTest.java |  40 ++++
 9 files changed, 386 insertions(+), 363 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AbstractAsyncThreadContextTestBase.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AbstractAsyncThreadContextTestBase.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AbstractAsyncThreadContextTestBase.java
new file mode 100644
index 0000000..560f250
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AbstractAsyncThreadContextTestBase.java
@@ -0,0 +1,188 @@
+/*
+ * 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.core.async;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.ThreadContextAccess;
+import org.apache.logging.log4j.ThreadContextTestAccess;
+import org.apache.logging.log4j.core.CoreLoggerContexts;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
+import org.apache.logging.log4j.core.util.Constants;
+import org.apache.logging.log4j.spi.DefaultThreadContextMap;
+import org.apache.logging.log4j.spi.LoggerContext;
+import org.apache.logging.log4j.util.Unbox;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public abstract class AbstractAsyncThreadContextTestBase {
+
+    private final static int LINE_COUNT = 130;
+
+    @BeforeClass
+    public static void beforeClass() {
+        System.setProperty("AsyncLogger.RingBufferSize", "128"); // minimum ringbuffer size
+        System.setProperty("AsyncLoggerConfig.RingBufferSize", "128"); // minimum ringbuffer size
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        System.clearProperty("AsyncLogger.RingBufferSize");
+        System.clearProperty("AsyncLoggerConfig.RingBufferSize");
+        System.clearProperty(Constants.LOG4J_CONTEXT_SELECTOR);
+        System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+        System.clearProperty("log4j2.garbagefree.threadContextMap");
+        System.clearProperty("log4j2.is.webapp");
+        System.clearProperty("log4j2.threadContextMap");
+    }
+
+    enum Mode {
+        ALL_ASYNC, MIXED, BOTH_ALL_ASYNC_AND_MIXED;
+
+        void initSelector() {
+            if (this == ALL_ASYNC || this == BOTH_ALL_ASYNC_AND_MIXED) {
+                System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR,  AsyncLoggerContextSelector.class.getName());
+            } else {
+                System.clearProperty(Constants.LOG4J_CONTEXT_SELECTOR);
+            }
+        }
+
+        void initConfigFile() {
+            // NOTICE: PLEASE DON'T REFACTOR: keep "file" local variable for confirmation in debugger.
+            final String file = this == ALL_ASYNC //
+                    ? "AsyncLoggerThreadContextTest.xml" //
+                    : "AsyncLoggerConfigThreadContextTest.xml";
+            System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, file);
+        }
+    }
+
+    enum ContextImpl {
+        WEBAPP, GARBAGE_FREE, COPY_ON_WRITE;
+
+        void init() {
+            System.clearProperty("log4j2.threadContextMap");
+            final String PACKAGE = "org.apache.logging.log4j.spi.";
+            System.setProperty("log4j2.threadContextMap", PACKAGE + implClassSimpleName());
+            ThreadContextTestAccess.init();
+        }
+
+        public String implClassSimpleName() {
+            switch (this) {
+                case WEBAPP:
+                    return DefaultThreadContextMap.class.getSimpleName();
+                case GARBAGE_FREE:
+                    return "GarbageFreeSortedArrayThreadContextMap";
+                case COPY_ON_WRITE:
+                    return "CopyOnWriteSortedArrayThreadContextMap";
+            }
+            throw new IllegalStateException("Unknown state " + this);
+        }
+    }
+
+    private final ContextImpl contextImpl;
+    private final Mode asyncMode;
+
+    public AbstractAsyncThreadContextTestBase(final ContextImpl contextImpl, final Mode asyncMode) {
+        this.contextImpl = contextImpl;
+        this.asyncMode = asyncMode;
+
+        asyncMode.initSelector();
+        asyncMode.initConfigFile();
+
+        contextImpl.init();
+    }
+
+    @Test
+    public void testAsyncLogWritesToLog() throws Exception {
+        final File[] files = new File[] {
+                new File("target", "AsyncLoggerTest.log"), //
+                new File("target", "SynchronousContextTest.log"), //
+                new File("target", "AsyncLoggerAndAsyncAppenderTest.log"), //
+                new File("target", "AsyncAppenderContextTest.log"), //
+        };
+        for (final File f : files) {
+            f.delete();
+        }
+
+        ThreadContext.push("stackvalue");
+        ThreadContext.put("KEY", "mapvalue");
+
+        final Logger log = LogManager.getLogger("com.foo.Bar");
+        final LoggerContext loggerContext = LogManager.getContext(false);
+        final String loggerContextName = loggerContext.getClass().getSimpleName();
+        RingBufferAdmin ring;
+        if (loggerContext instanceof AsyncLoggerContext) {
+            ring = ((AsyncLoggerContext) loggerContext).createRingBufferAdmin();
+        } else {
+            ring = ((AsyncLoggerConfig) ((org.apache.logging.log4j.core.Logger) log).get()).createRingBufferAdmin("");
+        }
+
+        for (int i = 0; i < LINE_COUNT; i++) {
+            while (i >= 128 && ring.getRemainingCapacity() == 0) { // buffer may be full
+                Thread.sleep(1);
+            }
+            if ((i & 1) == 1) {
+                ThreadContext.put("count", String.valueOf(i));
+            } else {
+                ThreadContext.remove("count");
+            }
+            final String contextmap = ThreadContextAccess.getThreadContextMap().getClass().getSimpleName();
+            log.info("{} {} {} i={}", contextImpl, contextmap, loggerContextName, Unbox.box(i));
+        }
+        ThreadContext.pop();
+        CoreLoggerContexts.stopLoggerContext(false, files[0]); // stop async thread
+
+        checkResult(files[0], loggerContextName);
+        if (asyncMode == Mode.MIXED || asyncMode == Mode.BOTH_ALL_ASYNC_AND_MIXED) {
+            for (int i = 1; i < files.length; i++) {
+                checkResult(files[i], loggerContextName);
+            }
+        }
+        LogManager.shutdown();
+    }
+
+    private void checkResult(final File file, final String loggerContextName) throws IOException {
+        final String contextDesc = contextImpl + " " + contextImpl.implClassSimpleName() + " " + loggerContextName;
+        try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
+            String expect;
+            for (int i = 0; i < LINE_COUNT; i++) {
+                final String line = reader.readLine();
+                if ((i & 1) == 1) {
+                    expect = "INFO c.f.Bar mapvalue [stackvalue] {KEY=mapvalue, configProp=configValue, configProp2=configValue2, count=" + i + "} "
+                            + contextDesc + " i=" + i;
+                } else {
+                    expect = "INFO c.f.Bar mapvalue [stackvalue] {KEY=mapvalue, configProp=configValue, configProp2=configValue2} " + contextDesc + " i=" + i;
+                }
+                assertEquals(file.getName() + ": line " + i, expect, line);
+            }
+            final String noMoreLines = reader.readLine();
+            assertNull("done", noMoreLines);
+        } finally {
+            file.delete();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerAllThreadContextImplementationsTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerAllThreadContextImplementationsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerAllThreadContextImplementationsTest.java
deleted file mode 100644
index 3dcd534..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerAllThreadContextImplementationsTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * 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.core.async;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.ThreadContextAccess;
-import org.apache.logging.log4j.ThreadContextTestAccess;
-import org.apache.logging.log4j.core.CoreLoggerContexts;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
-import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
-import org.apache.logging.log4j.spi.LoggerContext;
-import org.apache.logging.log4j.util.Unbox;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static org.junit.Assert.*;
-
-@RunWith(Parameterized.class)
-public class AsyncLoggerAllThreadContextImplementationsTest {
-
-    final static int LINE_COUNT = 130;
-    private final ContextImpl contextImpl;
-    private final Mode asyncMode;
-
-    @BeforeClass
-    public static void beforeClass() {
-        System.setProperty("AsyncLogger.RingBufferSize", "128"); // minimum ringbuffer size
-        System.setProperty("AsyncLoggerConfig.RingBufferSize", "128"); // minimum ringbuffer size
-    }
-
-    @AfterClass
-    public static void afterClass() {
-        System.clearProperty("AsyncLogger.RingBufferSize");
-        System.clearProperty("AsyncLoggerConfig.RingBufferSize");
-        System.clearProperty(Constants.LOG4J_CONTEXT_SELECTOR);
-        System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-        System.clearProperty("log4j2.garbagefree.threadContextMap");
-        System.clearProperty("log4j2.is.webapp");
-        System.clearProperty("log4j2.threadContextMap");
-    }
-
-    static enum Mode {
-        ALL_ASYNC, MIXED, BOTH_ALL_ASYNC_AND_MIXED;
-
-        void initSelector() {
-            if (this == ALL_ASYNC || this == BOTH_ALL_ASYNC_AND_MIXED) {
-                System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR,  AsyncLoggerContextSelector.class.getName());
-            } else {
-                System.clearProperty(Constants.LOG4J_CONTEXT_SELECTOR);
-            }
-        }
-
-        void initConfigFile() {
-            System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, this == ALL_ASYNC //
-                    ? "AsyncLoggerThreadContextTest.xml" //
-                    : "AsyncLoggerConfigThreadContextTest.xml");
-        }
-    }
-
-    static enum ContextImpl {
-        WEBAPP, GARBAGE_FREE, COPY_ON_WRITE;
-
-        void init() {
-            System.clearProperty("log4j2.threadContextMap");
-            final String PACKAGE = "org.apache.logging.log4j.spi.";
-            System.setProperty("log4j2.threadContextMap", PACKAGE + implClassSimpleName());
-            ThreadContextTestAccess.init();
-        }
-
-        public String implClassSimpleName() {
-            switch (this) {
-                case WEBAPP:
-                    return DefaultThreadContextMap.class.getSimpleName();
-                case GARBAGE_FREE:
-                    return "GarbageFreeSortedArrayThreadContextMap";
-                case COPY_ON_WRITE:
-                    return "CopyOnWriteSortedArrayThreadContextMap";
-            }
-            throw new IllegalStateException("Unknown state " + this);
-        }
-    }
-
-    @Parameterized.Parameters
-    public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[][] {
-                { ContextImpl.WEBAPP, Mode.ALL_ASYNC},
-                { ContextImpl.WEBAPP, Mode.BOTH_ALL_ASYNC_AND_MIXED},
-                { ContextImpl.GARBAGE_FREE, Mode.ALL_ASYNC},
-                { ContextImpl.GARBAGE_FREE, Mode.BOTH_ALL_ASYNC_AND_MIXED},
-                { ContextImpl.COPY_ON_WRITE, Mode.ALL_ASYNC},
-                { ContextImpl.COPY_ON_WRITE, Mode.BOTH_ALL_ASYNC_AND_MIXED}
-        });
-    }
-
-    public AsyncLoggerAllThreadContextImplementationsTest(final ContextImpl contextImpl, final Mode asyncMode) {
-        this.contextImpl = contextImpl;
-        this.asyncMode = asyncMode;
-
-        asyncMode.initSelector();
-        asyncMode.initConfigFile();
-
-        contextImpl.init();
-    }
-
-    @Test
-    public void testAsyncLogWritesToLog() throws Exception {
-        final File[] files = new File[] {
-                new File("target", "AsyncLoggerTest.log"), //
-                new File("target", "SynchronousContextTest.log"), //
-                new File("target", "AsyncLoggerAndAsyncAppenderTest.log"), //
-                new File("target", "AsyncAppenderContextTest.log"), //
-        };
-        for (final File f : files) {
-            f.delete();
-        }
-
-        ThreadContext.push("stackvalue");
-        ThreadContext.put("KEY", "mapvalue");
-
-        final Logger log = LogManager.getLogger("com.foo.Bar");
-        final LoggerContext loggerContext = LogManager.getContext(false);
-        final String loggerContextName = loggerContext.getClass().getSimpleName();
-        final RingBufferAdmin ring = ((AsyncLoggerContext) loggerContext).createRingBufferAdmin();
-        for (int i = 0; i < LINE_COUNT; i++) {
-            while (i >= 128 && ring.getRemainingCapacity() == 0) { // buffer may be full
-                Thread.sleep(1);
-            }
-            if ((i & 1) == 1) {
-                ThreadContext.put("count", String.valueOf(i));
-            } else {
-                ThreadContext.remove("count");
-            }
-            final String contextmap = ThreadContextAccess.getThreadContextMap().getClass().getSimpleName();
-            log.info("{} {} {} i={}", contextImpl, contextmap, loggerContextName, Unbox.box(i));
-        }
-        ThreadContext.pop();
-        CoreLoggerContexts.stopLoggerContext(false, files[0]); // stop async thread
-
-        checkResult(files[0], loggerContextName);
-        if (asyncMode == Mode.MIXED || asyncMode == Mode.BOTH_ALL_ASYNC_AND_MIXED) {
-            for (int i = 1; i < files.length; i++) {
-                checkResult(files[i], loggerContextName);
-            }
-        }
-        LogManager.shutdown();
-    }
-
-    private void checkResult(final File file, final String loggerContextName) throws IOException {
-        final String contextDesc = contextImpl + " " + contextImpl.implClassSimpleName() + " " + loggerContextName;
-        try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
-            String expect = null;
-            for (int i = 0; i < LINE_COUNT; i++) {
-                final String line = reader.readLine();
-                if ((i & 1) == 1) {
-                    expect = "INFO c.f.Bar mapvalue [stackvalue] {KEY=mapvalue, configProp=configValue, configProp2=configValue2, count=" + i + "} "
-                            + contextDesc + " i=" + i;
-                } else {
-                    expect = "INFO c.f.Bar mapvalue [stackvalue] {KEY=mapvalue, configProp=configValue, configProp2=configValue2} " + contextDesc + " i=" + i;
-                }
-                assertEquals(file.getName() + ": line " + i, expect, line);
-            }
-            final String noMoreLines = reader.readLine();
-            assertNull("done", noMoreLines);
-        } finally {
-            file.delete();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAllThreadContextImplementationsTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAllThreadContextImplementationsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAllThreadContextImplementationsTest.java
deleted file mode 100644
index 1f08d0a..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAllThreadContextImplementationsTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.core.async;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.ThreadContextAccess;
-import org.apache.logging.log4j.ThreadContextTestAccess;
-import org.apache.logging.log4j.core.CoreLoggerContexts;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
-import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
-import org.apache.logging.log4j.spi.LoggerContext;
-import org.apache.logging.log4j.util.Unbox;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static org.junit.Assert.*;
-
-@RunWith(Parameterized.class)
-public class AsyncLoggerConfigAllThreadContextImplementationsTest {
-
-    final static int LINE_COUNT = 130;
-    private final ContextImpl contextImpl;
-
-    @BeforeClass
-    public static void beforeClass() {
-        System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, "AsyncLoggerConfigThreadContextTest.xml");
-        System.setProperty("AsyncLoggerConfig.RingBufferSize", "128"); // minimum ringbuffer size
-    }
-
-    @AfterClass
-    public static void afterClass() {
-        System.clearProperty("AsyncLogger.RingBufferSize");
-        System.clearProperty("AsyncLoggerConfig.RingBufferSize");
-        System.clearProperty(Constants.LOG4J_CONTEXT_SELECTOR);
-        System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-        System.clearProperty("log4j2.garbagefree.threadContextMap");
-        System.clearProperty("log4j2.is.webapp");
-        System.clearProperty("log4j2.threadContextMap");
-    }
-
-    static enum ContextImpl {
-        WEBAPP, GARBAGE_FREE, COPY_ON_WRITE;
-
-        void init() {
-            System.clearProperty("log4j2.threadContextMap");
-            final String PACKAGE = "org.apache.logging.log4j.spi.";
-            System.setProperty("log4j2.threadContextMap", PACKAGE + implClassSimpleName());
-            ThreadContextTestAccess.init();
-        }
-
-        public String implClassSimpleName() {
-            switch (this) {
-                case WEBAPP:
-                    return DefaultThreadContextMap.class.getSimpleName();
-                case GARBAGE_FREE:
-                    return "GarbageFreeSortedArrayThreadContextMap";
-                case COPY_ON_WRITE:
-                    return "CopyOnWriteSortedArrayThreadContextMap";
-            }
-            throw new IllegalStateException("Unknown state " + this);
-        }
-    }
-
-    @Parameterized.Parameters
-    public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[][] {
-                { ContextImpl.WEBAPP, },
-                { ContextImpl.GARBAGE_FREE, },
-                { ContextImpl.COPY_ON_WRITE, }
-        });
-    }
-
-    public AsyncLoggerConfigAllThreadContextImplementationsTest(final ContextImpl contextImpl) {
-        this.contextImpl = contextImpl;
-        contextImpl.init();
-    }
-
-    @Test
-    public void testAsyncLogWritesToLog() throws Exception {
-        final File[] files = new File[] {
-                new File("target", "AsyncLoggerTest.log"), //
-                new File("target", "SynchronousContextTest.log"), //
-                new File("target", "AsyncLoggerAndAsyncAppenderTest.log"), //
-                new File("target", "AsyncAppenderContextTest.log"), //
-        };
-        for (final File f : files) {
-            f.delete();
-        }
-
-        ThreadContext.push("stackvalue");
-        ThreadContext.put("KEY", "mapvalue");
-
-        final Logger log = LogManager.getLogger("com.foo.Bar");
-        final LoggerContext loggerContext = LogManager.getContext(false);
-        final String loggerContextName = loggerContext.getClass().getSimpleName();
-        final RingBufferAdmin ring = ((AsyncLoggerConfig) ((org.apache.logging.log4j.core.Logger) log).get())
-                .createRingBufferAdmin("");
-        for (int i = 0; i < LINE_COUNT; i++) {
-            while (i >= 128 && ring.getRemainingCapacity() == 0) { // buffer may be full
-                Thread.sleep(1);
-            }
-            if ((i & 1) == 1) {
-                ThreadContext.put("count", String.valueOf(i));
-            } else {
-                ThreadContext.remove("count");
-            }
-            final String contextmap = ThreadContextAccess.getThreadContextMap().getClass().getSimpleName();
-            log.info("{} {} {} i={}", contextImpl, contextmap, loggerContextName, Unbox.box(i));
-        }
-        ThreadContext.pop();
-        CoreLoggerContexts.stopLoggerContext(false, files[files.length - 1]); // stop async thread
-
-        for (final File f : files) {
-            checkResult(f, loggerContextName);
-        }
-        LogManager.shutdown();
-    }
-
-    private void checkResult(final File file, final String loggerContextName) throws IOException {
-        final String contextDesc = contextImpl + " " + contextImpl.implClassSimpleName() + " " + loggerContextName;
-        try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
-            String expect = null;
-            for (int i = 0; i < LINE_COUNT; i++) {
-                final String line = reader.readLine();
-                if ((i & 1) == 1) {
-                    expect = "INFO c.f.Bar mapvalue [stackvalue] {KEY=mapvalue, configProp=configValue, configProp2=configValue2, count=" + i + "} "
-                            + contextDesc + " i=" + i;
-                } else {
-                    expect = "INFO c.f.Bar mapvalue [stackvalue] {KEY=mapvalue, configProp=configValue, configProp2=configValue2} " + contextDesc + " i=" + i;
-                }
-                assertEquals(file.getName() + ": line " + i, expect, line);
-            }
-            final String noMoreLines = reader.readLine();
-            assertNull("done", noMoreLines);
-        } finally {
-            file.delete();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java
new file mode 100644
index 0000000..17aaff8
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java
@@ -0,0 +1,26 @@
+/*
+ * 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.core.async;
+
+// Note: the different ThreadContextMap implementations cannot be parameterized:
+// ThreadContext initialization will result in static final fields being set in various components.
+// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+public class AsyncLoggerConfigThreadContextCopyOnWriteTest extends AbstractAsyncThreadContextTestBase {
+    public AsyncLoggerConfigThreadContextCopyOnWriteTest() {
+        super(ContextImpl.COPY_ON_WRITE, Mode.MIXED);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java
new file mode 100644
index 0000000..900a055
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java
@@ -0,0 +1,26 @@
+/*
+ * 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.core.async;
+
+// Note: the different ThreadContextMap implementations cannot be parameterized:
+// ThreadContext initialization will result in static final fields being set in various components.
+// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+public class AsyncLoggerConfigThreadContextDefaultTest extends AbstractAsyncThreadContextTestBase {
+    public AsyncLoggerConfigThreadContextDefaultTest() {
+        super(ContextImpl.WEBAPP, Mode.MIXED);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java
new file mode 100644
index 0000000..1afd311
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java
@@ -0,0 +1,26 @@
+/*
+ * 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.core.async;
+
+// Note: the different ThreadContextMap implementations cannot be parameterized:
+// ThreadContext initialization will result in static final fields being set in various components.
+// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+public class AsyncLoggerConfigThreadContextGarbageFreeTest extends AbstractAsyncThreadContextTestBase {
+    public AsyncLoggerConfigThreadContextGarbageFreeTest() {
+        super(ContextImpl.GARBAGE_FREE, Mode.MIXED);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java
new file mode 100644
index 0000000..82b8f1c
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.async;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+// Note: the different ThreadContextMap implementations cannot be parameterized:
+// ThreadContext initialization will result in static final fields being set in various components.
+// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+@RunWith(Parameterized.class)
+public class AsyncLoggerThreadContextCopyOnWriteTest extends AbstractAsyncThreadContextTestBase {
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                { ContextImpl.COPY_ON_WRITE, Mode.ALL_ASYNC},
+                { ContextImpl.COPY_ON_WRITE, Mode.BOTH_ALL_ASYNC_AND_MIXED}
+        });
+    }
+    public AsyncLoggerThreadContextCopyOnWriteTest(final ContextImpl contextImpl, final Mode asyncMode) {
+        super(contextImpl, asyncMode);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java
new file mode 100644
index 0000000..8ed73a2
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.async;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+// Note: the different ThreadContextMap implementations cannot be parameterized:
+// ThreadContext initialization will result in static final fields being set in various components.
+// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+@RunWith(Parameterized.class)
+public class AsyncLoggerThreadContextDefaultTest extends AbstractAsyncThreadContextTestBase {
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                { ContextImpl.WEBAPP, Mode.ALL_ASYNC},
+                { ContextImpl.WEBAPP, Mode.BOTH_ALL_ASYNC_AND_MIXED},
+        });
+    }
+    public AsyncLoggerThreadContextDefaultTest(final ContextImpl contextImpl, final Mode asyncMode) {
+        super(contextImpl, asyncMode);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b679156b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java
new file mode 100644
index 0000000..ec3d755
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.async;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+// Note: the different ThreadContextMap implementations cannot be parameterized:
+// ThreadContext initialization will result in static final fields being set in various components.
+// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+@RunWith(Parameterized.class)
+public class AsyncLoggerThreadContextGarbageFreeTest extends AbstractAsyncThreadContextTestBase {
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                { ContextImpl.GARBAGE_FREE, Mode.ALL_ASYNC},
+                { ContextImpl.GARBAGE_FREE, Mode.BOTH_ALL_ASYNC_AND_MIXED},
+        });
+    }
+    public AsyncLoggerThreadContextGarbageFreeTest(final ContextImpl contextImpl, final Mode asyncMode) {
+        super(contextImpl, asyncMode);
+    }
+}