5fad3f70c5aad15a5f52b8a757f278fc926810fb
[sdc.git] / openecomp-be / lib / openecomp-sdc-logging-lib / openecomp-sdc-logging-core / src / test / java / org / openecomp / sdc / logging / slf4j / CallableContextPropagationTest.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.slf4j;
18
19 import org.openecomp.sdc.logging.provider.LoggingContextService;
20 import org.testng.annotations.Test;
21
22 import java.util.UUID;
23 import java.util.concurrent.Callable;
24 import java.util.concurrent.ExecutorService;
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.TimeUnit;
28 import java.util.concurrent.atomic.AtomicBoolean;
29
30 import static org.testng.Assert.assertEquals;
31 import static org.testng.Assert.assertNull;
32 import static org.testng.Assert.assertTrue;
33
34 /**
35  * @author EVITALIY
36  * @since 08 Jan 18
37  */
38 public class CallableContextPropagationTest extends BaseContextPropagationTest {
39
40     @Test(enabled = ENABLED, dataProvider = PROVIDER)
41     public void testContextPropagated(LoggingContextService ctx) throws Exception {
42
43         String uuid = UUID.randomUUID().toString();
44         ctx.put(KEY, uuid);
45
46         AtomicBoolean complete = new AtomicBoolean(false);
47
48         // pass the callable to the context service first
49         execute(ctx.toCallable(() -> {
50             assertEquals(ctx.get(KEY), uuid, EXPECT_PROPAGATED_TO_CHILD);
51             complete.set(true);
52             return null;
53         }));
54
55         assertEquals(ctx.get(KEY), uuid, EXPECT_RETAINED_IN_CURRENT);
56         assertTrue(complete.get(), EXPECT_INNER_RUN);
57     }
58
59     @Test(enabled = ENABLED, dataProvider = PROVIDER)
60     public void testContextReplacement(LoggingContextService ctx) throws Exception {
61
62         String innerRandom = UUID.randomUUID().toString();
63         ctx.put(KEY, innerRandom);
64
65         AtomicBoolean innerComplete = new AtomicBoolean(false);
66
67         // should run with the context of main thread
68         Callable inner = ctx.toCallable(() -> {
69             assertEquals(ctx.get(KEY), innerRandom, EXPECT_PROPAGATED_TO_CHILD);
70             innerComplete.set(true);
71             return null;
72         });
73
74         // pushes its own context, but the inner must run with its own context
75         AtomicBoolean outerComplete = new AtomicBoolean(false);
76         execute(() -> {
77             String outerUuid = UUID.randomUUID().toString();
78             ctx.put(KEY, outerUuid);
79             inner.call();
80             assertEquals(ctx.get(KEY), outerUuid, EXPECT_REPLACED_WITH_STORED);
81             outerComplete.set(true);
82             return null;
83         });
84
85         assertEquals(ctx.get(KEY), innerRandom, EXPECT_RETAINED_IN_CURRENT);
86         assertTrue(outerComplete.get(), EXPECT_OUTER_RUN);
87         assertTrue(innerComplete.get(), EXPECT_INNER_RUN);
88     }
89
90     @Test(enabled = ENABLED, dataProvider = PROVIDER)
91     public void testContextRemainsEmpty(LoggingContextService ctx) throws Exception {
92
93         ctx.remove(KEY);
94         assertNull(ctx.get(KEY), EXPECT_EMPTY);
95
96         final AtomicBoolean complete = new AtomicBoolean(false);
97         execute(ctx.toCallable(() -> {
98             assertNull(ctx.get(KEY), EXPECT_EMPTY);
99             complete.set(true);
100             return null;
101         }));
102
103         assertNull(ctx.get(KEY), EXPECT_EMPTY);
104         assertTrue(complete.get(), EXPECT_INNER_RUN);
105     }
106
107     @Test(enabled = ENABLED, dataProvider = PROVIDER)
108     public void testContextCleanedUp(LoggingContextService ctx) throws Exception {
109
110         String innerRandom = UUID.randomUUID().toString();
111         ctx.put(KEY, innerRandom);
112
113         AtomicBoolean innerComplete = new AtomicBoolean(false);
114         // should run with the context of main thread
115         Callable inner = ctx.toCallable((() -> {
116             assertEquals(ctx.get(KEY), innerRandom, EXPECT_PROPAGATED_TO_CHILD);
117             innerComplete.set(true);
118             return null;
119         }));
120
121         // pushes its own context, but runs the inner
122         AtomicBoolean outerComplete = new AtomicBoolean(false);
123         execute(() -> {
124             assertNull(ctx.get(KEY), EXPECT_NOT_COPIED);
125             inner.call();
126             assertNull(ctx.get(KEY), EXPECT_REMAIN_EMPTY);
127             outerComplete.set(true);
128             return null;
129         });
130
131         assertEquals(ctx.get(KEY), innerRandom, EXPECT_RETAINED_IN_PARENT);
132         assertTrue(outerComplete.get(), EXPECT_OUTER_RUN);
133         assertTrue(innerComplete.get(), EXPECT_INNER_RUN);
134     }
135
136     @Test(enabled = ENABLED, dataProvider = PROVIDER)
137     public void testCleanupAfterError(LoggingContextService ctx) throws Exception {
138
139         String innerRandom = UUID.randomUUID().toString();
140         ctx.put(KEY, innerRandom);
141
142         // should run with the context of main thread
143         AtomicBoolean innerComplete = new AtomicBoolean(false);
144         Callable inner = ctx.toCallable(() -> {
145             assertEquals(ctx.get(KEY), innerRandom, EXPECT_PROPAGATED_TO_CHILD);
146             innerComplete.set(true);
147             throw new IllegalArgumentException();
148         });
149
150         // pushes its own context, but runs the inner callable
151         AtomicBoolean outerComplete = new AtomicBoolean(false);
152         AtomicBoolean exceptionThrown = new AtomicBoolean(false);
153         execute(() -> {
154
155             String outerUuid = UUID.randomUUID().toString();
156             ctx.put(KEY, outerUuid);
157             assertEquals(ctx.get(KEY), outerUuid, EXPECT_POPULATED);
158
159             try {
160                 inner.call();
161             } catch (IllegalArgumentException e) {
162                 exceptionThrown.set(true);
163             } finally {
164                 assertEquals(ctx.get(KEY), outerUuid, EXPECT_REVERTED_ON_EXCEPTION);
165                 outerComplete.set(true);
166             }
167
168             return null;
169         });
170
171         assertEquals(ctx.get(KEY), innerRandom, EXPECT_RETAINED_IN_PARENT);
172         assertTrue(outerComplete.get(), EXPECT_OUTER_RUN);
173         assertTrue(innerComplete.get(), EXPECT_INNER_RUN);
174         assertTrue(exceptionThrown.get(), EXPECT_EXCEPTION_FROM_INNER);
175     }
176
177     private void execute(Callable<Object> callable) throws Exception {
178
179         ExecutorService executor = Executors.newSingleThreadExecutor();
180
181         try {
182             Future<Object> future = executor.submit(callable);
183             future.get(10, TimeUnit.SECONDS);
184         } finally {
185             executor.shutdown();
186         }
187     }
188 }