aboutsummaryrefslogtreecommitdiff
path: root/impl_core/src/test/java/io/opencensus/implcore/trace/SpanBuilderImplTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'impl_core/src/test/java/io/opencensus/implcore/trace/SpanBuilderImplTest.java')
-rw-r--r--impl_core/src/test/java/io/opencensus/implcore/trace/SpanBuilderImplTest.java404
1 files changed, 404 insertions, 0 deletions
diff --git a/impl_core/src/test/java/io/opencensus/implcore/trace/SpanBuilderImplTest.java b/impl_core/src/test/java/io/opencensus/implcore/trace/SpanBuilderImplTest.java
new file mode 100644
index 00000000..3267eac5
--- /dev/null
+++ b/impl_core/src/test/java/io/opencensus/implcore/trace/SpanBuilderImplTest.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2017, OpenCensus Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.opencensus.implcore.trace;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import io.opencensus.implcore.trace.RecordEventsSpanImpl.StartEndHandler;
+import io.opencensus.implcore.trace.internal.RandomHandler;
+import io.opencensus.testing.common.TestClock;
+import io.opencensus.trace.Span;
+import io.opencensus.trace.Span.Kind;
+import io.opencensus.trace.Span.Options;
+import io.opencensus.trace.SpanContext;
+import io.opencensus.trace.SpanId;
+import io.opencensus.trace.TraceId;
+import io.opencensus.trace.TraceOptions;
+import io.opencensus.trace.config.TraceConfig;
+import io.opencensus.trace.config.TraceParams;
+import io.opencensus.trace.export.SpanData;
+import io.opencensus.trace.samplers.Samplers;
+import java.util.Collections;
+import java.util.Random;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Unit tests for {@link SpanBuilderImpl}. */
+@RunWith(JUnit4.class)
+public class SpanBuilderImplTest {
+ private static final String SPAN_NAME = "MySpanName";
+ private SpanBuilderImpl.Options spanBuilderOptions;
+ private final TraceParams alwaysSampleTraceParams =
+ TraceParams.DEFAULT.toBuilder().setSampler(Samplers.alwaysSample()).build();
+ private final TestClock testClock = TestClock.create();
+ private final RandomHandler randomHandler = new FakeRandomHandler();
+ @Mock private StartEndHandler startEndHandler;
+ @Mock private TraceConfig traceConfig;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ spanBuilderOptions =
+ new SpanBuilderImpl.Options(randomHandler, startEndHandler, testClock, traceConfig);
+ when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams);
+ }
+
+ @Test
+ public void startSpan_CreatesTheCorrectSpanImplInstance() {
+ assertThat(
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.alwaysSample())
+ .startSpan())
+ .isInstanceOf(RecordEventsSpanImpl.class);
+ assertThat(
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setRecordEvents(true)
+ .setSampler(Samplers.neverSample())
+ .startSpan())
+ .isInstanceOf(RecordEventsSpanImpl.class);
+ assertThat(
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan())
+ .isInstanceOf(NoRecordEventsSpanImpl.class);
+ }
+
+ @Test
+ public void setSpanKind_NotNull() {
+ RecordEventsSpanImpl span =
+ (RecordEventsSpanImpl)
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSpanKind(Kind.CLIENT)
+ .setRecordEvents(true)
+ .startSpan();
+ assertThat(span.getKind()).isEqualTo(Kind.CLIENT);
+ assertThat(span.toSpanData().getKind()).isEqualTo(Kind.CLIENT);
+ }
+
+ @Test
+ public void setSpanKind_DefaultNull() {
+ RecordEventsSpanImpl span =
+ (RecordEventsSpanImpl)
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setRecordEvents(true)
+ .startSpan();
+ assertThat(span.getKind()).isNull();
+ assertThat(span.toSpanData().getKind()).isNull();
+ }
+
+ @Test
+ public void startSpanNullParent() {
+ RecordEventsSpanImpl span =
+ (RecordEventsSpanImpl)
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setRecordEvents(true)
+ .startSpan();
+ assertThat(span.getContext().isValid()).isTrue();
+ assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue();
+ assertThat(span.getContext().getTraceOptions().isSampled()).isTrue();
+ SpanData spanData = span.toSpanData();
+ assertThat(spanData.getParentSpanId()).isNull();
+ assertThat(spanData.getHasRemoteParent()).isNull();
+ assertThat(spanData.getStartTimestamp()).isEqualTo(testClock.now());
+ assertThat(spanData.getName()).isEqualTo(SPAN_NAME);
+ }
+
+ @Test
+ public void startSpanNullParentWithRecordEvents() {
+ RecordEventsSpanImpl span =
+ (RecordEventsSpanImpl)
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .setRecordEvents(true)
+ .startSpan();
+ assertThat(span.getContext().isValid()).isTrue();
+ assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue();
+ assertThat(span.getContext().getTraceOptions().isSampled()).isFalse();
+ SpanData spanData = span.toSpanData();
+ assertThat(spanData.getParentSpanId()).isNull();
+ assertThat(spanData.getHasRemoteParent()).isNull();
+ }
+
+ @Test
+ public void startSpanNullParentNoRecordOptions() {
+ Span span =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan();
+ assertThat(span.getContext().isValid()).isTrue();
+ assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isFalse();
+ assertThat(span.getContext().getTraceOptions().isSampled()).isFalse();
+ }
+
+ @Test
+ public void startChildSpan() {
+ Span rootSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions).startSpan();
+ assertThat(rootSpan.getContext().isValid()).isTrue();
+ assertThat(rootSpan.getOptions().contains(Options.RECORD_EVENTS)).isTrue();
+ assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue();
+ assertThat(((RecordEventsSpanImpl) rootSpan).toSpanData().getHasRemoteParent()).isNull();
+ Span childSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, rootSpan, spanBuilderOptions).startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId());
+ assertThat(((RecordEventsSpanImpl) childSpan).toSpanData().getParentSpanId())
+ .isEqualTo(rootSpan.getContext().getSpanId());
+ assertThat(((RecordEventsSpanImpl) childSpan).toSpanData().getHasRemoteParent()).isFalse();
+ assertThat(((RecordEventsSpanImpl) childSpan).getTimestampConverter())
+ .isEqualTo(((RecordEventsSpanImpl) rootSpan).getTimestampConverter());
+ }
+
+ @Test
+ public void startRemoteSpan_NullParent() {
+ RecordEventsSpanImpl span =
+ (RecordEventsSpanImpl)
+ SpanBuilderImpl.createWithRemoteParent(SPAN_NAME, null, spanBuilderOptions)
+ .setRecordEvents(true)
+ .startSpan();
+ assertThat(span.getContext().isValid()).isTrue();
+ assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue();
+ assertThat(span.getContext().getTraceOptions().isSampled()).isTrue();
+ SpanData spanData = span.toSpanData();
+ assertThat(spanData.getParentSpanId()).isNull();
+ assertThat(spanData.getHasRemoteParent()).isNull();
+ }
+
+ @Test
+ public void startRemoteSpanInvalidParent() {
+ RecordEventsSpanImpl span =
+ (RecordEventsSpanImpl)
+ SpanBuilderImpl.createWithRemoteParent(
+ SPAN_NAME, SpanContext.INVALID, spanBuilderOptions)
+ .startSpan();
+ assertThat(span.getContext().isValid()).isTrue();
+ assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue();
+ assertThat(span.getContext().getTraceOptions().isSampled()).isTrue();
+ SpanData spanData = span.toSpanData();
+ assertThat(spanData.getParentSpanId()).isNull();
+ assertThat(spanData.getHasRemoteParent()).isNull();
+ }
+
+ @Test
+ public void startRemoteSpan() {
+ SpanContext spanContext =
+ SpanContext.create(
+ TraceId.generateRandomId(randomHandler.current()),
+ SpanId.generateRandomId(randomHandler.current()),
+ TraceOptions.DEFAULT);
+ RecordEventsSpanImpl span =
+ (RecordEventsSpanImpl)
+ SpanBuilderImpl.createWithRemoteParent(SPAN_NAME, spanContext, spanBuilderOptions)
+ .setRecordEvents(true)
+ .startSpan();
+ assertThat(span.getContext().isValid()).isTrue();
+ assertThat(span.getContext().getTraceId()).isEqualTo(spanContext.getTraceId());
+ assertThat(span.getContext().getTraceOptions().isSampled()).isTrue();
+ SpanData spanData = span.toSpanData();
+ assertThat(spanData.getParentSpanId()).isEqualTo(spanContext.getSpanId());
+ assertThat(spanData.getHasRemoteParent()).isTrue();
+ }
+
+ @Test
+ public void startRootSpan_WithSpecifiedSampler() {
+ // Apply given sampler before default sampler for root spans.
+ Span rootSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan();
+ assertThat(rootSpan.getContext().isValid()).isTrue();
+ assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isFalse();
+ }
+
+ @Test
+ public void startRootSpan_WithoutSpecifiedSampler() {
+ // Apply default sampler (always true in the tests) for root spans.
+ Span rootSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions).startSpan();
+ assertThat(rootSpan.getContext().isValid()).isTrue();
+ assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue();
+ }
+
+ @Test
+ public void startRemoteChildSpan_WithSpecifiedSampler() {
+ Span rootSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.alwaysSample())
+ .startSpan();
+ assertThat(rootSpan.getContext().isValid()).isTrue();
+ assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue();
+ // Apply given sampler before default sampler for spans with remote parent.
+ Span childSpan =
+ SpanBuilderImpl.createWithRemoteParent(SPAN_NAME, rootSpan.getContext(), spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId());
+ assertThat(childSpan.getContext().getTraceOptions().isSampled()).isFalse();
+ }
+
+ @Test
+ public void startRemoteChildSpan_WithoutSpecifiedSampler() {
+ Span rootSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan();
+ assertThat(rootSpan.getContext().isValid()).isTrue();
+ assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isFalse();
+ // Apply default sampler (always true in the tests) for spans with remote parent.
+ Span childSpan =
+ SpanBuilderImpl.createWithRemoteParent(SPAN_NAME, rootSpan.getContext(), spanBuilderOptions)
+ .startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId());
+ assertThat(childSpan.getContext().getTraceOptions().isSampled()).isTrue();
+ }
+
+ @Test
+ public void startChildSpan_WithSpecifiedSampler() {
+ Span rootSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.alwaysSample())
+ .startSpan();
+ assertThat(rootSpan.getContext().isValid()).isTrue();
+ assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue();
+ // Apply the given sampler for child spans.
+ Span childSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, rootSpan, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId());
+ assertThat(childSpan.getContext().getTraceOptions().isSampled()).isFalse();
+ }
+
+ @Test
+ public void startChildSpan_WithoutSpecifiedSampler() {
+ Span rootSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan();
+ assertThat(rootSpan.getContext().isValid()).isTrue();
+ assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isFalse();
+ // Don't apply the default sampler (always true) for child spans.
+ Span childSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, rootSpan, spanBuilderOptions).startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId());
+ assertThat(childSpan.getContext().getTraceOptions().isSampled()).isFalse();
+ }
+
+ @Test
+ public void startChildSpan_SampledLinkedParent() {
+ Span rootSpanUnsampled =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.neverSample())
+ .startSpan();
+ assertThat(rootSpanUnsampled.getContext().getTraceOptions().isSampled()).isFalse();
+ Span rootSpanSampled =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions)
+ .setSampler(Samplers.alwaysSample())
+ .startSpan();
+ assertThat(rootSpanSampled.getContext().getTraceOptions().isSampled()).isTrue();
+ // Sampled because the linked parent is sampled.
+ Span childSpan =
+ SpanBuilderImpl.createWithParent(SPAN_NAME, rootSpanUnsampled, spanBuilderOptions)
+ .setParentLinks(Collections.singletonList(rootSpanSampled))
+ .startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId())
+ .isEqualTo(rootSpanUnsampled.getContext().getTraceId());
+ assertThat(childSpan.getContext().getTraceOptions().isSampled()).isTrue();
+ }
+
+ @Test
+ public void startRemoteChildSpan_WithProbabilitySamplerDefaultSampler() {
+ when(traceConfig.getActiveTraceParams()).thenReturn(TraceParams.DEFAULT);
+ // This traceId will not be sampled by the ProbabilitySampler because the first 8 bytes as long
+ // is not less than probability * Long.MAX_VALUE;
+ TraceId traceId =
+ TraceId.fromBytes(
+ new byte[] {
+ (byte) 0x8F,
+ (byte) 0xFF,
+ (byte) 0xFF,
+ (byte) 0xFF,
+ (byte) 0xFF,
+ (byte) 0xFF,
+ (byte) 0xFF,
+ (byte) 0xFF,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ });
+
+ // If parent is sampled then the remote child must be sampled.
+ Span childSpan =
+ SpanBuilderImpl.createWithRemoteParent(
+ SPAN_NAME,
+ SpanContext.create(
+ traceId,
+ SpanId.generateRandomId(randomHandler.current()),
+ TraceOptions.builder().setIsSampled(true).build()),
+ spanBuilderOptions)
+ .startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId()).isEqualTo(traceId);
+ assertThat(childSpan.getContext().getTraceOptions().isSampled()).isTrue();
+ childSpan.end();
+
+ assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT);
+
+ // If parent is not sampled then the remote child must be not sampled.
+ childSpan =
+ SpanBuilderImpl.createWithRemoteParent(
+ SPAN_NAME,
+ SpanContext.create(
+ traceId,
+ SpanId.generateRandomId(randomHandler.current()),
+ TraceOptions.DEFAULT),
+ spanBuilderOptions)
+ .startSpan();
+ assertThat(childSpan.getContext().isValid()).isTrue();
+ assertThat(childSpan.getContext().getTraceId()).isEqualTo(traceId);
+ assertThat(childSpan.getContext().getTraceOptions().isSampled()).isFalse();
+ childSpan.end();
+ }
+
+ private static final class FakeRandomHandler extends RandomHandler {
+ private final Random random;
+
+ FakeRandomHandler() {
+ this.random = new Random(1234);
+ }
+
+ @Override
+ public Random current() {
+ return random;
+ }
+ }
+}