blob: 2742da1e9f4bee2044660f0f6b84c96213ddb953 [file] [log] [blame]
package org.apache.logging.log4j.core.impl;
import java.util.Collection;
import java.util.concurrent.ExecutionException;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.ThreadContextTest;
import org.apache.logging.log4j.core.ContextDataInjector;
import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap;
import org.apache.logging.log4j.util.PropertiesUtil;
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.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
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.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;
@RunWith(Parameterized.class)
public class ThreadContextDataInjectorTest {
@Parameters(name = "{0}")
public static Collection<String[]> threadContextMapClassNames() {
return asList(new String[][] {
{ "org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap", "org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap" },
{ "org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap", "org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap" },
{ "org.apache.logging.log4j.spi.DefaultThreadContextMap", null }
});
}
@Parameter
public String threadContextMapClassName;
@Parameter(value = 1)
public String readOnlythreadContextMapClassName;
@Before
public void before() {
System.setProperty("log4j2.threadContextMap", threadContextMapClassName);
}
@After
public void after() {
ThreadContext.remove("foo");
ThreadContext.remove("baz");
System.clearProperty("log4j2.threadContextMap");
System.clearProperty("log4j2.isThreadContextMapInheritable");
}
private void testContextDataInjector() {
ReadOnlyThreadContextMap readOnlythreadContextMap = getThreadContextMap();
assertThat("thread context map class name",
(readOnlythreadContextMap == null) ? null : readOnlythreadContextMap.getClass().getName(),
is(equalTo(readOnlythreadContextMapClassName)));
ContextDataInjector contextDataInjector = createInjector();
StringMap stringMap = contextDataInjector.injectContextData(null, new SortedArrayStringMap());
assertThat("thread context map", ThreadContext.getContext(), allOf(hasEntry("foo", "bar"), not(hasKey("baz"))));
assertThat("context map", stringMap.toMap(), allOf(hasEntry("foo", "bar"), not(hasKey("baz"))));
if (!stringMap.isFrozen()) {
stringMap.clear();
assertThat("thread context map", ThreadContext.getContext(), allOf(hasEntry("foo", "bar"), not(hasKey("baz"))));
assertThat("context map", stringMap.toMap().entrySet(), is(empty()));
}
ThreadContext.put("foo", "bum");
ThreadContext.put("baz", "bam");
assertThat("thread context map", ThreadContext.getContext(), allOf(hasEntry("foo", "bum"), hasEntry("baz", "bam")));
if (stringMap.isFrozen()) {
assertThat("context map", stringMap.toMap(), allOf(hasEntry("foo", "bar"), not(hasKey("baz"))));
} else {
assertThat("context map", stringMap.toMap().entrySet(), is(empty()));
}
}
private void prepareThreadContext(boolean isThreadContextMapInheritable) {
System.setProperty("log4j2.isThreadContextMapInheritable", Boolean.toString(isThreadContextMapInheritable));
PropertiesUtil.getProperties().reload();
ThreadContextTest.reinitThreadContext();
ThreadContext.remove("baz");
ThreadContext.put("foo", "bar");
}
@Test
public void testThreadContextImmutability() {
prepareThreadContext(false);
testContextDataInjector();
}
@Test
public void testInheritableThreadContextImmutability() throws Throwable {
prepareThreadContext(true);
try {
newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
testContextDataInjector();
}
}).get();
} catch (ExecutionException ee) {
throw ee.getCause();
}
}
}