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.*;
31 public class MDCPropagationFactoryTest {
33 // Disable if an old version of MDC implementation is being used.
34 // MDCPropagationFactory should be used when MDC is not propagated to child threads.
35 // See https://jira.qos.ch/browse/LOGBACK-422 and https://jira.qos.ch/browse/LOGBACK-624
36 private static final boolean ENABLED = false;
38 @Test(enabled = ENABLED)
39 public void testNoPropagation() throws InterruptedException {
41 String uuid = UUID.randomUUID().toString();
42 AtomicBoolean complete = new AtomicBoolean(false);
43 MDC.put("data", uuid);
45 Runnable runnable = () -> {
46 assertNull(MDC.get("data"), "Data unexpectedly copied to a child thread. " +
47 "Are you using an old version of MDC implementation (e.g. logback)?");
51 Thread thread = new Thread(runnable);
55 assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
56 assertTrue(complete.get(), "Expected the inner thread to run");
59 @Test(enabled = ENABLED)
60 public void testPropagation() throws InterruptedException {
62 String uuid = UUID.randomUUID().toString();
63 AtomicBoolean complete = new AtomicBoolean(false);
64 MDC.put("data", uuid);
66 MDCPropagationService factory = new MDCPropagationService();
67 Runnable runnable = factory.create(() -> {
68 assertEquals(MDC.get("data"), uuid, "Expected data to be propagated to the child thread's MDC");
72 Thread thread = new Thread(runnable);
77 assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
78 assertTrue(complete.get(), "Expected the inner thread to run");
81 @Test(enabled = ENABLED)
82 public void testReplacement() throws InterruptedException {
84 String innerUuid = UUID.randomUUID().toString();
85 AtomicBoolean innerComplete = new AtomicBoolean(false);
86 AtomicBoolean outerComplete = new AtomicBoolean(false);
88 MDC.put("data", innerUuid);
90 MDCPropagationService factory = new MDCPropagationService();
92 // should run with the context of main thread
93 Runnable inner = factory.create(() -> {
94 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
95 innerComplete.set(true);
98 // pushes its own context, but runs the inner runnable
99 Runnable outer = () -> {
100 String outerUuid = UUID.randomUUID().toString();
101 MDC.put("data", outerUuid);
103 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be replaced with stored data");
104 outerComplete.set(true);
108 Thread thread = new Thread(outer);
112 assertEquals(MDC.get("data"), innerUuid, "Expected data to be retained in this thread");
113 assertTrue(outerComplete.get(), "Expected the outer thread to run");
114 assertTrue(innerComplete.get(), "Expected the inner thread to run");
117 @Test(enabled = ENABLED)
118 public void testEmpty() throws InterruptedException {
120 final AtomicBoolean complete = new AtomicBoolean(false);
123 assertNull(MDC.get("data"), "Expected MDC data to be empty");
125 MDCPropagationService factory = new MDCPropagationService();
126 Runnable runnable = factory.create(() -> {
127 assertNull(MDC.get("data"), "Expected MDC data to be empty");
131 Thread thread = new Thread(runnable);
135 assertNull(MDC.get("data"), "Expected MDC data to be empty");
136 assertTrue(complete.get(), "Expected the inner thread to run");
139 @Test(enabled = ENABLED)
140 public void testCleanup() throws Exception {
142 String innerUuid = UUID.randomUUID().toString();
143 AtomicBoolean innerComplete = new AtomicBoolean(false);
144 AtomicBoolean outerComplete = new AtomicBoolean(false);
146 MDC.put("data", innerUuid);
148 MDCPropagationService factory = new MDCPropagationService();
150 // should run with the context of main thread
151 Runnable inner = factory.create(() -> {
152 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
153 innerComplete.set(true);
156 // pushes its own context, but runs the inner runnable
157 Runnable outer = () -> {
158 assertNull(MDC.get("data"), "Expected MDC data not to be copied to this thread");
160 assertNull(MDC.get("data"), "Expected MDC data to remain empty in this thread");
161 outerComplete.set(true);
164 Thread thread = new Thread(outer);
168 assertEquals(MDC.get("data"), innerUuid, "Expected MDC data to be retained in parent thread");
169 assertTrue(outerComplete.get(), "Expected the outer thread to run");
170 assertTrue(innerComplete.get(), "Expected the inner thread to run");
173 @Test(enabled = ENABLED)
174 public void testCleanupAfterError() throws Exception {
176 String innerUuid = UUID.randomUUID().toString();
177 AtomicBoolean innerComplete = new AtomicBoolean(false);
178 AtomicBoolean outerComplete = new AtomicBoolean(false);
179 AtomicBoolean exceptionThrown = new AtomicBoolean(false);
181 MDC.put("data", innerUuid);
183 MDCPropagationService factory = new MDCPropagationService();
185 // should run with the context of main thread
186 Runnable inner = factory.create(() -> {
187 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
188 innerComplete.set(true);
189 throw new RuntimeException();
192 // pushes its own context, but runs the inner runnable
193 Runnable outer = () -> {
195 String outerUuid = UUID.randomUUID().toString();
196 MDC.put("data", outerUuid);
197 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be populated in this thread");
201 } catch (RuntimeException e) {
202 exceptionThrown.set(true);
204 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be reverted even in case of exception");
205 outerComplete.set(true);
209 Thread thread = new Thread(outer);
213 assertEquals(MDC.get("data"), innerUuid, "Expected MDC data to be retained in parent thread");
214 assertTrue(outerComplete.get(), "Expected the outer thread to run");
215 assertTrue(innerComplete.get(), "Expected the inner thread to run");
216 assertTrue(exceptionThrown.get(), "Expected the inner class to throw exception");