Browse Source

Adds dedicated tests for OC shim (#7488)

Dan Markwat 1 year ago
parent
commit
aef70d2f63

+ 8 - 0
instrumentation/opencensus-shim/testing/build.gradle.kts

@@ -0,0 +1,8 @@
+plugins {
+  id("otel.javaagent-testing")
+}
+
+dependencies {
+  testLibrary("io.opentelemetry:opentelemetry-opencensus-shim")
+  testCompileOnly("io.opentelemetry:opentelemetry-api")
+}

+ 327 - 0
instrumentation/opencensus-shim/testing/src/test/java/io/opentelemetry/opencensusshim/JavaagentInstrumentationTest.java

@@ -0,0 +1,327 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.opencensusshim;
+
+import io.opencensus.trace.AttributeValue;
+import io.opencensus.trace.Tracing;
+import io.opencensus.trace.samplers.Samplers;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.Scope;
+import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
+import org.assertj.core.api.AbstractBooleanAssert;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class JavaagentInstrumentationTest {
+
+  @RegisterExtension
+  static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
+
+  @BeforeEach
+  void setup() {
+    // by default in opencensus, a probability sampling is used which is not 100%;
+    // we specifically set this configuration here to always sample to ensure traces are emitted for
+    // our tests
+    Tracing.getTraceConfig()
+        .updateActiveTraceParams(
+            Tracing.getTraceConfig().getActiveTraceParams().toBuilder()
+                .setSampler(Samplers.alwaysSample())
+                .build());
+  }
+
+  @Test
+  void testInterleavedSpansOcFirst() {
+    io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
+    Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
+
+    io.opencensus.trace.Span outerSpan = ocTracer.spanBuilder("outer-span").startSpan();
+    Span midSpan;
+    io.opencensus.trace.Span innerSpan;
+
+    outerSpan.putAttribute("outer", AttributeValue.booleanAttributeValue(true));
+
+    try (io.opencensus.common.Scope outerScope = ocTracer.withSpan(outerSpan)) {
+      midSpan =
+          otelTracer
+              .spanBuilder("mid-span")
+              .setSpanKind(SpanKind.INTERNAL)
+              .setAttribute("middle", true)
+              .startSpan();
+      try (Scope midScope = midSpan.makeCurrent()) {
+        innerSpan = ocTracer.spanBuilder("inner-span").startSpan();
+        innerSpan.putAttribute("inner", AttributeValue.booleanAttributeValue(true));
+
+        // make current and immediately close -- avoid empty try block
+        ocTracer.withSpan(innerSpan).close();
+
+        innerSpan.end();
+      } finally {
+        midSpan.end();
+      }
+    } finally {
+      outerSpan.end();
+    }
+
+    Tracing.getExportComponent().shutdown();
+
+    // expecting 1 trace with 3 spans
+    testing.waitAndAssertTraces(
+        ta ->
+            // ensure each span's attributes haven't seeped into parents or children
+            ta.hasSpansSatisfyingExactly(
+                // outer span
+                sa ->
+                    sa.hasName("outer-span")
+                        .hasNoParent()
+                        .hasAttribute(AttributeKey.booleanKey("outer"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull)),
+                // middle span
+                sa ->
+                    sa.hasName("mid-span")
+                        .hasParent(ta.getSpan(0))
+                        .hasAttribute(AttributeKey.booleanKey("middle"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull)),
+                // inner span
+                sa ->
+                    sa.hasName("inner-span")
+                        .hasParent(ta.getSpan(1))
+                        .hasAttribute(AttributeKey.booleanKey("inner"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull))));
+  }
+
+  @Test
+  void testInterleavedSpansOtelFirst() {
+    io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
+    Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
+
+    Span outerSpan =
+        otelTracer
+            .spanBuilder("outer-span")
+            .setSpanKind(SpanKind.INTERNAL)
+            .setAttribute("outer", true)
+            .startSpan();
+    io.opencensus.trace.Span midSpan;
+    Span innerSpan;
+
+    try (Scope outerScope = outerSpan.makeCurrent()) {
+      midSpan = ocTracer.spanBuilder("mid-span").startSpan();
+      midSpan.putAttribute("middle", AttributeValue.booleanAttributeValue(true));
+      try (io.opencensus.common.Scope midScope = ocTracer.withSpan(midSpan)) {
+        innerSpan =
+            otelTracer
+                .spanBuilder("inner-span")
+                .setSpanKind(SpanKind.INTERNAL)
+                .setAttribute("inner", true)
+                .startSpan();
+
+        // make current and immediately close -- avoid empty try block
+        innerSpan.makeCurrent().close();
+
+        innerSpan.end();
+      } finally {
+        midSpan.end();
+      }
+    } finally {
+      outerSpan.end();
+    }
+
+    Tracing.getExportComponent().shutdown();
+
+    // expecting 1 trace with 3 spans
+    testing.waitAndAssertTraces(
+        ta ->
+            // ensure each span's attributes haven't seeped into parents or children
+            ta.hasSpansSatisfyingExactly(
+                // outer span
+                sa ->
+                    sa.hasName("outer-span")
+                        .hasNoParent()
+                        .hasAttribute(AttributeKey.booleanKey("outer"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull)),
+                // middle span
+                sa ->
+                    sa.hasName("mid-span")
+                        .hasParent(ta.getSpan(0))
+                        .hasAttribute(AttributeKey.booleanKey("middle"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull)),
+                // inner span
+                sa ->
+                    sa.hasName("inner-span")
+                        .hasParent(ta.getSpan(1))
+                        .hasAttribute(AttributeKey.booleanKey("inner"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull))));
+  }
+
+  @Test
+  void testStartingWithOtelSpan() {
+    io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
+    Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
+
+    Span otelSpan =
+        otelTracer
+            .spanBuilder("otel-span")
+            .setSpanKind(SpanKind.INTERNAL)
+            .setAttribute("present-on-otel", true)
+            .startSpan();
+
+    io.opencensus.trace.Span ocSpan;
+    try (Scope scope = otelSpan.makeCurrent()) {
+      ocSpan = ocTracer.spanBuilder("oc-span").startSpan();
+      try (io.opencensus.common.Scope ocScope = ocTracer.withSpan(ocSpan)) {
+        ocTracer
+            .getCurrentSpan()
+            .putAttribute("present-on-oc", AttributeValue.booleanAttributeValue(true));
+      }
+      ocSpan.end();
+    }
+    otelSpan.end();
+
+    Tracing.getExportComponent().shutdown();
+
+    testing.waitAndAssertTraces(
+        trace ->
+            trace.hasSpansSatisfyingExactly(
+                span ->
+                    span.hasName("otel-span")
+                        .hasNoParent()
+                        .hasAttribute(AttributeKey.booleanKey("present-on-otel"), true),
+                span ->
+                    span.hasName("oc-span")
+                        .hasParent(trace.getSpan(0))
+                        .hasAttribute(AttributeKey.booleanKey("present-on-oc"), true)));
+  }
+
+  @Test
+  void testStartingWithOpenCensusSpan() {
+    io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
+    Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
+
+    io.opencensus.trace.Span ocSpan = ocTracer.spanBuilder("oc-span").startSpan();
+
+    ocSpan.putAttribute("present-on-oc", AttributeValue.booleanAttributeValue(true));
+
+    Span otelSpan;
+    try (io.opencensus.common.Scope ocScope = ocTracer.withSpan(ocSpan)) {
+      otelSpan = otelTracer.spanBuilder("otel-span").setSpanKind(SpanKind.INTERNAL).startSpan();
+      try (Scope scope = otelSpan.makeCurrent()) {
+        Span.current().setAttribute("present-on-otel", true);
+      }
+      otelSpan.end();
+    }
+    ocSpan.end();
+
+    Tracing.getExportComponent().shutdown();
+
+    testing.waitAndAssertTraces(
+        trace ->
+            trace.hasSpansSatisfyingExactly(
+                span ->
+                    span.hasName("oc-span")
+                        .hasNoParent()
+                        .hasAttribute(AttributeKey.booleanKey("present-on-oc"), true),
+                span ->
+                    span.hasName("otel-span")
+                        .hasParent(trace.getSpan(0))
+                        .hasAttribute(AttributeKey.booleanKey("present-on-otel"), true)));
+  }
+
+  @Test
+  void testNestedOpenCensusSpans() {
+    io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
+
+    io.opencensus.trace.Span outerSpan = ocTracer.spanBuilder("outer-span").startSpan();
+    io.opencensus.trace.Span midSpan;
+    io.opencensus.trace.Span innerSpan;
+
+    outerSpan.putAttribute("outer", AttributeValue.booleanAttributeValue(true));
+
+    try (io.opencensus.common.Scope outerScope = ocTracer.withSpan(outerSpan)) {
+      midSpan = ocTracer.spanBuilder("mid-span").startSpan();
+      midSpan.putAttribute("middle", AttributeValue.booleanAttributeValue(true));
+      try (io.opencensus.common.Scope midScope = ocTracer.withSpan(midSpan)) {
+        innerSpan = ocTracer.spanBuilder("inner-span").startSpan();
+        innerSpan.putAttribute("inner", AttributeValue.booleanAttributeValue(true));
+
+        // make current and immediately close -- avoid empty try block
+        ocTracer.withSpan(innerSpan).close();
+
+        innerSpan.end();
+      } finally {
+        midSpan.end();
+      }
+    } finally {
+      outerSpan.end();
+    }
+
+    Tracing.getExportComponent().shutdown();
+
+    // expecting 1 trace with 3 spans
+    testing.waitAndAssertTraces(
+        ta ->
+            // ensure each span's attributes haven't seeped into parents or children
+            ta.hasSpansSatisfyingExactly(
+                // outer span
+                sa ->
+                    sa.hasName("outer-span")
+                        .hasNoParent()
+                        .hasAttribute(AttributeKey.booleanKey("outer"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull)),
+                // middle span
+                sa ->
+                    sa.hasName("mid-span")
+                        .hasParent(ta.getSpan(0))
+                        .hasAttribute(AttributeKey.booleanKey("middle"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull)),
+                // inner span
+                sa ->
+                    sa.hasName("inner-span")
+                        .hasParent(ta.getSpan(1))
+                        .hasAttribute(AttributeKey.booleanKey("inner"), true)
+                        .hasAttributesSatisfying(
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull),
+                            OpenTelemetryAssertions.satisfies(
+                                AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull))));
+  }
+}

+ 1 - 0
settings.gradle.kts

@@ -378,6 +378,7 @@ hideFromDependabot(":instrumentation:okhttp:okhttp-2.2:javaagent")
 hideFromDependabot(":instrumentation:okhttp:okhttp-3.0:javaagent")
 hideFromDependabot(":instrumentation:okhttp:okhttp-3.0:library")
 hideFromDependabot(":instrumentation:okhttp:okhttp-3.0:testing")
+hideFromDependabot(":instrumentation:opencensus-shim:testing")
 hideFromDependabot(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent")
 hideFromDependabot(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")
 hideFromDependabot(":instrumentation:opentelemetry-api:opentelemetry-api-1.10:javaagent")