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