2 * Copyright © 2016-2017 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.logging.context;
20 import org.testng.annotations.Test;
22 import java.util.UUID;
23 import java.util.concurrent.atomic.AtomicBoolean;
25 import static org.testng.Assert.assertEquals;
26 import static org.testng.Assert.assertNull;
27 import static org.testng.Assert.assertTrue;
33 public class MDCPropagationFactoryTest {
35 // Disable if an old version of MDC implementation is being used.
36 // MDCPropagationFactory should be used when MDC is not propagated to child threads.
37 // See https://jira.qos.ch/browse/LOGBACK-422 and https://jira.qos.ch/browse/LOGBACK-624
38 private static final boolean ENABLED = false;
40 @Test(enabled = ENABLED)
41 public void testNoPropagation() throws InterruptedException {
43 String uuid = UUID.randomUUID().toString();
44 AtomicBoolean complete = new AtomicBoolean(false);
45 MDC.put("data", uuid);
47 Runnable runnable = () -> {
48 assertNull(MDC.get("data"), "Data unexpectedly copied to a child thread. " +
49 "Are you using an old version of MDC implementation (e.g. logback)?");
53 Thread thread = new Thread(runnable);
57 assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
58 assertTrue(complete.get(), "Expected the inner thread to run");
61 @Test(enabled = ENABLED)
62 public void testPropagation() throws InterruptedException {
64 String uuid = UUID.randomUUID().toString();
65 AtomicBoolean complete = new AtomicBoolean(false);
66 MDC.put("data", uuid);
68 MDCPropagationService factory = new MDCPropagationService();
69 Runnable runnable = factory.create(() -> {
70 assertEquals(MDC.get("data"), uuid, "Expected data to be propagated to the child thread's MDC");
74 Thread thread = new Thread(runnable);
79 assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
80 assertTrue(complete.get(), "Expected the inner thread to run");
83 @Test(enabled = ENABLED)
84 public void testReplacement() throws InterruptedException {
86 String innerUuid = UUID.randomUUID().toString();
87 AtomicBoolean innerComplete = new AtomicBoolean(false);
88 AtomicBoolean outerComplete = new AtomicBoolean(false);
90 MDC.put("data", innerUuid);
92 MDCPropagationService factory = new MDCPropagationService();
94 // should run with the context of main thread
95 Runnable inner = factory.create(() -> {
96 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
97 innerComplete.set(true);
100 // pushes its own context, but runs the inner runnable
101 Runnable outer = () -> {
102 String outerUuid = UUID.randomUUID().toString();
103 MDC.put("data", outerUuid);
105 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be replaced with stored data");
106 outerComplete.set(true);
110 Thread thread = new Thread(outer);
114 assertEquals(MDC.get("data"), innerUuid, "Expected data to be retained in this thread");
115 assertTrue(outerComplete.get(), "Expected the outer thread to run");
116 assertTrue(innerComplete.get(), "Expected the inner thread to run");
119 @Test(enabled = ENABLED)
120 public void testEmpty() throws InterruptedException {
122 final AtomicBoolean complete = new AtomicBoolean(false);
125 assertNull(MDC.get("data"), "Expected MDC data to be empty");
127 MDCPropagationService factory = new MDCPropagationService();
128 Runnable runnable = factory.create(() -> {
129 assertNull(MDC.get("data"), "Expected MDC data to be empty");
133 Thread thread = new Thread(runnable);
137 assertNull(MDC.get("data"), "Expected MDC data to be empty");
138 assertTrue(complete.get(), "Expected the inner thread to run");
141 @Test(enabled = ENABLED)
142 public void testCleanup() throws Exception {
144 String innerUuid = UUID.randomUUID().toString();
145 AtomicBoolean innerComplete = new AtomicBoolean(false);
146 AtomicBoolean outerComplete = new AtomicBoolean(false);
148 MDC.put("data", innerUuid);
150 MDCPropagationService factory = new MDCPropagationService();
152 // should run with the context of main thread
153 Runnable inner = factory.create(() -> {
154 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
155 innerComplete.set(true);
158 // pushes its own context, but runs the inner runnable
159 Runnable outer = () -> {
160 assertNull(MDC.get("data"), "Expected MDC data not to be copied to this thread");
162 assertNull(MDC.get("data"), "Expected MDC data to remain empty in this thread");
163 outerComplete.set(true);
166 Thread thread = new Thread(outer);
170 assertEquals(MDC.get("data"), innerUuid, "Expected MDC data to be retained in parent thread");
171 assertTrue(outerComplete.get(), "Expected the outer thread to run");
172 assertTrue(innerComplete.get(), "Expected the inner thread to run");
175 @Test(enabled = ENABLED)
176 public void testCleanupAfterError() throws Exception {
178 String innerUuid = UUID.randomUUID().toString();
179 AtomicBoolean innerComplete = new AtomicBoolean(false);
180 AtomicBoolean outerComplete = new AtomicBoolean(false);
181 AtomicBoolean exceptionThrown = new AtomicBoolean(false);
183 MDC.put("data", innerUuid);
185 MDCPropagationService factory = new MDCPropagationService();
187 // should run with the context of main thread
188 Runnable inner = factory.create(() -> {
189 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
190 innerComplete.set(true);
191 throw new RuntimeException();
194 // pushes its own context, but runs the inner runnable
195 Runnable outer = () -> {
197 String outerUuid = UUID.randomUUID().toString();
198 MDC.put("data", outerUuid);
199 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be populated in this thread");
203 } catch (RuntimeException e) {
204 exceptionThrown.set(true);
206 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be reverted even in case of exception");
207 outerComplete.set(true);
211 Thread thread = new Thread(outer);
215 assertEquals(MDC.get("data"), innerUuid, "Expected MDC data to be retained in parent thread");
216 assertTrue(outerComplete.get(), "Expected the outer thread to run");
217 assertTrue(innerComplete.get(), "Expected the inner thread to run");
218 assertTrue(exceptionThrown.get(), "Expected the inner class to throw exception");