2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.logging.context;
24 import org.testng.annotations.Test;
26 import java.util.UUID;
27 import java.util.concurrent.atomic.AtomicBoolean;
29 import static org.testng.Assert.*;
35 public class MDCPropagationFactoryTest {
37 // Disable if an old version of MDC implementation is being used.
38 // MDCPropagationFactory should be used when MDC is not propagated to child threads.
39 // See https://jira.qos.ch/browse/LOGBACK-422 and https://jira.qos.ch/browse/LOGBACK-624
40 private static final boolean ENABLED = false;
42 @Test(enabled = ENABLED)
43 public void testNoPropagation() throws InterruptedException {
45 String uuid = UUID.randomUUID().toString();
46 AtomicBoolean complete = new AtomicBoolean(false);
47 MDC.put("data", uuid);
49 Runnable runnable = () -> {
50 assertNull(MDC.get("data"), "Data unexpectedly copied to a child thread. " +
51 "Are you using an old version of MDC implementation (e.g. logback)?");
55 Thread thread = new Thread(runnable);
59 assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
60 assertTrue(complete.get(), "Expected the inner thread to run");
63 @Test(enabled = ENABLED)
64 public void testPropagation() throws InterruptedException {
66 String uuid = UUID.randomUUID().toString();
67 AtomicBoolean complete = new AtomicBoolean(false);
68 MDC.put("data", uuid);
70 MDCPropagationService factory = new MDCPropagationService();
71 Runnable runnable = factory.create(() -> {
72 assertEquals(MDC.get("data"), uuid, "Expected data to be propagated to the child thread's MDC");
76 Thread thread = new Thread(runnable);
81 assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
82 assertTrue(complete.get(), "Expected the inner thread to run");
85 @Test(enabled = ENABLED)
86 public void testReplacement() throws InterruptedException {
88 String innerUuid = UUID.randomUUID().toString();
89 AtomicBoolean innerComplete = new AtomicBoolean(false);
90 AtomicBoolean outerComplete = new AtomicBoolean(false);
92 MDC.put("data", innerUuid);
94 MDCPropagationService factory = new MDCPropagationService();
96 // should run with the context of main thread
97 Runnable inner = factory.create(() -> {
98 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
99 innerComplete.set(true);
102 // pushes its own context, but runs the inner runnable
103 Runnable outer = () -> {
104 String outerUuid = UUID.randomUUID().toString();
105 MDC.put("data", outerUuid);
107 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be replaced with stored data");
108 outerComplete.set(true);
112 Thread thread = new Thread(outer);
116 assertEquals(MDC.get("data"), innerUuid, "Expected data to be retained in this thread");
117 assertTrue(outerComplete.get(), "Expected the outer thread to run");
118 assertTrue(innerComplete.get(), "Expected the inner thread to run");
121 @Test(enabled = ENABLED)
122 public void testEmpty() throws InterruptedException {
124 final AtomicBoolean complete = new AtomicBoolean(false);
127 assertNull(MDC.get("data"), "Expected MDC data to be empty");
129 MDCPropagationService factory = new MDCPropagationService();
130 Runnable runnable = factory.create(() -> {
131 assertNull(MDC.get("data"), "Expected MDC data to be empty");
135 Thread thread = new Thread(runnable);
139 assertNull(MDC.get("data"), "Expected MDC data to be empty");
140 assertTrue(complete.get(), "Expected the inner thread to run");
143 @Test(enabled = ENABLED)
144 public void testCleanup() throws Exception {
146 String innerUuid = UUID.randomUUID().toString();
147 AtomicBoolean innerComplete = new AtomicBoolean(false);
148 AtomicBoolean outerComplete = new AtomicBoolean(false);
150 MDC.put("data", innerUuid);
152 MDCPropagationService factory = new MDCPropagationService();
154 // should run with the context of main thread
155 Runnable inner = factory.create(() -> {
156 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
157 innerComplete.set(true);
160 // pushes its own context, but runs the inner runnable
161 Runnable outer = () -> {
162 assertNull(MDC.get("data"), "Expected MDC data not to be copied to this thread");
164 assertNull(MDC.get("data"), "Expected MDC data to remain empty in this thread");
165 outerComplete.set(true);
168 Thread thread = new Thread(outer);
172 assertEquals(MDC.get("data"), innerUuid, "Expected MDC data to be retained in parent thread");
173 assertTrue(outerComplete.get(), "Expected the outer thread to run");
174 assertTrue(innerComplete.get(), "Expected the inner thread to run");
177 @Test(enabled = ENABLED)
178 public void testCleanupAfterError() throws Exception {
180 String innerUuid = UUID.randomUUID().toString();
181 AtomicBoolean innerComplete = new AtomicBoolean(false);
182 AtomicBoolean outerComplete = new AtomicBoolean(false);
183 AtomicBoolean exceptionThrown = new AtomicBoolean(false);
185 MDC.put("data", innerUuid);
187 MDCPropagationService factory = new MDCPropagationService();
189 // should run with the context of main thread
190 Runnable inner = factory.create(() -> {
191 assertEquals(MDC.get("data"), innerUuid, "Expected data to be propagated to the child thread's MDC");
192 innerComplete.set(true);
193 throw new RuntimeException();
196 // pushes its own context, but runs the inner runnable
197 Runnable outer = () -> {
199 String outerUuid = UUID.randomUUID().toString();
200 MDC.put("data", outerUuid);
201 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be populated in this thread");
205 } catch (RuntimeException e) {
206 exceptionThrown.set(true);
208 assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be reverted even in case of exception");
209 outerComplete.set(true);
213 Thread thread = new Thread(outer);
217 assertEquals(MDC.get("data"), innerUuid, "Expected MDC data to be retained in parent thread");
218 assertTrue(outerComplete.get(), "Expected the outer thread to run");
219 assertTrue(innerComplete.get(), "Expected the inner thread to run");
220 assertTrue(exceptionThrown.get(), "Expected the inner class to throw exception");