1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.slf4j.helpers;
26
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertFalse;
29 import static org.junit.Assert.assertNull;
30 import static org.junit.Assert.fail;
31
32 import java.lang.Thread.UncaughtExceptionHandler;
33 import java.util.Map;
34
35 import org.junit.After;
36 import org.junit.Test;
37 import org.slf4j.spi.MDCAdapter;
38
39
40
41
42
43
44 public class MDCAdapterTestBase {
45
46 protected MDCAdapter mdc = instantiateMDC();
47
48
49
50 protected MDCAdapter instantiateMDC() {
51 return new BasicMDCAdapter();
52 }
53
54
55 @After
56 public void tearDown() throws Exception {
57 mdc.clear();
58 }
59
60 @Test
61 public void testSettingAndGettingWithMDC() {
62 assertNull(mdc.get("testKey"));
63 mdc.put("testKey", "testValue");
64 assertEquals(mdc.get("testKey"), "testValue");
65 }
66
67 @Test
68 public void testOverwritingAKeyInMDC() {
69 assertNull(mdc.get("testKey"));
70 mdc.put("testKey", "testValue");
71 mdc.put("testKey", "differentTestValue");
72 assertEquals(mdc.get("testKey"), "differentTestValue");
73 }
74
75 @Test
76 public void testGetCopyOfContextMapFromMDC() {
77 mdc.put("testKey", "testValue");
78 Map<String, String> copy = mdc.getCopyOfContextMap();
79 mdc.put("anotherTestKey", "anotherTestValue");
80 assertFalse(copy.size() == mdc.getCopyOfContextMap().size());
81 }
82
83 @Test
84 public void testMDCInheritsValuesFromParentThread() throws Exception {
85 mdc.put("parentKey", "parentValue");
86 runAndWait(() -> {
87 mdc.put("childKey", "childValue");
88 assertEquals("parentValue", mdc.get("parentKey"));
89 });
90 }
91
92 @Test
93 public void testMDCDoesntGetValuesFromChildThread() throws Exception {
94 mdc.put("parentKey", "parentValue");
95 runAndWait(() -> mdc.put("childKey", "childValue"));
96 assertEquals("parentValue", mdc.get("parentKey"));
97 assertNull(mdc.get("childKey"));
98 }
99
100
101 @Test
102 public void testInvokingSetContextMap_WithANullMap_SLF4J_414() {
103 mdc.setContextMap(null);
104 }
105
106 @Test
107 public void testMDCChildThreadCanOverwriteParentThread() throws Exception {
108 mdc.put("sharedKey", "parentValue");
109 runAndWait(() -> {
110 assertEquals("parentValue", mdc.get("sharedKey"));
111 mdc.put("sharedKey", "childValue");
112 assertEquals("childValue", mdc.get("sharedKey"));
113 });
114 assertEquals("parentValue", mdc.get("sharedKey"));
115 }
116
117 private void runAndWait(Runnable runnable) {
118 RecordingExceptionHandler handler = new RecordingExceptionHandler();
119 Thread thread = new Thread(runnable);
120 thread.setUncaughtExceptionHandler(handler);
121 thread.start();
122 try {
123 thread.join();
124 } catch (Throwable t) {
125 fail("Unexpected failure in child thread:" + t.getMessage());
126 }
127 assertFalse(handler.getMessage(), handler.hadException());
128 }
129
130
131 private static class RecordingExceptionHandler implements UncaughtExceptionHandler {
132 private Throwable exception;
133
134 @Override
135 public void uncaughtException(Thread t, Throwable e) {
136 exception = e;
137 }
138
139 boolean hadException() {
140 return exception != null;
141 }
142
143 String getMessage() {
144 return exception != null ? exception.getMessage() : "";
145 }
146 }
147 }