Add collaboration feature
[sdc.git] / openecomp-be / lib / openecomp-sdc-logging-lib / openecomp-sdc-logging-core / src / test / java / org / openecomp / sdc / logging / context / MDCPropagationFactoryTest.java
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
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
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
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.
15  */
16
17 package org.openecomp.sdc.logging.context;
18
19 import org.slf4j.MDC;
20 import org.testng.annotations.Test;
21
22 import java.util.UUID;
23 import java.util.concurrent.atomic.AtomicBoolean;
24
25 import static org.testng.Assert.assertEquals;
26 import static org.testng.Assert.assertNull;
27 import static org.testng.Assert.assertTrue;
28
29 /**
30  * @author evitaliy
31  * @since 12/09/2016.
32  */
33 public class MDCPropagationFactoryTest {
34
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;
39
40   @Test(enabled = ENABLED)
41   public void testNoPropagation() throws InterruptedException {
42
43     String uuid = UUID.randomUUID().toString();
44     AtomicBoolean complete = new AtomicBoolean(false);
45     MDC.put("data", uuid);
46
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)?");
50       complete.set(true);
51     };
52
53     Thread thread = new Thread(runnable);
54     thread.start();
55     thread.join();
56
57     assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
58     assertTrue(complete.get(), "Expected the inner thread to run");
59   }
60
61   @Test(enabled = ENABLED)
62   public void testPropagation() throws InterruptedException {
63
64     String uuid = UUID.randomUUID().toString();
65     AtomicBoolean complete = new AtomicBoolean(false);
66     MDC.put("data", uuid);
67
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");
71       complete.set(true);
72     });
73
74     Thread thread = new Thread(runnable);
75     thread.start();
76
77     thread.join();
78
79     assertEquals(MDC.get("data"), uuid, "Expected data to be retained in this thread");
80     assertTrue(complete.get(), "Expected the inner thread to run");
81   }
82
83   @Test(enabled = ENABLED)
84   public void testReplacement() throws InterruptedException {
85
86     String innerUuid = UUID.randomUUID().toString();
87     AtomicBoolean innerComplete = new AtomicBoolean(false);
88     AtomicBoolean outerComplete = new AtomicBoolean(false);
89
90     MDC.put("data", innerUuid);
91
92     MDCPropagationService factory = new MDCPropagationService();
93
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);
98     });
99
100     // pushes its own context, but runs the inner runnable
101     Runnable outer = () -> {
102       String outerUuid = UUID.randomUUID().toString();
103       MDC.put("data", outerUuid);
104       inner.run();
105       assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be replaced with stored data");
106       outerComplete.set(true);
107     };
108
109
110     Thread thread = new Thread(outer);
111     thread.start();
112     thread.join();
113
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");
117   }
118
119   @Test(enabled = ENABLED)
120   public void testEmpty() throws InterruptedException {
121
122     final AtomicBoolean complete = new AtomicBoolean(false);
123
124     MDC.remove("data");
125     assertNull(MDC.get("data"), "Expected MDC data to be empty");
126
127     MDCPropagationService factory = new MDCPropagationService();
128     Runnable runnable = factory.create(() -> {
129       assertNull(MDC.get("data"), "Expected MDC data to be empty");
130       complete.set(true);
131     });
132
133     Thread thread = new Thread(runnable);
134     thread.start();
135     thread.join();
136
137     assertNull(MDC.get("data"), "Expected MDC data to be empty");
138     assertTrue(complete.get(), "Expected the inner thread to run");
139   }
140
141   @Test(enabled = ENABLED)
142   public void testCleanup() throws Exception {
143
144     String innerUuid = UUID.randomUUID().toString();
145     AtomicBoolean innerComplete = new AtomicBoolean(false);
146     AtomicBoolean outerComplete = new AtomicBoolean(false);
147
148     MDC.put("data", innerUuid);
149
150     MDCPropagationService factory = new MDCPropagationService();
151
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);
156     });
157
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");
161       inner.run();
162       assertNull(MDC.get("data"), "Expected MDC data to remain empty in this thread");
163       outerComplete.set(true);
164     };
165
166     Thread thread = new Thread(outer);
167     thread.start();
168     thread.join();
169
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");
173   }
174
175   @Test(enabled = ENABLED)
176   public void testCleanupAfterError() throws Exception {
177
178     String innerUuid = UUID.randomUUID().toString();
179     AtomicBoolean innerComplete = new AtomicBoolean(false);
180     AtomicBoolean outerComplete = new AtomicBoolean(false);
181     AtomicBoolean exceptionThrown = new AtomicBoolean(false);
182
183     MDC.put("data", innerUuid);
184
185     MDCPropagationService factory = new MDCPropagationService();
186
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();
192     });
193
194     // pushes its own context, but runs the inner runnable
195     Runnable outer = () -> {
196
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");
200
201       try {
202         inner.run();
203       } catch (RuntimeException e) {
204         exceptionThrown.set(true);
205       } finally {
206         assertEquals(MDC.get("data"), outerUuid, "Expected MDC data to be reverted even in case of exception");
207         outerComplete.set(true);
208       }
209     };
210
211     Thread thread = new Thread(outer);
212     thread.start();
213     thread.join();
214
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");
219   }
220
221 }