diff options
| author | Bogdan Drutu <bdrutu@google.com> | 2017-06-30 11:12:56 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-06-30 11:12:56 -0700 |
| commit | 07d69996286f6800be2d3977571cac0a80bb4e7c (patch) | |
| tree | 0411a46146d208b253c5bb633203905b6f84dda1 | |
| parent | 1989720ea57fc40a4a2aaedcfb09fe988e9b186d (diff) | |
| download | platform_external_opencensus-java-07d69996286f6800be2d3977571cac0a80bb4e7c.tar.gz platform_external_opencensus-java-07d69996286f6800be2d3977571cac0a80bb4e7c.tar.bz2 platform_external_opencensus-java-07d69996286f6800be2d3977571cac0a80bb4e7c.zip | |
Change API to remove the "Option" logic and keep only Builder. (#380)
21 files changed, 421 insertions, 877 deletions
diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index 782248ba..f573d9a6 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -13,11 +13,11 @@ package io.opencensus.trace; +import static com.google.common.base.Preconditions.checkNotNull; + import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Sampler; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.internal.SpanFactory; import java.util.List; import javax.annotation.Nullable; @@ -102,34 +102,15 @@ import javax.annotation.Nullable; * <p>If your Java version is less than Java SE 7, see {@link SpanBuilder#startSpan} and {@link * SpanBuilder#startScopedSpan} for usage examples. */ -public final class SpanBuilder { - private final SpanFactory spanFactory; - private final String name; - private final StartSpanOptions.Builder startSpanOptionsBuilder = StartSpanOptions.builder(); - private Span parentSpan; - private SpanContext parentSpanContext; - private boolean remoteParent; - - static SpanBuilder builder(SpanFactory spanFactory, Span parentSpan, String name) { - return new SpanBuilder(spanFactory, parentSpan, null, false, name); - } - - static SpanBuilder builderWithRemoteParent( - SpanFactory spanFactory, SpanContext parentSpanContext, String name) { - return new SpanBuilder(spanFactory, null, parentSpanContext, true, name); - } +public abstract class SpanBuilder { /** - * Sets the {@link Sampler} to use. If a {@code null} value is passed, the implementation will - * provide a default. + * Sets the {@link Sampler} to use. If not set, the implementation will provide a default. * * @param sampler The {@code Sampler} to use when determining sampling for a {@code Span}. * @return this. */ - public SpanBuilder setSampler(@Nullable Sampler sampler) { - startSpanOptionsBuilder.setSampler(sampler); - return this; - } + public abstract SpanBuilder setSampler(Sampler sampler); /** * Sets the {@code List} of parent links. Links are used to link {@link Span}s in different @@ -138,11 +119,9 @@ public final class SpanBuilder { * * @param parentLinks New links to be added. * @return this. + * @throws NullPointerException if {@code parentLinks} is {@code null}. */ - public SpanBuilder setParentLinks(@Nullable List<Span> parentLinks) { - startSpanOptionsBuilder.setParentLinks(parentLinks); - return this; - } + public abstract SpanBuilder setParentLinks(List<Span> parentLinks); /** * Sets the option {@link Span.Options#RECORD_EVENTS} for the newly created {@code Span}. If not @@ -151,27 +130,7 @@ public final class SpanBuilder { * @param recordEvents New value determining if this {@code Span} should have events recorded. * @return this. */ - public SpanBuilder setRecordEvents(boolean recordEvents) { - startSpanOptionsBuilder.setRecordEvents(recordEvents); - return this; - } - - /** - * If called this will force the newly created {@code Span} to be a root span. As a consequence, - * any parent specified (or inherited from the Context) will be ignored (N.B. does not apply to - * linked parents set through {@link #setParentLinks}). - * - * <p>This is useful when {@link Tracer#spanBuilder(String)} is used and the newly created {@code - * Span} needs to be decoupled from the parent {@code Span}. - * - * @return this. - */ - public SpanBuilder becomeRoot() { - parentSpan = null; - parentSpanContext = null; - remoteParent = false; - return this; - } + public abstract SpanBuilder setRecordEvents(boolean recordEvents); /** * Starts a new {@link Span}. @@ -201,9 +160,7 @@ public final class SpanBuilder { * * @return the newly created {@code Span}. */ - public Span startSpan() { - return start(); - } + public abstract Span startSpan(); // TODO(bdrutu): Add error_prone annotation @MustBeClosed when the 2.0.16 jar is fixed. /** @@ -260,28 +217,38 @@ public final class SpanBuilder { * @return an object that defines a scope where the newly created {@code Span} will be set to the * current Context. */ - public NonThrowingCloseable startScopedSpan() { - return new ScopedSpanHandle(start()); + public final NonThrowingCloseable startScopedSpan() { + return new ScopedSpanHandle(startSpan()); } - private SpanBuilder( - SpanFactory spanFactory, - @Nullable Span parentSpan, - @Nullable SpanContext parentSpanContext, - boolean remoteParent, - String name) { - this.parentSpan = parentSpan; - this.parentSpanContext = parentSpanContext; - this.remoteParent = remoteParent; - this.name = name; - this.spanFactory = spanFactory; - } + static final class NoopSpanBuilder extends SpanBuilder { + NoopSpanBuilder(@Nullable Span parentSpan, String name) { + checkNotNull(name, "name"); + } + + NoopSpanBuilder(SpanContext remoteParentSpanContext, String name) { + checkNotNull(remoteParentSpanContext, "remoteParentSpanContext"); + checkNotNull(name, "name"); + } + + @Override + public Span startSpan() { + return BlankSpan.INSTANCE; + } + + @Override + public SpanBuilder setSampler(@Nullable Sampler sampler) { + return this; + } + + @Override + public SpanBuilder setParentLinks(List<Span> parentLinks) { + return this; + } - // Utility method to start a Span. - private Span start() { - return remoteParent - ? spanFactory.startSpanWithRemoteParent( - parentSpanContext, name, startSpanOptionsBuilder.build()) - : spanFactory.startSpan(parentSpan, name, startSpanOptionsBuilder.build()); + @Override + public SpanBuilder setRecordEvents(boolean recordEvents) { + return this; + } } } diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java index e6172bed..ef5616a9 100644 --- a/api/src/main/java/io/opencensus/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -16,8 +16,6 @@ package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.internal.SpanFactory; import javax.annotation.Nullable; /** @@ -67,7 +65,6 @@ import javax.annotation.Nullable; */ public abstract class Tracer { private static final NoopTracer noopTracer = new NoopTracer(); - private final SpanFactory spanFactory; /** * Returns the no-op implementation of the {@code Tracer}. @@ -142,7 +139,7 @@ public abstract class Tracer { * @param span The {@link Span} to be set to the current Context. * @return an object that defines a scope where the given {@link Span} will be set to the current * Context. - * @throws NullPointerException if span is null. + * @throws NullPointerException if {@code span} is null. */ public final NonThrowingCloseable withSpan(Span span) { return ContextUtils.withSpan(checkNotNull(span, "span")); @@ -150,7 +147,7 @@ public abstract class Tracer { /** * Returns a {@link SpanBuilder} to create and start a new child {@link Span} as a child of to the - * current {@code Span} if any, otherwise create a root Span with the default options. + * current {@code Span} if any, otherwise creates a root {@code Span}. * * <p>See {@link SpanBuilder} for usage examples. * @@ -159,7 +156,7 @@ public abstract class Tracer { * * @param name The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if name is null. + * @throws NullPointerException if {@code name} is null. */ public final SpanBuilder spanBuilder(String name) { return spanBuilder(ContextUtils.getCurrentSpan(), name); @@ -167,64 +164,60 @@ public abstract class Tracer { /** * Returns a {@link SpanBuilder} to create and start a new child {@link Span} (or root if parent - * is null), with parent being the designated {@code Span}. + * is {@code null} or has an invalid {@link SpanContext}), with parent being the designated {@code + * Span}. * * <p>See {@link SpanBuilder} for usage examples. * - * <p>This <b>must</b> be used to create a {@code Span} when manual Context propagation is used. + * <p>This <b>must</b> be used to create a {@code Span} when manual Context propagation is used + * OR when creating a root {@code Span} with a {@code null} parent. * * @param parent The parent of the returned Span. If null the {@code SpanBuilder} will build a * root {@code Span}. * @param name The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if name is null. + * @throws NullPointerException if {@code name} is null. */ - public final SpanBuilder spanBuilder(@Nullable Span parent, String name) { - return SpanBuilder.builder(spanFactory, parent, checkNotNull(name, "name")); - } + public abstract SpanBuilder spanBuilder(@Nullable Span parent, String name); /** * Returns a {@link SpanBuilder} to create and start a new child {@link Span} (or root if parent - * is null), with parent being the {@link Span} designated by the {@link SpanContext}. + * is an invalid {@link SpanContext}), with parent being the {@link Span} designated by the {@link + * SpanContext}. * * <p>See {@link SpanBuilder} for usage examples. * * <p>This <b>must</b> be used to create a {@code Span} when the parent is in a different process. * This is only intended for use by RPC systems or similar. * - * @param remoteParent The remote parent of the returned Span. + * <p>If no {@link SpanContext} OR fail to parse the {@link SpanContext} on the server side, + * users must call this method with an {@link SpanContext#INVALID} remote parent {@code + * SpanContext}. + * + * @param remoteParentSpanContext The remote parent of the returned Span. * @param name The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if name is null. + * @throws NullPointerException if {@code name} or {@code remoteParentSpanContext} are null. */ - public final SpanBuilder spanBuilderWithRemoteParent( - @Nullable SpanContext remoteParent, String name) { - return SpanBuilder.builderWithRemoteParent( - spanFactory, remoteParent, checkNotNull(name, "name")); - } + public abstract SpanBuilder spanBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name); // No-Op implementation of the Tracer. private static final class NoopTracer extends Tracer { - private NoopTracer() { - super(new NoopSpanFactory()); - } - // No-op implementation of the SpanFactory - private static final class NoopSpanFactory extends SpanFactory { - @Override - public Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { - return BlankSpan.INSTANCE; - } + @Override + public SpanBuilder spanBuilder(@Nullable Span parent, String name) { + return new SpanBuilder.NoopSpanBuilder(parent, name); + } - @Override - public Span startSpanWithRemoteParent( - @Nullable SpanContext remoteParent, String name, StartSpanOptions options) { - return BlankSpan.INSTANCE; - } + @Override + public SpanBuilder spanBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name) { + return new SpanBuilder.NoopSpanBuilder(remoteParentSpanContext, name); } - } - protected Tracer(SpanFactory spanFactory) { - this.spanFactory = checkNotNull(spanFactory, "spanFactory"); + private NoopTracer() {} } + + protected Tracer() {} } diff --git a/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java b/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java deleted file mode 100644 index 518f1e60..00000000 --- a/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * 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.trace.base; - -import com.google.auto.value.AutoValue; -import com.google.common.annotations.VisibleForTesting; -import io.opencensus.trace.Span; -import io.opencensus.trace.config.TraceConfig; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * A class that enables overriding the default values used when starting a {@link Span}. Allows - * overriding the {@link Sampler sampler}, the parent links, and option to record all the events - * even if the {@code Span} is not sampled. - */ -@AutoValue -@Immutable -public abstract class StartSpanOptions { - private static final List<Span> EMPTY_PARENT_LINKS_LIST = Collections.emptyList(); - - /** The default {@code StartSpanOptions}. */ - @VisibleForTesting public static final StartSpanOptions DEFAULT = builder().build(); - - /** - * Returns the {@link Sampler} to be used, or {@code null} if default. - * - * @return the {@code Sampler} to be used, or {@code null} if default. - */ - @Nullable - public abstract Sampler getSampler(); - - /** - * Returns the parent links to be set for the {@link Span}. - * - * @return the parent links to be set for the {@code Span}. - */ - public abstract List<Span> getParentLinks(); - - /** - * Returns the record events option, or {@code null} if default. - * - * <p>See {@link Span.Options#RECORD_EVENTS} for more details. - * - * @return the record events option, or {@code null} if default. - */ - @Nullable - public abstract Boolean getRecordEvents(); - - /** - * Returns a new {@link Builder} with default options. - * - * @return a new {@code Builder} with default options. - */ - public static Builder builder() { - return new AutoValue_StartSpanOptions.Builder().setParentLinks(EMPTY_PARENT_LINKS_LIST); - } - - /** Builder class for {@link StartSpanOptions}. */ - @AutoValue.Builder - public abstract static class Builder { - - /** - * Sets the {@link Sampler} to be used. If {@code null} the default {@code Sampler} from the - * {@link TraceConfig#getActiveTraceParams()} will be used. - * - * @param sampler the {@link Sampler} to be used. - * @return this. - */ - public abstract Builder setSampler(@Nullable Sampler sampler); - - /** - * Sets the parent links to be set for the {@link Span}. - * - * @param parentLinks the parent links to be set for the {@link Span}. - * @return this. - * @throws NullPointerException if {@code parentLinks} is {@code null}. - */ - public abstract Builder setParentLinks(List<Span> parentLinks); - - /** - * Sets the record events option. If {@code null} the default value from the {@link - * TraceConfig#getActiveTraceParams()} will be used. - * - * <p>See {@link Span.Options#RECORD_EVENTS} for more details. - * - * @param recordEvents the record events option. - * @return this. - */ - public abstract Builder setRecordEvents(@Nullable Boolean recordEvents); - - abstract List<Span> getParentLinks(); // not public - - abstract StartSpanOptions autoBuild(); // not public - - /** - * Builds and returns a {@code StartSpanOptions} with the desired settings. - * - * @return a {@code StartSpanOptions} with the desired settings. - */ - public StartSpanOptions build() { - setParentLinks(Collections.unmodifiableList(new ArrayList<Span>(getParentLinks()))); - return autoBuild(); - } - } - - StartSpanOptions() {} -} diff --git a/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java b/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java deleted file mode 100644 index a0306152..00000000 --- a/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * 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.trace.internal; - -import io.opencensus.trace.Span; -import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.StartSpanOptions; -import javax.annotation.Nullable; - -/** Factory class to create and start a {@link Span}. */ -public abstract class SpanFactory { - /** - * Creates and starts a new child {@link Span} (or root if parent is {@code null}), with parent - * being the designated {@code Span} and the given options. - * - * @param parent The parent of the returned {@code Span}. - * @param name The name of the returned {@code Span}. - * @param options The options for the start of the {@code Span}. - * @return A child {@code Span} that will have the name provided. - */ - public abstract Span startSpan(@Nullable Span parent, String name, StartSpanOptions options); - - /** - * Creates and starts a new child {@link Span} (or root if parent is {@code null}), with parent - * being the {@code Span} designated by the {@link SpanContext} and the given options. - * - * <p>This must be used to create a {@code Span} when the parent is on a different process. - * - * @param remoteParent The remote parent of the returned {@code Span}. - * @param name The name of the returned {@code Span}. - * @param options The options for the start of the {@code Span}. - * @return A child {@code Span} that will have the name provided. - */ - public abstract Span startSpanWithRemoteParent( - @Nullable SpanContext remoteParent, String name, StartSpanOptions options); -} diff --git a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java deleted file mode 100644 index 10eccbe6..00000000 --- a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * 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.trace; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; -import static org.mockito.Matchers.same; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.EndSpanOptions; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; -import io.opencensus.trace.internal.SpanFactory; -import io.opencensus.trace.samplers.Samplers; -import java.util.Arrays; -import java.util.List; -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 Tracer}. */ -@RunWith(JUnit4.class) -public class SpanBuilderTest { - private static final String SPAN_NAME = "MySpanName"; - private static final Tracer tracer = Tracing.getTracer(); - private final Random random = new Random(1234); - private final SpanContext spanContext = - SpanContext.create( - TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); - @Mock private Span span; - @Mock private SpanFactory spanFactory; - private SpanBuilder spanBuilder; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - spanBuilder = SpanBuilder.builder(spanFactory, BlankSpan.INSTANCE, SPAN_NAME); - } - - @Test - public void startScopedSpanRoot() { - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - NonThrowingCloseable ss = spanBuilder.becomeRoot().startScopedSpan(); - try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); - } finally { - ss.close(); - } - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startScopedSpanRootWithOptions() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(startSpanOptions))) - .thenReturn(span); - NonThrowingCloseable ss = - spanBuilder.becomeRoot().setSampler(Samplers.neverSample()).startScopedSpan(); - try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); - } finally { - ss.close(); - } - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startRootSpan() { - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span rootSpan = spanBuilder.becomeRoot().startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpan_WithNullParent() { - spanBuilder = SpanBuilder.builder(spanFactory, null, SPAN_NAME); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span rootSpan = spanBuilder.startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startRootSpanWithOptions() { - List<Span> parentList = Arrays.<Span>asList(BlankSpan.INSTANCE); - StartSpanOptions startSpanOptions = - StartSpanOptions.builder() - .setSampler(Samplers.neverSample()) - .setParentLinks(parentList) - .build(); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(startSpanOptions))) - .thenReturn(span); - Span rootSpan = - spanBuilder - .becomeRoot() - .setSampler(Samplers.neverSample()) - .setParentLinks(parentList) - .startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startChildSpan() { - when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span childSpan = spanBuilder.startSpan(); - assertThat(childSpan).isEqualTo(span); - childSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startChildSpanWithOptions() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).setRecordEvents(true).build(); - ; - when(spanFactory.startSpan(same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(startSpanOptions))) - .thenReturn(span); - Span childSpan = - spanBuilder.setSampler(Samplers.neverSample()).setRecordEvents(true).startSpan(); - assertThat(childSpan).isEqualTo(span); - childSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpanWitRemoteParent() { - spanBuilder = SpanBuilder.builderWithRemoteParent(spanFactory, spanContext, SPAN_NAME); - when(spanFactory.startSpanWithRemoteParent( - same(spanContext), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span remoteChildSpan = spanBuilder.startSpan(); - assertThat(remoteChildSpan).isEqualTo(span); - remoteChildSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpanWitRemoteParent_WithNullParent() { - spanBuilder = SpanBuilder.builderWithRemoteParent(spanFactory, null, SPAN_NAME); - when(spanFactory.startSpanWithRemoteParent( - isNull(SpanContext.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span remoteChildSpan = spanBuilder.startSpan(); - assertThat(remoteChildSpan).isEqualTo(span); - remoteChildSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } -} diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index 7339eae2..3c69068b 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -14,21 +14,11 @@ package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; import static org.mockito.Matchers.same; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.grpc.Context; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.EndSpanOptions; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; -import io.opencensus.trace.internal.SpanFactory; -import java.util.Random; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -41,10 +31,11 @@ import org.mockito.MockitoAnnotations; /** Unit tests for {@link Tracer}. */ @RunWith(JUnit4.class) public class TracerTest { - private static final Tracer tracer = Tracing.getTracer(); + private static final Tracer noopTracer = Tracer.getNoopTracer(); private static final String SPAN_NAME = "MySpanName"; @Rule public ExpectedException thrown = ExpectedException.none(); - @Mock private SpanFactory spanFactory; + @Mock private Tracer tracer; + @Mock private SpanBuilder spanBuilder; @Mock private Span span; @Before @@ -54,163 +45,107 @@ public class TracerTest { @Test public void defaultGetCurrentSpan() { - assertThat(tracer.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void withSpan_NullSpan() { - tracer.withSpan(null); + noopTracer.withSpan(null); } @Test public void getCurrentSpan_WithSpan() { - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); - NonThrowingCloseable ws = tracer.withSpan(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + NonThrowingCloseable ws = noopTracer.withSpan(span); try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); } finally { ws.close(); } - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); } @Test public void propagationViaRunnable() { - Runnable runnable = null; - NonThrowingCloseable ws = tracer.withSpan(span); + Runnable runnable; + NonThrowingCloseable ws = noopTracer.withSpan(span); try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); runnable = Context.current() .wrap( new Runnable() { @Override public void run() { - assertThat(tracer.getCurrentSpan()).isSameAs(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); } }); } finally { ws.close(); } - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); // When we run the runnable we will have the span in the current Context. runnable.run(); - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void spanBuilderWithName_NullName() { - assertThat(tracer.spanBuilder(null).startSpan()).isSameAs(BlankSpan.INSTANCE); + noopTracer.spanBuilder(null); } @Test public void defaultSpanBuilderWithName() { - assertThat(tracer.spanBuilder(SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.spanBuilder(SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void spanBuilderWithParentAndName_NullName() { - assertThat(tracer.spanBuilder(null, null).startSpan()).isSameAs(BlankSpan.INSTANCE); + noopTracer.spanBuilder(null, null); } @Test public void defaultSpanBuilderWithParentAndName() { - assertThat(tracer.spanBuilder(null, SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.spanBuilder(null, SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void spanBuilderWithRemoteParent_NullName() { - assertThat(tracer.spanBuilderWithRemoteParent(null, null).startSpan()) - .isSameAs(BlankSpan.INSTANCE); + noopTracer.spanBuilderWithRemoteParent(null, null); + } + + @Test(expected = NullPointerException.class) + public void defaultSpanBuilderWitRemoteParent_NullParent() { + noopTracer.spanBuilderWithRemoteParent(null, SPAN_NAME); } @Test - public void defaultSpanBuilderWitRemoteParent() { - assertThat(tracer.spanBuilderWithRemoteParent(null, SPAN_NAME).startSpan()) + public void defaultSpanBuilderWithRemoteParent() { + assertThat(noopTracer.spanBuilderWithRemoteParent(SpanContext.INVALID, SPAN_NAME).startSpan()) .isSameAs(BlankSpan.INSTANCE); } @Test - public void startScopedSpanRoot() { - Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - NonThrowingCloseable ss = mockTracer.spanBuilder(SPAN_NAME).becomeRoot().startScopedSpan(); + public void startSpanWithParentFromContext() { + NonThrowingCloseable ws = tracer.withSpan(span); try { assertThat(tracer.getCurrentSpan()).isSameAs(span); + when(tracer.spanBuilder(same(span), same(SPAN_NAME))).thenReturn(spanBuilder); + assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); } finally { - ss.close(); + ws.close(); } - verify(span).end(same(EndSpanOptions.DEFAULT)); } @Test - public void startScopedSpanChild() { - Tracer mockTracer = new MockTracer(spanFactory); - NonThrowingCloseable ws = mockTracer.withSpan(BlankSpan.INSTANCE); + public void startSpanWithInvalidParentFromContext() { + NonThrowingCloseable ws = tracer.withSpan(BlankSpan.INSTANCE); try { assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); - when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - NonThrowingCloseable ss = mockTracer.spanBuilder(SPAN_NAME).startScopedSpan(); - try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); - } finally { - ss.close(); - } - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + when(tracer.spanBuilder(same(BlankSpan.INSTANCE), same(SPAN_NAME))).thenReturn(spanBuilder); + assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); } finally { ws.close(); } - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startRootSpan() { - Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span rootSpan = mockTracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME).becomeRoot().startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startChildSpan() { - Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span childSpan = mockTracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME).startSpan(); - assertThat(childSpan).isEqualTo(span); - childSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpanWitRemoteParent() { - Random random = new Random(1234); - Tracer mockTracer = new MockTracer(spanFactory); - SpanContext spanContext = - SpanContext.create( - TraceId.generateRandomId(random), - SpanId.generateRandomId(random), - TraceOptions.DEFAULT); - when(spanFactory.startSpanWithRemoteParent( - same(spanContext), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span remoteChildSpan = - mockTracer.spanBuilderWithRemoteParent(spanContext, SPAN_NAME).startSpan(); - assertThat(remoteChildSpan).isEqualTo(span); - remoteChildSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - private static final class MockTracer extends Tracer { - private MockTracer(SpanFactory spanFactory) { - super(spanFactory); - } } } diff --git a/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java deleted file mode 100644 index 1a983b73..00000000 --- a/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * 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.trace.base; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import io.opencensus.trace.BlankSpan; -import io.opencensus.trace.Span; -import io.opencensus.trace.samplers.Samplers; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link StartSpanOptions}. */ -@RunWith(JUnit4.class) -public class StartSpanOptionsTest { - private final List<Span> singleParentList = Arrays.<Span>asList(BlankSpan.INSTANCE); - - @Test - public void defaultOptions() { - StartSpanOptions defaultOptions = StartSpanOptions.builder().build(); - assertThat(defaultOptions.getSampler()).isNull(); - assertThat(defaultOptions.getParentLinks().isEmpty()).isTrue(); - assertThat(defaultOptions.getRecordEvents()).isNull(); - } - - @Test - public void setSampler() { - StartSpanOptions options = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - assertThat(options.getSampler()).isEqualTo(Samplers.neverSample()); - assertThat(options.getParentLinks().isEmpty()).isTrue(); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setParentLinks() { - StartSpanOptions options = StartSpanOptions.builder().setParentLinks(singleParentList).build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks()).isEqualTo(singleParentList); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setParentLinks_EmptyList() { - StartSpanOptions options = - StartSpanOptions.builder().setParentLinks(new LinkedList<Span>()).build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks().size()).isEqualTo(0); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setParentLinks_MultipleParents() { - StartSpanOptions options = - StartSpanOptions.builder() - .setParentLinks(Arrays.<Span>asList(BlankSpan.INSTANCE, BlankSpan.INSTANCE)) - .build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks().size()).isEqualTo(2); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setRecordEvents() { - StartSpanOptions options = StartSpanOptions.builder().setRecordEvents(true).build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks().isEmpty()).isTrue(); - assertThat(options.getRecordEvents()).isTrue(); - } - - @Test - public void setAllProperties() { - StartSpanOptions options = - StartSpanOptions.builder() - .setSampler(Samplers.alwaysSample()) - .setRecordEvents(true) - .setParentLinks(singleParentList) - .build(); - assertThat(options.getSampler()).isEqualTo(Samplers.alwaysSample()); - assertThat(options.getParentLinks()).isEqualTo(singleParentList); - assertThat(options.getRecordEvents()).isTrue(); - } - - @Test - public void startSpanOptions_EqualsAndHashCode() { - EqualsTester tester = new EqualsTester(); - StartSpanOptions optionsWithAlwaysSampler1 = - StartSpanOptions.builder().setSampler(Samplers.alwaysSample()).build(); - StartSpanOptions optionsWithAlwaysSampler2 = - StartSpanOptions.builder().setSampler(Samplers.alwaysSample()).build(); - tester.addEqualityGroup(optionsWithAlwaysSampler1, optionsWithAlwaysSampler2); - StartSpanOptions optionsWithNeverSampler = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - tester.addEqualityGroup(optionsWithNeverSampler); - tester.addEqualityGroup(StartSpanOptions.DEFAULT); - tester.testEquals(); - } -} diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index 3013e764..06a1412f 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -36,9 +36,9 @@ public class RecordTraceEventsNonSampledSpanBenchmark { private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; private Span linkedSpan = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); private Span span = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); /** TearDown method. */ @TearDown diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index ccfbc775..5773923f 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -36,9 +36,9 @@ public class RecordTraceEventsSampledSpanBenchmark { private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; private Span linkedSpan = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.alwaysSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); private Span span = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.alwaysSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); /** TearDown method. */ @TearDown diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java index 0a86b6f8..8418184f 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java @@ -23,13 +23,13 @@ import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; -/** Benchmarks for {@link SpanFactoryImpl} and {@link SpanImpl}. */ +/** Benchmarks for {@link SpanBuilderImpl} and {@link SpanImpl}. */ @State(Scope.Benchmark) public class StartEndSpanBenchmark { private static final Tracer tracer = Tracing.getTracer(); private static final String SPAN_NAME = "MySpanName"; private Span rootSpan = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); @TearDown public void doTearDown() { @@ -45,7 +45,7 @@ public class StartEndSpanBenchmark { @OutputTimeUnit(TimeUnit.NANOSECONDS) public Span startEndNonSampledRootSpan() { Span span = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); span.end(); return span; } @@ -60,8 +60,7 @@ public class StartEndSpanBenchmark { public Span startEndRecordEventsRootSpan() { Span span = tracer - .spanBuilder(SPAN_NAME) - .becomeRoot() + .spanBuilder(null, SPAN_NAME) .setSampler(Samplers.neverSample()) .setRecordEvents(true) .startSpan(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index aa23f3f7..c6fa0317 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -49,7 +49,7 @@ public final class MultiSpansContextTracing { /** Main method. */ public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); - Span span = tracer.spanBuilder("MyRootSpan").becomeRoot().startSpan(); + Span span = tracer.spanBuilder(null,"MyRootSpan").startSpan(); try (NonThrowingCloseable ws = tracer.withSpan(span)) { doWork(); } diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index 10f2d2ca..547403bb 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -48,7 +48,7 @@ public final class MultiSpansScopedTracing { public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); try (NonThrowingCloseable ss = - tracer.spanBuilder("MyRootSpan").becomeRoot().startScopedSpan()) { + tracer.spanBuilder(null,"MyRootSpan").startScopedSpan()) { doWork(); } } diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java new file mode 100644 index 00000000..74a4ae34 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java @@ -0,0 +1,192 @@ +/* + * Copyright 2017, Google Inc. + * 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.trace; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.opencensus.common.Clock; +import io.opencensus.internal.TimestampConverter; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.Link.Type; +import io.opencensus.trace.base.Sampler; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.internal.RandomHandler; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Random; +import javax.annotation.Nullable; + +/** Implementation of the {@link SpanBuilder}. */ +final class SpanBuilderImpl extends SpanBuilder { + private final Options options; + + private final String name; + private final Span parentSpan; + private final SpanContext remoteParentSpanContext; + private Sampler sampler; + private List<Span> parentLinks = Collections.<Span>emptyList(); + private Boolean recordEvents; + + private Span startSpanInternal( + @Nullable SpanContext parent, + boolean hasRemoteParent, + String name, + Sampler sampler, + List<Span> parentLinks, + Boolean recordEvents, + @Nullable TimestampConverter timestampConverter) { + TraceParams activeTraceParams = options.traceConfig.getActiveTraceParams(); + Random random = options.randomHandler.current(); + TraceId traceId; + SpanId spanId = SpanId.generateRandomId(random); + SpanId parentSpanId = null; + TraceOptions.Builder traceOptionsBuilder; + if (parent == null || !parent.isValid()) { + // New root span. + traceId = TraceId.generateRandomId(random); + traceOptionsBuilder = TraceOptions.builder(); + // This is a root span so no remote or local parent. + hasRemoteParent = false; + } else { + // New child span. + traceId = parent.getTraceId(); + parentSpanId = parent.getSpanId(); + traceOptionsBuilder = TraceOptions.builder(parent.getTraceOptions()); + } + if (sampler == null) { + sampler = activeTraceParams.getSampler(); + } + if (sampler.shouldSample(parent, hasRemoteParent, traceId, spanId, name, parentLinks)) { + traceOptionsBuilder.setIsSampled(); + } + TraceOptions traceOptions = traceOptionsBuilder.build(); + EnumSet<Span.Options> spanOptions = EnumSet.noneOf(Span.Options.class); + if (traceOptions.isSampled() || Boolean.TRUE.equals(recordEvents)) { + spanOptions.add(Span.Options.RECORD_EVENTS); + } + Span span = + SpanImpl.startSpan( + SpanContext.create(traceId, spanId, traceOptions), + spanOptions, + name, + parentSpanId, + hasRemoteParent, + activeTraceParams, + options.startEndHandler, + timestampConverter, + options.clock); + linkSpans(span, parentLinks); + return span; + } + + private static void linkSpans(Span span, List<Span> parentLinks) { + if (!parentLinks.isEmpty()) { + Link childLink = Link.fromSpanContext(span.getContext(), Type.CHILD); + for (Span linkedSpan : parentLinks) { + linkedSpan.addLink(childLink); + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Type.PARENT)); + } + } + } + + static SpanBuilder createBuilder(@Nullable Span parentSpan, String name, Options options) { + return new SpanBuilderImpl(parentSpan, null, name, options); + } + + static SpanBuilder createBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name, Options options) { + return new SpanBuilderImpl(null, checkNotNull(remoteParentSpanContext, + "remoteParentSpanContext"), name, options); + } + + private SpanBuilderImpl( + @Nullable Span parentSpan, + @Nullable SpanContext remoteParentSpanContext, + String name, + Options options) { + this.name = checkNotNull(name, "name"); + this.parentSpan = parentSpan; + this.remoteParentSpanContext = remoteParentSpanContext; + this.options = options; + } + + @Override + public Span startSpan() { + SpanContext parentContext = remoteParentSpanContext; + boolean hasRemoteParent = parentContext != null; + TimestampConverter timestampConverter = null; + if (!hasRemoteParent) { + // This is not a child of a remote Span. Get the parent SpanContext from the parent Span if + // any. + Span parent = parentSpan; + if (parent != null) { + parentContext = parent.getContext(); + // Pass the timestamp converter from the parent to ensure that the recorded events are in + // the right order. Implementation uses System.nanoTime() which is monotonically increasing. + if (parent instanceof SpanImpl) { + timestampConverter = ((SpanImpl) parent).getTimestampConverter(); + } + } + } + return startSpanInternal( + parentContext, + hasRemoteParent, + name, + sampler, + parentLinks, + recordEvents, + timestampConverter); + } + + static final class Options { + private final RandomHandler randomHandler; + private final SpanImpl.StartEndHandler startEndHandler; + private final Clock clock; + private final TraceConfig traceConfig; + + Options( + RandomHandler randomHandler, + SpanImpl.StartEndHandler startEndHandler, + Clock clock, + TraceConfig traceConfig) { + this.randomHandler = checkNotNull(randomHandler, "randomHandler"); + this.startEndHandler = checkNotNull(startEndHandler, "startEndHandler"); + this.clock = checkNotNull(clock, "clock"); + this.traceConfig = checkNotNull(traceConfig, "traceConfig"); + } + } + + @Override + public SpanBuilder setSampler(Sampler sampler) { + this.sampler = checkNotNull(sampler, "sampler"); + return this; + } + + @Override + public SpanBuilder setParentLinks(List<Span> parentLinks) { + this.parentLinks = checkNotNull(parentLinks, "parentLinks"); + return this; + } + + @Override + public SpanBuilder setRecordEvents(boolean recordEvents) { + this.recordEvents = recordEvents; + return this; + } +} diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java deleted file mode 100644 index 4e816d97..00000000 --- a/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * 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.trace; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.opencensus.common.Clock; -import io.opencensus.internal.TimestampConverter; -import io.opencensus.trace.Span.Options; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.Link.Type; -import io.opencensus.trace.base.Sampler; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; -import io.opencensus.trace.config.TraceConfig; -import io.opencensus.trace.config.TraceParams; -import io.opencensus.trace.internal.RandomHandler; -import io.opencensus.trace.internal.SpanFactory; -import java.util.EnumSet; -import java.util.List; -import java.util.Random; -import javax.annotation.Nullable; - -/** Implementation of the {@link SpanFactory}. */ -final class SpanFactoryImpl extends SpanFactory { - private final RandomHandler randomHandler; - private final SpanImpl.StartEndHandler startEndHandler; - private final Clock clock; - private final TraceConfig traceConfig; - - @Override - public Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { - SpanContext parentContext = null; - TimestampConverter timestampConverter = null; - if (parent != null) { - parentContext = parent.getContext(); - // Pass the timestamp converter from the parent to ensure that the recorded events are in - // the right order. Implementation uses System.nanoTime() which is monotonically increasing. - if (parent instanceof SpanImpl) { - timestampConverter = ((SpanImpl) parent).getTimestampConverter(); - } - } - return startSpanInternal(parentContext, false, name, options, timestampConverter); - } - - @Override - public Span startSpanWithRemoteParent( - @Nullable SpanContext remoteParent, String name, StartSpanOptions options) { - return startSpanInternal(remoteParent, true, name, options, null); - } - - Span startSpanInternal( - @Nullable SpanContext parent, - boolean hasRemoteParent, - String name, - StartSpanOptions startSpanOptions, - @Nullable TimestampConverter timestampConverter) { - TraceParams activeTraceParams = traceConfig.getActiveTraceParams(); - Random random = randomHandler.current(); - TraceId traceId; - SpanId spanId = SpanId.generateRandomId(random); - SpanId parentSpanId = null; - TraceOptions.Builder traceOptionsBuilder; - if (parent == null || !parent.isValid()) { - // New root span. - traceId = TraceId.generateRandomId(random); - traceOptionsBuilder = TraceOptions.builder(); - // This is a root span so no remote or local parent. - hasRemoteParent = false; - } else { - // New child span. - traceId = parent.getTraceId(); - parentSpanId = parent.getSpanId(); - traceOptionsBuilder = TraceOptions.builder(parent.getTraceOptions()); - } - Sampler sampler = - startSpanOptions.getSampler() != null - ? startSpanOptions.getSampler() - : activeTraceParams.getSampler(); - if (sampler.shouldSample( - parent, hasRemoteParent, traceId, spanId, name, startSpanOptions.getParentLinks())) { - traceOptionsBuilder.setIsSampled(); - } - TraceOptions traceOptions = traceOptionsBuilder.build(); - EnumSet<Options> spanOptions = EnumSet.noneOf(Options.class); - if (traceOptions.isSampled() || Boolean.TRUE.equals(startSpanOptions.getRecordEvents())) { - spanOptions.add(Options.RECORD_EVENTS); - } - Span span = - SpanImpl.startSpan( - SpanContext.create(traceId, spanId, traceOptions), - spanOptions, - name, - parentSpanId, - hasRemoteParent, - activeTraceParams, - startEndHandler, - timestampConverter, - clock); - linkSpans(span, startSpanOptions.getParentLinks()); - return span; - } - - private static void linkSpans(Span span, List<Span> parentLinks) { - if (!parentLinks.isEmpty()) { - Link childLink = Link.fromSpanContext(span.getContext(), Type.CHILD); - for (Span linkedSpan : parentLinks) { - linkedSpan.addLink(childLink); - span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Type.PARENT)); - } - } - } - - SpanFactoryImpl( - RandomHandler randomHandler, - SpanImpl.StartEndHandler startEndHandler, - Clock clock, - TraceConfig traceConfig) { - this.randomHandler = checkNotNull(randomHandler, "randomHandler"); - this.startEndHandler = checkNotNull(startEndHandler, "startEndHandler"); - this.clock = checkNotNull(clock, "clock"); - this.traceConfig = checkNotNull(traceConfig, "traceConfig"); - } -} diff --git a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index b0f7e07a..9159eead 100644 --- a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -68,8 +68,7 @@ public final class StartEndHandlerImpl implements StartEndHandler { public void onEnd(SpanImpl span) { if ((span.getOptions().contains(Options.RECORD_EVENTS) && enqueueEventForNonSampledSpans) || span.getContext().getTraceOptions().isSampled()) { - eventQueue.enqueue( - new SpanEndEvent(span, spanExporter, runningSpanStore, sampledSpanStore)); + eventQueue.enqueue(new SpanEndEvent(span, spanExporter, runningSpanStore, sampledSpanStore)); } } diff --git a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java b/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java index f753a847..b15a8b99 100644 --- a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java @@ -16,14 +16,30 @@ package io.opencensus.trace; import io.opencensus.common.Clock; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.internal.RandomHandler; +import javax.annotation.Nullable; /** Implementation of the {@link Tracer}. */ final class TracerImpl extends Tracer { + private final SpanBuilderImpl.Options spanBuilderOptions; + TracerImpl( RandomHandler randomHandler, SpanImpl.StartEndHandler startEndHandler, Clock clock, TraceConfig traceConfig) { - super(new SpanFactoryImpl(randomHandler, startEndHandler, clock, traceConfig)); + spanBuilderOptions = + new SpanBuilderImpl.Options(randomHandler, startEndHandler, clock, traceConfig); + } + + @Override + public SpanBuilder spanBuilder(@Nullable Span parent, String name) { + return SpanBuilderImpl.createBuilder(parent, name, spanBuilderOptions); + } + + @Override + public SpanBuilder spanBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name) { + return SpanBuilderImpl.createBuilderWithRemoteParent( + remoteParentSpanContext, name, spanBuilderOptions); } } diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java index a6b80986..fa968f4e 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java @@ -43,8 +43,8 @@ public final class ExportComponentImpl extends ExportComponent { } /** - * Returns a new {@code ExportComponentImpl} that has valid instances for {@link - * RunningSpanStore} and {@link SampledSpanStore}. + * Returns a new {@code ExportComponentImpl} that has valid instances for {@link RunningSpanStore} + * and {@link SampledSpanStore}. * * @return a new {@code ExportComponentImpl}. */ @@ -65,8 +65,8 @@ public final class ExportComponentImpl extends ExportComponent { /** * Constructs a new {@code ExportComponentImpl}. * - * @param supportInProcessStores {@code true} to instantiate {@link RunningSpanStore} and - * {@link SampledSpanStore}. + * @param supportInProcessStores {@code true} to instantiate {@link RunningSpanStore} and {@link + * SampledSpanStore}. */ private ExportComponentImpl(boolean supportInProcessStores) { this.spanExporter = SpanExporterImpl.create(EXPORTER_BUFFER_SIZE, EXPORTER_SCHEDULE_DELAY_MS); diff --git a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java index a2a986e5..b9a62e00 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java @@ -40,6 +40,7 @@ public final class SampledSpanStoreImpl extends SampledSpanStore { private static final int MAX_PER_SPAN_NAME_SAMPLES = NUM_SAMPLES_PER_LATENCY_BUCKET * NUM_LATENCY_BUCKETS + NUM_SAMPLES_PER_ERROR_BUCKET * NUM_ERROR_BUCKETS; + @GuardedBy("samples") private final Map<String, PerSpanNameSamples> samples; @@ -91,8 +92,8 @@ public final class SampledSpanStoreImpl extends SampledSpanStore { } /** - * Keeps samples for a given span name. Samples for all the latency buckets and for all - * canonical codes other than OK. + * Keeps samples for a given span name. Samples for all the latency buckets and for all canonical + * codes other than OK. */ private static final class PerSpanNameSamples { @@ -210,8 +211,8 @@ public final class SampledSpanStoreImpl extends SampledSpanStore { } /** - * Considers to save the given spans to the stored samples. This must be called at the end of - * each Span with the option RECORD_EVENTS. + * Considers to save the given spans to the stored samples. This must be called at the end of each + * Span with the option RECORD_EVENTS. * * @param span the span to be consider for storing into the store buckets. */ diff --git a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java b/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java index 602a0acc..d04d0052 100644 --- a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java +++ b/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java @@ -31,16 +31,12 @@ public abstract class RandomHandler { */ public abstract Random current(); - /** - * Implementation of the {@link RandomHandler} using {@link SecureRandom}. - */ + /** Implementation of the {@link RandomHandler} using {@link SecureRandom}. */ @ThreadSafe public static final class SecureRandomHandler extends RandomHandler { private final Random random = new SecureRandom(); - /** - * Constructs a new {@link SecureRandomHandler}. - */ + /** Constructs a new {@link SecureRandomHandler}. */ public SecureRandomHandler() {} @Override diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java index 1d5cf3ac..afcd3b8b 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java @@ -20,7 +20,6 @@ import io.opencensus.testing.common.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; @@ -36,11 +35,11 @@ import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit tests for {@link SpanFactoryImpl}. */ +/** Unit tests for {@link SpanBuilderImpl}. */ @RunWith(JUnit4.class) -public class SpanFactoryImplTest { +public class SpanBuilderImplTest { private static final String SPAN_NAME = "MySpanName"; - private SpanFactoryImpl spanFactory; + private SpanBuilderImpl.Options spanBuilderOptions; private TraceParams alwaysSampleTraceParams = TraceParams.DEFAULT.toBuilder().setSampler(Samplers.alwaysSample()).build(); private final TestClock testClock = TestClock.create(); @@ -51,14 +50,14 @@ public class SpanFactoryImplTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - spanFactory = new SpanFactoryImpl(randomHandler, startEndHandler, testClock, traceConfig); + spanBuilderOptions = + new SpanBuilderImpl.Options(randomHandler, startEndHandler, testClock, traceConfig); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); } @Test public void startSpanNullParent() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span span = SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions).startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); @@ -72,10 +71,11 @@ public class SpanFactoryImplTest { @Test public void startSpanNullParentWithRecordEvents() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).setRecordEvents(true).build(); - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span span = + SpanBuilderImpl.createBuilder(null, SPAN_NAME, 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(); @@ -87,38 +87,23 @@ public class SpanFactoryImplTest { @Test public void startSpanNullParentNoRecordOptions() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span span = + SpanBuilderImpl.createBuilder(null, SPAN_NAME, 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 startRemoteSpanNullParent() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpanWithRemoteParent(null, SPAN_NAME, startSpanOptions); - assertThat(span.getContext().isValid()).isTrue(); - assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); - assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); - assertThat(span instanceof SpanImpl).isTrue(); - SpanData spanData = ((SpanImpl) span).toSpanData(); - assertThat(spanData.getParentSpanId()).isNull(); - assertThat(spanData.getHasRemoteParent()).isFalse(); - } - - @Test public void startChildSpan() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span rootSpan = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span rootSpan = SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions).startSpan(); assertThat(rootSpan.getContext().isValid()).isTrue(); assertThat(rootSpan.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue(); - Span childSpan = spanFactory.startSpan(rootSpan, SPAN_NAME, startSpanOptions); + Span childSpan = + SpanBuilderImpl.createBuilder(rootSpan, SPAN_NAME, spanBuilderOptions).startSpan(); assertThat(childSpan.getContext().isValid()).isTrue(); assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId()); assertThat(((SpanImpl) childSpan).toSpanData().getParentSpanId()) @@ -127,12 +112,17 @@ public class SpanFactoryImplTest { .isEqualTo(((SpanImpl) rootSpan).getTimestampConverter()); } + @Test(expected = NullPointerException.class) + public void startRemoteSpan_NullParent() { + SpanBuilderImpl.createBuilderWithRemoteParent(null, SPAN_NAME, spanBuilderOptions); + } + @Test public void startRemoteSpanInvalidParent() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = - spanFactory.startSpanWithRemoteParent(SpanContext.INVALID, SPAN_NAME, startSpanOptions); + SpanBuilderImpl.createBuilderWithRemoteParent( + SpanContext.INVALID, SPAN_NAME, spanBuilderOptions) + .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); @@ -149,9 +139,9 @@ public class SpanFactoryImplTest { TraceId.generateRandomId(randomHandler.current()), SpanId.generateRandomId(randomHandler.current()), TraceOptions.DEFAULT); - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpanWithRemoteParent(spanContext, SPAN_NAME, startSpanOptions); + Span span = + SpanBuilderImpl.createBuilderWithRemoteParent(spanContext, SPAN_NAME, spanBuilderOptions) + .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getContext().getTraceId()).isEqualTo(spanContext.getTraceId()); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); diff --git a/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java b/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java new file mode 100644 index 00000000..9ee70c98 --- /dev/null +++ b/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017, Google Inc. + * 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.trace; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.testing.common.TestClock; +import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; +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 TracerImpl}. */ +@RunWith(JUnit4.class) +public class TracerImplTest { + private static final String SPAN_NAME = "MySpanName"; + @Mock private StartEndHandler startEndHandler; + @Mock private TraceConfig traceConfig; + private TracerImpl tracer; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + tracer = + new TracerImpl(new SecureRandomHandler(), startEndHandler, TestClock.create(), traceConfig); + } + + @Test + public void createSpanBuilder() { + SpanBuilder spanBuilder = tracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME); + assertThat(spanBuilder).isInstanceOf(SpanBuilderImpl.class); + } + + @Test + public void createSpanBuilderWithRemoteParet() { + SpanBuilder spanBuilder = tracer.spanBuilderWithRemoteParent(SpanContext.INVALID, SPAN_NAME); + assertThat(spanBuilder).isInstanceOf(SpanBuilderImpl.class); + } +} |
