• 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.Matchers.same;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.verifyZeroInteractions;
23 
24 import io.grpc.Context;
25 import io.opencensus.common.Scope;
26 import io.opencensus.trace.unsafe.ContextUtils;
27 import java.util.concurrent.Callable;
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.junit.runners.JUnit4;
32 import org.mockito.Mock;
33 import org.mockito.MockitoAnnotations;
34 
35 /** Unit tests for {@link CurrentSpanUtils}. */
36 @RunWith(JUnit4.class)
37 public class CurrentSpanUtilsTest {
38   @Mock private Span span;
39 
40   @Before
setUp()41   public void setUp() {
42     MockitoAnnotations.initMocks(this);
43   }
44 
45   // TODO(bdrutu): When update to junit 4.13 use assertThrows instead of this.
executeRunnableAndExpectError(Runnable runnable, Throwable error)46   private void executeRunnableAndExpectError(Runnable runnable, Throwable error) {
47     boolean called = false;
48     try {
49       CurrentSpanUtils.withSpan(span, true, runnable).run();
50     } catch (Throwable e) {
51       assertThat(e).isEqualTo(error);
52       called = true;
53     }
54     assertThat(called).isTrue();
55   }
56 
57   // TODO(bdrutu): When update to junit 4.13 use assertThrows instead of this.
executeCallableAndExpectError(Callable<Object> callable, Throwable error)58   private void executeCallableAndExpectError(Callable<Object> callable, Throwable error) {
59     boolean called = false;
60     try {
61       CurrentSpanUtils.withSpan(span, true, callable).call();
62     } catch (Throwable e) {
63       assertThat(e).isEqualTo(error);
64       called = true;
65     }
66     assertThat(called).isTrue();
67   }
68 
69   @Test
getCurrentSpan_WhenNoContext()70   public void getCurrentSpan_WhenNoContext() {
71     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
72   }
73 
74   @Test
getCurrentSpan()75   public void getCurrentSpan() {
76     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
77     Context origContext = Context.current().withValue(ContextUtils.CONTEXT_SPAN_KEY, span).attach();
78     // Make sure context is detached even if test fails.
79     try {
80       assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span);
81     } finally {
82       Context.current().detach(origContext);
83     }
84     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
85   }
86 
87   @Test
withSpan_CloseDetaches()88   public void withSpan_CloseDetaches() {
89     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
90     Scope ws = CurrentSpanUtils.withSpan(span, false);
91     try {
92       assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span);
93     } finally {
94       ws.close();
95     }
96     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
97     verifyZeroInteractions(span);
98   }
99 
100   @Test
withSpan_CloseDetachesAndEndsSpan()101   public void withSpan_CloseDetachesAndEndsSpan() {
102     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
103     Scope ss = CurrentSpanUtils.withSpan(span, true);
104     try {
105       assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span);
106     } finally {
107       ss.close();
108     }
109     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
110     verify(span).end(same(EndSpanOptions.DEFAULT));
111   }
112 
113   @Test
withSpanRunnable()114   public void withSpanRunnable() {
115     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(span);
122           }
123         };
124     CurrentSpanUtils.withSpan(span, false, runnable).run();
125     verifyZeroInteractions(span);
126     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
127   }
128 
129   @Test
withSpanRunnable_EndSpan()130   public void withSpanRunnable_EndSpan() {
131     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(span);
138           }
139         };
140     CurrentSpanUtils.withSpan(span, true, runnable).run();
141     verify(span).end(EndSpanOptions.DEFAULT);
142     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
143   }
144 
145   @Test
withSpanRunnable_WithError()146   public void withSpanRunnable_WithError() {
147     final AssertionError error = new AssertionError("MyError");
148     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(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()).isNull();
162   }
163 
164   @Test
withSpanRunnable_WithErrorNoMessage()165   public void withSpanRunnable_WithErrorNoMessage() {
166     final AssertionError error = new AssertionError();
167     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(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()).isNull();
181   }
182 
183   @Test
withSpanCallable()184   public void withSpanCallable() throws Exception {
185     final Object ret = new Object();
186     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(span);
193             return ret;
194           }
195         };
196     assertThat(CurrentSpanUtils.withSpan(span, false, callable).call()).isEqualTo(ret);
197     verifyZeroInteractions(span);
198     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
199   }
200 
201   @Test
withSpanCallable_EndSpan()202   public void withSpanCallable_EndSpan() throws Exception {
203     final Object ret = new Object();
204     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(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()).isNull();
217   }
218 
219   @Test
withSpanCallable_WithException()220   public void withSpanCallable_WithException() {
221     final Exception exception = new Exception("MyException");
222     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(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()).isNull();
236   }
237 
238   @Test
withSpanCallable_WithExceptionNoMessage()239   public void withSpanCallable_WithExceptionNoMessage() {
240     final Exception exception = new Exception();
241     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(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()).isNull();
255   }
256 
257   @Test
withSpanCallable_WithError()258   public void withSpanCallable_WithError() {
259     final AssertionError error = new AssertionError("MyError");
260     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(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()).isNull();
274   }
275 
276   @Test
withSpanCallable_WithErrorNoMessage()277   public void withSpanCallable_WithErrorNoMessage() {
278     final AssertionError error = new AssertionError();
279     assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
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()).isSameAs(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()).isNull();
293   }
294 }
295