• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017, OpenCensus Authors
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 io.opencensus.trace;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.mockito.ArgumentMatchers.same;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.verifyZeroInteractions;
23 
24 import io.opencensus.common.Scope;
25 import io.opencensus.trace.unsafe.ContextHandleUtils;
26 import java.util.concurrent.Callable;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.junit.runners.JUnit4;
31 import org.mockito.Mock;
32 import org.mockito.MockitoAnnotations;
33 
34 /** Unit tests for {@link CurrentSpanUtils}. */
35 @RunWith(JUnit4.class)
36 public class CurrentSpanUtilsTest {
37   @Mock private Span span;
38 
39   @Before
setUp()40   public void setUp() {
41     MockitoAnnotations.initMocks(this);
42   }
43 
44   // TODO(bdrutu): When update to junit 4.13 use assertThrows instead of this.
executeRunnableAndExpectError(Runnable runnable, Throwable error)45   private void executeRunnableAndExpectError(Runnable runnable, Throwable error) {
46     boolean called = false;
47     try {
48       CurrentSpanUtils.withSpan(span, true, runnable).run();
49     } catch (Throwable e) {
50       assertThat(e).isEqualTo(error);
51       called = true;
52     }
53     assertThat(called).isTrue();
54   }
55 
56   // TODO(bdrutu): When update to junit 4.13 use assertThrows instead of this.
executeCallableAndExpectError(Callable<Object> callable, Throwable error)57   private void executeCallableAndExpectError(Callable<Object> callable, Throwable error) {
58     boolean called = false;
59     try {
60       CurrentSpanUtils.withSpan(span, true, callable).call();
61     } catch (Throwable e) {
62       assertThat(e).isEqualTo(error);
63       called = true;
64     }
65     assertThat(called).isTrue();
66   }
67 
68   @Test
getCurrentSpan_WhenNoContext()69   public void getCurrentSpan_WhenNoContext() {
70     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
71   }
72 
73   @Test
getCurrentSpan()74   public void getCurrentSpan() {
75     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
76     ContextHandle origContext =
77         ContextHandleUtils.withValue(ContextHandleUtils.currentContext(), span).attach();
78     // Make sure context is detached even if test fails.
79     try {
80       assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
81     } finally {
82       ContextHandleUtils.currentContext().detach(origContext);
83     }
84     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
85   }
86 
87   @Test
withSpan_CloseDetaches()88   public void withSpan_CloseDetaches() {
89     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
90     Scope ws = CurrentSpanUtils.withSpan(span, false);
91     try {
92       assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
93     } finally {
94       ws.close();
95     }
96     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
97     verifyZeroInteractions(span);
98   }
99 
100   @Test
withSpan_CloseDetachesAndEndsSpan()101   public void withSpan_CloseDetachesAndEndsSpan() {
102     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
103     Scope ss = CurrentSpanUtils.withSpan(span, true);
104     try {
105       assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
106     } finally {
107       ss.close();
108     }
109     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
110     verify(span).end(same(EndSpanOptions.DEFAULT));
111   }
112 
113   @Test
withSpanRunnable()114   public void withSpanRunnable() {
115     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
116     Runnable runnable =
117         new Runnable() {
118           @Override
119           public void run() {
120             // When we run the runnable we will have the span in the current Context.
121             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
122           }
123         };
124     CurrentSpanUtils.withSpan(span, false, runnable).run();
125     verifyZeroInteractions(span);
126     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
127   }
128 
129   @Test
withSpanRunnable_EndSpan()130   public void withSpanRunnable_EndSpan() {
131     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
132     Runnable runnable =
133         new Runnable() {
134           @Override
135           public void run() {
136             // When we run the runnable we will have the span in the current Context.
137             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
138           }
139         };
140     CurrentSpanUtils.withSpan(span, true, runnable).run();
141     verify(span).end(EndSpanOptions.DEFAULT);
142     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
143   }
144 
145   @Test
withSpanRunnable_WithError()146   public void withSpanRunnable_WithError() {
147     final AssertionError error = new AssertionError("MyError");
148     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
149     Runnable runnable =
150         new Runnable() {
151           @Override
152           public void run() {
153             // When we run the runnable we will have the span in the current Context.
154             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
155             throw error;
156           }
157         };
158     executeRunnableAndExpectError(runnable, error);
159     verify(span).setStatus(Status.UNKNOWN.withDescription("MyError"));
160     verify(span).end(EndSpanOptions.DEFAULT);
161     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
162   }
163 
164   @Test
withSpanRunnable_WithErrorNoMessage()165   public void withSpanRunnable_WithErrorNoMessage() {
166     final AssertionError error = new AssertionError();
167     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
168     Runnable runnable =
169         new Runnable() {
170           @Override
171           public void run() {
172             // When we run the runnable we will have the span in the current Context.
173             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
174             throw error;
175           }
176         };
177     executeRunnableAndExpectError(runnable, error);
178     verify(span).setStatus(Status.UNKNOWN.withDescription("AssertionError"));
179     verify(span).end(EndSpanOptions.DEFAULT);
180     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
181   }
182 
183   @Test
withSpanCallable()184   public void withSpanCallable() throws Exception {
185     final Object ret = new Object();
186     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
187     Callable<Object> callable =
188         new Callable<Object>() {
189           @Override
190           public Object call() throws Exception {
191             // When we run the runnable we will have the span in the current Context.
192             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
193             return ret;
194           }
195         };
196     assertThat(CurrentSpanUtils.withSpan(span, false, callable).call()).isEqualTo(ret);
197     verifyZeroInteractions(span);
198     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
199   }
200 
201   @Test
withSpanCallable_EndSpan()202   public void withSpanCallable_EndSpan() throws Exception {
203     final Object ret = new Object();
204     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
205     Callable<Object> callable =
206         new Callable<Object>() {
207           @Override
208           public Object call() throws Exception {
209             // When we run the runnable we will have the span in the current Context.
210             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
211             return ret;
212           }
213         };
214     assertThat(CurrentSpanUtils.withSpan(span, true, callable).call()).isEqualTo(ret);
215     verify(span).end(EndSpanOptions.DEFAULT);
216     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
217   }
218 
219   @Test
withSpanCallable_WithException()220   public void withSpanCallable_WithException() {
221     final Exception exception = new Exception("MyException");
222     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
223     Callable<Object> callable =
224         new Callable<Object>() {
225           @Override
226           public Object call() throws Exception {
227             // When we run the runnable we will have the span in the current Context.
228             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
229             throw exception;
230           }
231         };
232     executeCallableAndExpectError(callable, exception);
233     verify(span).setStatus(Status.UNKNOWN.withDescription("MyException"));
234     verify(span).end(EndSpanOptions.DEFAULT);
235     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
236   }
237 
238   @Test
withSpanCallable_WithExceptionNoMessage()239   public void withSpanCallable_WithExceptionNoMessage() {
240     final Exception exception = new Exception();
241     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
242     Callable<Object> callable =
243         new Callable<Object>() {
244           @Override
245           public Object call() throws Exception {
246             // When we run the runnable we will have the span in the current Context.
247             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
248             throw exception;
249           }
250         };
251     executeCallableAndExpectError(callable, exception);
252     verify(span).setStatus(Status.UNKNOWN.withDescription("Exception"));
253     verify(span).end(EndSpanOptions.DEFAULT);
254     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
255   }
256 
257   @Test
withSpanCallable_WithError()258   public void withSpanCallable_WithError() {
259     final AssertionError error = new AssertionError("MyError");
260     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
261     Callable<Object> callable =
262         new Callable<Object>() {
263           @Override
264           public Object call() throws Exception {
265             // When we run the runnable we will have the span in the current Context.
266             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
267             throw error;
268           }
269         };
270     executeCallableAndExpectError(callable, error);
271     verify(span).setStatus(Status.UNKNOWN.withDescription("MyError"));
272     verify(span).end(EndSpanOptions.DEFAULT);
273     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
274   }
275 
276   @Test
withSpanCallable_WithErrorNoMessage()277   public void withSpanCallable_WithErrorNoMessage() {
278     final AssertionError error = new AssertionError();
279     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
280     Callable<Object> callable =
281         new Callable<Object>() {
282           @Override
283           public Object call() throws Exception {
284             // When we run the runnable we will have the span in the current Context.
285             assertThat(CurrentSpanUtils.getCurrentSpan()).isSameInstanceAs(span);
286             throw error;
287           }
288         };
289     executeCallableAndExpectError(callable, error);
290     verify(span).setStatus(Status.UNKNOWN.withDescription("AssertionError"));
291     verify(span).end(EndSpanOptions.DEFAULT);
292     assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
293   }
294 }
295