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.slf4j;
19 import static org.junit.Assert.assertTrue;
20 import static org.junit.Assume.assumeTrue;
21 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_EMPTY;
22 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_EXCEPTION_FROM_INNER;
23 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_INNER_RUN;
24 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_NOT_COPIED;
25 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_OUTER_RUN;
26 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_POPULATED;
27 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_PROPAGATED_TO_CHILD;
28 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_REMAIN_EMPTY;
29 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_REPLACED_WITH_STORED;
30 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_RETAINED_IN_CURRENT;
31 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_RETAINED_IN_PARENT;
32 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.EXPECT_REVERTED_ON_EXCEPTION;
33 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.IS_SUITABLE_LOGBACK_VERSION;
34 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.assertContextEmpty;
35 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.assertContextFields;
36 import static org.openecomp.sdc.logging.slf4j.ContextPropagationTestHelper.putUniqueValues;
39 import java.util.concurrent.Callable;
40 import java.util.concurrent.ExecutorService;
41 import java.util.concurrent.Executors;
42 import java.util.concurrent.Future;
43 import java.util.concurrent.TimeUnit;
44 import java.util.concurrent.atomic.AtomicBoolean;
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.openecomp.sdc.logging.spi.LoggingContextService;
50 * Tests propagation of logging fields to Callable via the logging service.
55 @SuppressWarnings("DefaultAnnotationParam") // see the comment to ENABLED
56 public class CallableContextPropagationTest {
58 private final LoggingContextService ctxService = new SLF4JLoggingServiceProvider();
61 public void checkSuitableLogbackVersion() {
62 assumeTrue(IS_SUITABLE_LOGBACK_VERSION);
66 public void testContextPropagated() throws Exception {
68 Map<ContextField, String> values = putUniqueValues();
69 AtomicBoolean complete = new AtomicBoolean(false);
71 // pass the callable to the context service first
72 execute(ctxService.copyToCallable(() -> {
73 assertContextFields(EXPECT_PROPAGATED_TO_CHILD, values);
78 assertContextFields(EXPECT_RETAINED_IN_CURRENT, values);
79 assertTrue(EXPECT_INNER_RUN, complete.get());
83 public void testContextReplacement() throws Exception {
85 Map<ContextField, String> innerValues = putUniqueValues();
86 AtomicBoolean innerComplete = new AtomicBoolean(false);
88 // should run with the context of main thread
89 Callable inner = ctxService.copyToCallable(() -> {
90 assertContextFields(EXPECT_PROPAGATED_TO_CHILD, innerValues);
91 innerComplete.set(true);
95 // pushes its own context, but the inner must run with its own context
96 AtomicBoolean outerComplete = new AtomicBoolean(false);
98 Map<ContextField, String> outerValues = putUniqueValues();
100 assertContextFields(EXPECT_REPLACED_WITH_STORED, outerValues);
101 outerComplete.set(true);
105 assertContextFields(EXPECT_RETAINED_IN_CURRENT, innerValues);
106 assertTrue(EXPECT_OUTER_RUN, outerComplete.get());
107 assertTrue(EXPECT_INNER_RUN, innerComplete.get());
111 public void testContextRemainsEmpty() throws Exception {
114 assertContextEmpty(EXPECT_EMPTY);
116 final AtomicBoolean complete = new AtomicBoolean(false);
117 execute(ctxService.copyToCallable(() -> {
118 assertContextEmpty(EXPECT_EMPTY);
123 assertContextEmpty(EXPECT_EMPTY);
124 assertTrue(EXPECT_INNER_RUN, complete.get());
128 public void testContextCleanedUp() throws Exception {
130 Map<ContextField, String> innerValues = putUniqueValues();
132 AtomicBoolean innerComplete = new AtomicBoolean(false);
133 // should run with the context of main thread
134 Callable inner = ctxService.copyToCallable((() -> {
135 assertContextFields(EXPECT_PROPAGATED_TO_CHILD, innerValues);
136 innerComplete.set(true);
140 // pushes its own context, but runs the inner
141 AtomicBoolean outerComplete = new AtomicBoolean(false);
143 assertContextEmpty(EXPECT_NOT_COPIED);
145 assertContextEmpty(EXPECT_REMAIN_EMPTY);
146 outerComplete.set(true);
150 assertContextFields(EXPECT_RETAINED_IN_PARENT, innerValues);
151 assertTrue(EXPECT_OUTER_RUN, outerComplete.get());
152 assertTrue(EXPECT_INNER_RUN, innerComplete.get());
156 public void testCleanupAfterError() throws Exception {
158 Map<ContextField, String> innerValues = putUniqueValues();
160 // should run with the context of main thread
161 AtomicBoolean innerComplete = new AtomicBoolean(false);
162 Callable inner = ctxService.copyToCallable(() -> {
163 assertContextFields(EXPECT_PROPAGATED_TO_CHILD, innerValues);
164 innerComplete.set(true);
165 throw new IllegalArgumentException();
168 // pushes its own context, but runs the inner callable
169 AtomicBoolean outerComplete = new AtomicBoolean(false);
170 AtomicBoolean exceptionThrown = new AtomicBoolean(false);
173 Map<ContextField, String> outerValues = putUniqueValues();
174 assertContextFields(EXPECT_POPULATED, outerValues);
178 } catch (IllegalArgumentException e) {
179 exceptionThrown.set(true);
181 assertContextFields(EXPECT_REVERTED_ON_EXCEPTION, outerValues);
182 outerComplete.set(true);
188 assertContextFields(EXPECT_RETAINED_IN_PARENT, innerValues);
189 assertTrue(EXPECT_OUTER_RUN, outerComplete.get());
190 assertTrue(EXPECT_INNER_RUN, innerComplete.get());
191 assertTrue(EXPECT_EXCEPTION_FROM_INNER, exceptionThrown.get());
194 private void execute(Callable<Object> callable) throws Exception {
196 ExecutorService executor = Executors.newSingleThreadExecutor();
199 Future<Object> future = executor.submit(callable);
200 future.get(10, TimeUnit.SECONDS);