From 3f780610374ff9797ab595912ce0b2a9477eda38 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 29 Aug 2024 02:16:22 +0800 Subject: [PATCH 1/4] Convert opentelemetry-api-1.0 tests from groovy to java --- .../src/test/groovy/ContextBridgeTest.groovy | 169 --------- .../src/test/groovy/ContextTest.groovy | 72 ---- .../src/test/groovy/TracerTest.groovy | 357 ------------------ .../opentelemetryapi/ContextBridgeTest.java | 194 ++++++++++ .../opentelemetryapi/ContextTest.java | 96 +++++ .../opentelemetryapi/TracerTest.java | 329 ++++++++++++++++ 6 files changed, 619 insertions(+), 598 deletions(-) delete mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextBridgeTest.groovy delete mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextTest.groovy delete mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/TracerTest.groovy create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextBridgeTest.groovy b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextBridgeTest.groovy deleted file mode 100644 index 3b3778b25374..000000000000 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextBridgeTest.groovy +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.api.GlobalOpenTelemetry -import io.opentelemetry.api.baggage.Baggage -import io.opentelemetry.api.trace.Span -import io.opentelemetry.context.Context -import io.opentelemetry.context.ContextKey -import io.opentelemetry.instrumentation.annotations.WithSpan -import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification -import io.opentelemetry.semconv.incubating.CodeIncubatingAttributes - -import java.util.concurrent.CountDownLatch -import java.util.concurrent.Executors -import java.util.concurrent.atomic.AtomicReference - -class ContextBridgeTest extends AgentInstrumentationSpecification { - - private static final ContextKey ANIMAL = ContextKey.named("animal") - - def "agent propagates application's context"() { - when: - def context = Context.current().with(ANIMAL, "cat") - def captured = new AtomicReference() - context.makeCurrent().withCloseable { - Executors.newSingleThreadExecutor().submit({ - captured.set(Context.current().get(ANIMAL)) - }).get() - } - - then: - captured.get() == "cat" - } - - def "application propagates agent's context"() { - given: - def runnable = new Runnable() { - @WithSpan("test") - @Override - void run() { - // using @WithSpan above to make the agent generate a context - // and then using manual propagation below to verify that context can be propagated by user - def context = Context.current() - Context.root().makeCurrent().withCloseable { - Span.current().setAttribute("dog", "no") - context.makeCurrent().withCloseable { - Span.current().setAttribute("cat", "yes") - } - } - } - } - - when: - runnable.run() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test" - hasNoParent() - attributes { - "$CodeIncubatingAttributes.CODE_NAMESPACE" runnable.class.name - "$CodeIncubatingAttributes.CODE_FUNCTION" "run" - "cat" "yes" - } - } - } - } - } - - def "agent propagates application's span"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - - def testSpan = tracer.spanBuilder("test").startSpan() - testSpan.makeCurrent().withCloseable { - Executors.newSingleThreadExecutor().submit({ - Span.current().setAttribute("cat", "yes") - }).get() - } - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test" - hasNoParent() - attributes { - "cat" "yes" - } - } - } - } - } - - def "application propagates agent's span"() { - given: - def runnable = new Runnable() { - @WithSpan("test") - @Override - void run() { - // using @WithSpan above to make the agent generate a span - // and then using manual propagation below to verify that span can be propagated by user - def span = Span.current() - Context.root().makeCurrent().withCloseable { - Span.current().setAttribute("dog", "no") - span.makeCurrent().withCloseable { - Span.current().setAttribute("cat", "yes") - } - } - } - } - - when: - runnable.run() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test" - hasNoParent() - attributes { - "$CodeIncubatingAttributes.CODE_NAMESPACE" runnable.class.name - "$CodeIncubatingAttributes.CODE_FUNCTION" "run" - "cat" "yes" - } - } - } - } - } - - def "agent propagates application's baggage"() { - when: - def testBaggage = Baggage.builder().put("cat", "yes").build() - def ref = new AtomicReference() - def latch = new CountDownLatch(1) - testBaggage.makeCurrent().withCloseable { - Executors.newSingleThreadExecutor().submit({ - ref.set(Baggage.current()) - latch.countDown() - }).get() - } - - then: - latch.await() - ref.get().size() == 1 - ref.get().getEntryValue("cat") == "yes" - } - - def "test empty current context is root context"() { - expect: - Context.current() == Context.root() - } - - // TODO (trask) - // more tests are needed here, not sure how to implement, probably need to write some test - // instrumentation to help test, similar to :testing-common:integration-tests - // - // * "application propagates agent's baggage" - // * "agent uses application's span" - // * "application uses agent's span" (this is covered above by "application propagates agent's span") - // * "agent uses application's baggage" - // * "application uses agent's baggage" -} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextTest.groovy b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextTest.groovy deleted file mode 100644 index ba2d52a68708..000000000000 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/ContextTest.groovy +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.api.GlobalOpenTelemetry -import io.opentelemetry.api.trace.Span -import io.opentelemetry.context.Context -import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification - -class ContextTest extends AgentInstrumentationSpecification { - - def "Span.current() should return invalid"() { - when: - def span = Span.current() - - then: - !span.spanContext.valid - } - - def "Span.current() should return span"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - def scope = testSpan.makeCurrent() - def span = Span.current() - scope.close() - - then: - span == testSpan - } - - def "Span.fromContext should return invalid"() { - when: - def span = Span.fromContext(Context.current()) - - then: - !span.spanContext.valid - } - - def "getSpan should return span"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - def scope = testSpan.makeCurrent() - def span = Span.fromContext(Context.current()) - scope.close() - - then: - span == testSpan - } - - def "Span.fromContextOrNull should return null"() { - when: - def span = Span.fromContextOrNull(Context.current()) - - then: - span == null - } - - def "Span.fromContextOrNull should return span"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - def scope = testSpan.makeCurrent() - def span = Span.fromContextOrNull(Context.current()) - scope.close() - - then: - span == testSpan - } -} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/TracerTest.groovy b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/TracerTest.groovy deleted file mode 100644 index be63f3d40255..000000000000 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/groovy/TracerTest.groovy +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.api.GlobalOpenTelemetry -import io.opentelemetry.api.common.Attributes -import io.opentelemetry.api.trace.Span -import io.opentelemetry.context.Context -import io.opentelemetry.context.Scope -import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification -import io.opentelemetry.semconv.ExceptionAttributes - -import static io.opentelemetry.api.trace.SpanKind.PRODUCER -import static io.opentelemetry.api.trace.StatusCode.ERROR - -class TracerTest extends AgentInstrumentationSpecification { - - def "capture span, kind, attributes, and status"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan() - testSpan.setAttribute("string", "1") - testSpan.setAttribute("long", 2) - testSpan.setAttribute("double", 3.0) - testSpan.setAttribute("boolean", true) - testSpan.setStatus(ERROR) - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test" - kind PRODUCER - hasNoParent() - status ERROR - attributes { - "string" "1" - "long" 2 - "double" 3.0 - "boolean" true - } - } - } - } - } - - def "capture span with implicit parent using Tracer.withSpan()"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - Span parentSpan = tracer.spanBuilder("parent").startSpan() - Scope parentScope = Context.current().with(parentSpan).makeCurrent() - - def testSpan = tracer.spanBuilder("test").startSpan() - testSpan.end() - - parentSpan.end() - parentScope.close() - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - hasNoParent() - attributes { - } - } - span(1) { - name "test" - childOf span(0) - attributes { - } - } - } - } - } - - def "capture span with implicit parent using makeCurrent"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - Span parentSpan = tracer.spanBuilder("parent").startSpan() - Scope parentScope = parentSpan.makeCurrent() - - def testSpan = tracer.spanBuilder("test").startSpan() - testSpan.end() - - parentSpan.end() - parentScope.close() - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - hasNoParent() - attributes { - } - } - span(1) { - name "test" - childOf span(0) - attributes { - } - } - } - } - } - - def "capture span with implicit parent using TracingContextUtils.withSpan and makeCurrent"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - Span parentSpan = tracer.spanBuilder("parent").startSpan() - def parentContext = Context.current().with(parentSpan) - Scope parentScope = parentContext.makeCurrent() - - def testSpan = tracer.spanBuilder("test").startSpan() - testSpan.end() - - parentSpan.end() - parentScope.close() - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - hasNoParent() - attributes { - } - } - span(1) { - name "test" - childOf span(0) - attributes { - } - } - } - } - } - - def "capture span with explicit parent"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def parentSpan = tracer.spanBuilder("parent").startSpan() - def context = Context.root().with(parentSpan) - def testSpan = tracer.spanBuilder("test").setParent(context).startSpan() - testSpan.end() - parentSpan.end() - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - hasNoParent() - attributes { - } - } - span(1) { - name "test" - childOf span(0) - attributes { - } - } - } - } - } - - def "capture span with explicit no parent"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def parentSpan = tracer.spanBuilder("parent").startSpan() - def parentScope = parentSpan.makeCurrent() - def testSpan = tracer.spanBuilder("test").setNoParent().startSpan() - testSpan.end() - parentSpan.end() - parentScope.close() - - then: - assertTraces(2) { - traces.sort(orderByRootSpanName("parent", "test")) - trace(0, 1) { - span(0) { - name "parent" - hasNoParent() - attributes { - } - } - } - trace(1, 1) { - span(0) { - name "test" - hasNoParent() - attributes { - } - } - } - } - } - - def "capture name update"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - testSpan.updateName("test2") - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test2" - hasNoParent() - attributes { - } - } - } - } - } - - def "capture exception()"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - testSpan.recordException(new IllegalStateException()) - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test" - event(0) { - eventName("exception") - attributes { - "$ExceptionAttributes.EXCEPTION_TYPE" "java.lang.IllegalStateException" - "$ExceptionAttributes.EXCEPTION_STACKTRACE" String - } - } - attributes { - } - } - } - } - } - - def "capture exception with Attributes()"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - testSpan.recordException( - new IllegalStateException(), - Attributes.builder().put("dog", "bark").build()) - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test" - event(0) { - eventName("exception") - attributes { - "$ExceptionAttributes.EXCEPTION_TYPE" "java.lang.IllegalStateException" - "$ExceptionAttributes.EXCEPTION_STACKTRACE" String - "dog" "bark" - } - } - attributes { - } - } - } - } - } - - def "capture name update using TracingContextUtils.getCurrentSpan()"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - def testScope = Context.current().with(testSpan).makeCurrent() - Span.current().updateName("test2") - testScope.close() - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test2" - hasNoParent() - attributes { - } - } - } - } - } - - def "capture name update using TracingContextUtils.Span.fromContext(Context.current())"() { - when: - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").startSpan() - def testScope = Context.current().with(testSpan).makeCurrent() - Span.fromContext(Context.current()).updateName("test2") - testScope.close() - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test2" - hasNoParent() - attributes { - } - } - } - } - } - - def "add wrapped span to context"() { - when: - // Lazy way to get a span context - def tracer = GlobalOpenTelemetry.getTracer("test") - def testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan() - testSpan.end() - - def span = Span.wrap(testSpan.getSpanContext()) - def context = Context.current().with(span) - - then: - Span.fromContext(context).getSpanContext().getSpanId() == span.getSpanContext().getSpanId() - } - - // this test uses opentelemetry-api-1.4 instrumentation - def "test tracer builder"() { - when: - def tracer = GlobalOpenTelemetry.get().tracerBuilder("test").setInstrumentationVersion("1.2.3").build() - def testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan() - testSpan.end() - - then: - assertTraces(1) { - trace(0, 1) { - span(0) { - name "test" - kind PRODUCER - hasNoParent() - instrumentationLibraryVersion "1.2.3" - attributes { - } - } - } - } - } -} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java new file mode 100644 index 000000000000..9f172c4a29b8 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java @@ -0,0 +1,194 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.baggage.Baggage; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.ContextKey; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.annotations.WithSpan; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.semconv.incubating.CodeIncubatingAttributes; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.RegisterExtension; + +@ExtendWith(AgentInstrumentationExtension.class) +public class ContextBridgeTest { + + @RegisterExtension + private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private static final ContextKey ANIMAL = ContextKey.named("animal"); + + @Test + @DisplayName("agent propagates application's context") + public void agentPropagatesApplicationsContext() throws Exception { + // When + Context context = Context.current().with(ANIMAL, "cat"); + AtomicReference captured = new AtomicReference<>(); + try (Scope ignored = context.makeCurrent()) { + Executors.newSingleThreadExecutor() + .submit(() -> captured.set(Context.current().get(ANIMAL))) + .get(); + } + + // Then + assertEquals("cat", captured.get()); + } + + @Test + @DisplayName("application propagates agent's context") + public void applicationPropagatesAgentsContext() { + // Given + Runnable runnable = + new Runnable() { + @WithSpan("test") + @Override + public void run() { + Context context = Context.current(); + try (Scope ignored = Context.root().makeCurrent()) { + Span.current().setAttribute("dog", "no"); + try (Scope ignored2 = context.makeCurrent()) { + Span.current().setAttribute("cat", "yes"); + } + } + } + }; + + // When + runnable.run(); + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("test") + .hasNoParent() + .hasAttributesSatisfyingExactly( + equalTo( + CodeIncubatingAttributes.CODE_NAMESPACE, + runnable.getClass().getName()), + equalTo(CodeIncubatingAttributes.CODE_FUNCTION, "run"), + equalTo(stringKey("cat"), "yes")))); + } + + @Test + @DisplayName("agent propagates application's span") + public void agentPropagatesApplicationsSpan() throws Exception { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + + Span testSpan = tracer.spanBuilder("test").startSpan(); + try (Scope ignored = testSpan.makeCurrent()) { + Executors.newSingleThreadExecutor() + .submit( + () -> { + Span.current().setAttribute("cat", "yes"); + }) + .get(); + } + testSpan.end(); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("test") + .hasNoParent() + .hasAttributesSatisfyingExactly(equalTo(stringKey("cat"), "yes")))); + } + + @Test + @DisplayName("application propagates agent's span") + public void applicationPropagatesAgentsSpan() { + // Given + Runnable runnable = + new Runnable() { + @WithSpan("test") + @Override + public void run() { + Span span = Span.current(); + try (Scope ignored = Context.root().makeCurrent()) { + Span.current().setAttribute("dog", "no"); + try (Scope ignored2 = span.makeCurrent()) { + Span.current().setAttribute("cat", "yes"); + } + } + } + }; + + // When + runnable.run(); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("test") + .hasNoParent() + .hasAttributesSatisfyingExactly( + equalTo( + CodeIncubatingAttributes.CODE_NAMESPACE, + runnable.getClass().getName()), + equalTo(CodeIncubatingAttributes.CODE_FUNCTION, "run"), + equalTo(stringKey("cat"), "yes")))); + } + + @Test + @DisplayName("agent propagates application's baggage") + public void agentPropagatesApplicationsBaggage() throws Exception { + // When + Baggage testBaggage = Baggage.builder().put("cat", "yes").build(); + AtomicReference ref = new AtomicReference<>(); + CountDownLatch latch = new CountDownLatch(1); + try (Scope ignored = testBaggage.makeCurrent()) { + Executors.newSingleThreadExecutor() + .submit( + () -> { + ref.set(Baggage.current()); + latch.countDown(); + }) + .get(); + } + + // Then + latch.await(); + assertEquals(1, ref.get().size()); + assertEquals("yes", ref.get().getEntryValue("cat")); + } + + @Test + @DisplayName("test empty current context is root context") + public void testEmptyCurrentContextIsRootContext() { + // Expect + assertEquals(Context.root(), Context.current()); + } + + // TODO (trask) + // more tests are needed here, not sure how to implement, probably need to write some test + // instrumentation to help test, similar to :testing-common:integration-tests + // + // * "application propagates agent's baggage" + // * "agent uses application's span" + // * "application uses agent's span" (this is covered above by "application propagates agent's + // span") + // * "agent uses application's baggage" + // * "application uses agent's baggage" +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java new file mode 100644 index 000000000000..d8f7f77e7956 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java @@ -0,0 +1,96 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(AgentInstrumentationExtension.class) +public class ContextTest { + + @Test + @DisplayName("Span.current() should return invalid") + public void spanCurrentShouldReturnInvalid() { + // When + Span span = Span.current(); + + // Then + assertFalse(span.getSpanContext().isValid()); + } + + @Test + @DisplayName("Span.current() should return span") + public void spanCurrentShouldReturnSpan() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + try (Scope ignored = testSpan.makeCurrent()) { + Span span = Span.current(); + + // Then + assertEquals(testSpan, span); + } + } + + @Test + @DisplayName("Span.fromContext should return invalid") + public void spanFromContextShouldReturnInvalid() { + // When + Span span = Span.fromContext(Context.current()); + + // Then + assertFalse(span.getSpanContext().isValid()); + } + + @Test + @DisplayName("getSpan should return span") + public void getSpanShouldReturnSpan() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + try (Scope ignored = testSpan.makeCurrent()) { + Span span = Span.fromContext(Context.current()); + + // Then + assertEquals(testSpan, span); + } + } + + @Test + @DisplayName("Span.fromContextOrNull should return null") + public void spanFromContextOrNullShouldReturnNull() { + // When + Span span = Span.fromContextOrNull(Context.current()); + + // Then + assertNull(span); + } + + @Test + @DisplayName("Span.fromContextOrNull should return span") + public void spanFromContextOrNullShouldReturnSpan() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + try (Scope ignored = testSpan.makeCurrent()) { + Span span = Span.fromContextOrNull(Context.current()); + + // Then + assertEquals(testSpan, span); + } + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java new file mode 100644 index 000000000000..5a55f14dbdc5 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java @@ -0,0 +1,329 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi; + +import static io.opentelemetry.api.common.AttributeKey.booleanKey; +import static io.opentelemetry.api.common.AttributeKey.doubleKey; +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.api.trace.SpanKind.PRODUCER; +import static io.opentelemetry.api.trace.StatusCode.ERROR; +import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.trace.data.StatusData; +import io.opentelemetry.semconv.ExceptionAttributes; +import java.io.PrintWriter; +import java.io.StringWriter; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.RegisterExtension; + +@ExtendWith(AgentInstrumentationExtension.class) +public class TracerTest { + + @RegisterExtension + private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + @Test + @DisplayName("capture span, kind, attributes, and status") + public void captureSpanKindAttributesAndStatus() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan(); + testSpan.setAttribute("string", "1"); + testSpan.setAttribute("long", 2L); + testSpan.setAttribute("double", 3.0); + testSpan.setAttribute("boolean", true); + testSpan.setStatus(ERROR); + testSpan.end(); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("test") + .hasKind(PRODUCER) + .hasNoParent() + .hasStatus(StatusData.error()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("string"), "1"), + equalTo(longKey("long"), 2L), + equalTo(doubleKey("double"), 3.0), + equalTo(booleanKey("boolean"), true)))); + } + + @Test + @DisplayName("capture span with implicit parent using Tracer.withSpan()") + public void captureSpanWithImplicitParentUsingTracerWithSpan() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span parentSpan = tracer.spanBuilder("parent").startSpan(); + Scope parentScope = Context.current().with(parentSpan).makeCurrent(); + + Span testSpan = tracer.spanBuilder("test").startSpan(); + testSpan.end(); + + parentSpan.end(); + parentScope.close(); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span0 -> span0.hasName("parent").hasNoParent().hasAttributesSatisfyingExactly(), + span1 -> + span1 + .hasName("test") + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly())); + } + + @Test + @DisplayName("capture span with implicit parent using makeCurrent") + public void captureSpanWithImplicitParentUsingMakeCurrent() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span parentSpan = tracer.spanBuilder("parent").startSpan(); + Scope parentScope = parentSpan.makeCurrent(); + + Span testSpan = tracer.spanBuilder("test").startSpan(); + testSpan.end(); + + parentSpan.end(); + parentScope.close(); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span0 -> span0.hasName("parent").hasNoParent(), + span1 -> span1.hasName("test").hasParent(trace.getSpan(0)))); + } + + @Test + @DisplayName( + "capture span with implicit parent using TracingContextUtils.withSpan and makeCurrent") + public void captureSpanWithImplicitParentUsingTracingContextUtilsWithSpanAndMakeCurrent() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span parentSpan = tracer.spanBuilder("parent").startSpan(); + Context parentContext = Context.current().with(parentSpan); + Scope parentScope = parentContext.makeCurrent(); + + Span testSpan = tracer.spanBuilder("test").startSpan(); + testSpan.end(); + + parentSpan.end(); + parentScope.close(); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span0 -> span0.hasName("parent").hasNoParent(), + span1 -> span1.hasName("test").hasParent(trace.getSpan(0)))); + } + + @Test + @DisplayName("capture span with explicit parent") + public void captureSpanWithExplicitParent() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span parentSpan = tracer.spanBuilder("parent").startSpan(); + Context context = Context.root().with(parentSpan); + Span testSpan = tracer.spanBuilder("test").setParent(context).startSpan(); + testSpan.end(); + parentSpan.end(); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span0 -> span0.hasName("parent").hasNoParent(), + span1 -> span1.hasName("test").hasParent(trace.getSpan(0)))); + } + + @Test + @DisplayName("capture span with explicit no parent") + public void captureSpanWithExplicitNoParent() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span parentSpan = tracer.spanBuilder("parent").startSpan(); + Scope parentScope = parentSpan.makeCurrent(); + Span testSpan = tracer.spanBuilder("test").setNoParent().startSpan(); + testSpan.end(); + parentSpan.end(); + parentScope.close(); + + // Then + testing.waitAndAssertSortedTraces( + orderByRootSpanName("parent", "test"), + trace0 -> trace0.hasSpansSatisfyingExactly(span -> span.hasName("parent").hasNoParent()), + trace1 -> trace1.hasSpansSatisfyingExactly(span -> span.hasName("test").hasNoParent())); + } + + @Test + @DisplayName("capture name update") + public void captureNameUpdate() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + testSpan.updateName("test2"); + testSpan.end(); + + // Then + testing.waitAndAssertTraces( + trace -> trace.hasSpansSatisfyingExactly(span -> span.hasName("test2").hasNoParent())); + } + + @Test + @DisplayName("capture exception()") + public void captureException() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + IllegalStateException throwable = new IllegalStateException(); + testSpan.recordException(throwable); + testSpan.end(); + + StringWriter writer = new StringWriter(); + throwable.printStackTrace(new PrintWriter(writer)); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("test") + .hasEventsSatisfyingExactly( + event -> + event + .hasName("exception") + .hasAttributesSatisfyingExactly( + equalTo( + ExceptionAttributes.EXCEPTION_TYPE, + "java.lang.IllegalStateException"), + equalTo( + ExceptionAttributes.EXCEPTION_STACKTRACE, + writer.toString()))))); + } + + @Test + @DisplayName("capture exception with Attributes()") + public void captureExceptionWithAttributes() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + IllegalStateException throwable = new IllegalStateException(); + testSpan.recordException(throwable, Attributes.builder().put("dog", "bark").build()); + testSpan.end(); + + StringWriter writer = new StringWriter(); + throwable.printStackTrace(new PrintWriter(writer)); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("test") + .hasEventsSatisfyingExactly( + event -> + event + .hasName("exception") + .hasAttributesSatisfyingExactly( + equalTo( + ExceptionAttributes.EXCEPTION_TYPE, + "java.lang.IllegalStateException"), + equalTo( + ExceptionAttributes.EXCEPTION_STACKTRACE, + writer.toString()), + equalTo(stringKey("dog"), "bark"))))); + } + + @Test + @DisplayName("capture name update using TracingContextUtils.getCurrentSpan()") + public void captureNameUpdateUsingTracingContextUtilsGetCurrentSpan() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + Scope testScope = Context.current().with(testSpan).makeCurrent(); + Span.current().updateName("test2"); + testScope.close(); + testSpan.end(); + + // Then + testing.waitAndAssertTraces( + trace -> trace.hasSpansSatisfyingExactly(span -> span.hasName("test2").hasNoParent())); + } + + @Test + @DisplayName("capture name update using TracingContextUtils.Span.fromContext(Context.current())") + public void captureNameUpdateUsingTracingContextUtilsSpanFromContextCurrent() { + // When + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").startSpan(); + Scope testScope = Context.current().with(testSpan).makeCurrent(); + Span.fromContext(Context.current()).updateName("test2"); + testScope.close(); + testSpan.end(); + + // Then + testing.waitAndAssertTraces( + trace -> trace.hasSpansSatisfyingExactly(span -> span.hasName("test2").hasNoParent())); + } + + @Test + @DisplayName("add wrapped span to context") + public void addWrappedSpanToContext() { + // When + // Lazy way to get a span context + Tracer tracer = GlobalOpenTelemetry.getTracer("test"); + Span testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan(); + testSpan.end(); + + Span span = Span.wrap(testSpan.getSpanContext()); + Context context = Context.current().with(span); + + // Then + assertEquals( + span.getSpanContext().getSpanId(), Span.fromContext(context).getSpanContext().getSpanId()); + } + + @Test + @DisplayName("test tracer builder") + public void testTracerBuilder() { + // When + Tracer tracer = + GlobalOpenTelemetry.get().tracerBuilder("test").setInstrumentationVersion("1.2.3").build(); + Span testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan(); + testSpan.end(); + + // Then + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("test") + .hasKind(PRODUCER) + .hasNoParent() + .hasInstrumentationScopeInfo( + InstrumentationScopeInfo.builder("test").setVersion("1.2.3").build()))); + } +} From 4ce60f9fd7d2452521e4414500752eba02cedd78 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 29 Aug 2024 12:19:33 +0800 Subject: [PATCH 2/4] 1. Change test classes and methods to package-private 2. Replace jupiter with assertj for assertions 3. Remove the redundantly declared AgentInstrumentationExtension 4. Retain comments in the groovy tests 5. Use the method hasTotalAttributeCount when asserting a Span with no attributes 6. Rename span1 and span2 to span --- .../opentelemetryapi/ContextBridgeTest.java | 31 +++---- .../opentelemetryapi/ContextTest.java | 31 ++++--- .../opentelemetryapi/TracerTest.java | 84 +++++++++++-------- 3 files changed, 79 insertions(+), 67 deletions(-) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java index 9f172c4a29b8..d73dc4b80fa6 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextBridgeTest.java @@ -7,7 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.baggage.Baggage; @@ -25,11 +25,9 @@ import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; -@ExtendWith(AgentInstrumentationExtension.class) -public class ContextBridgeTest { +class ContextBridgeTest { @RegisterExtension private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); @@ -38,7 +36,7 @@ public class ContextBridgeTest { @Test @DisplayName("agent propagates application's context") - public void agentPropagatesApplicationsContext() throws Exception { + void agentPropagatesApplicationsContext() throws Exception { // When Context context = Context.current().with(ANIMAL, "cat"); AtomicReference captured = new AtomicReference<>(); @@ -49,18 +47,21 @@ public void agentPropagatesApplicationsContext() throws Exception { } // Then - assertEquals("cat", captured.get()); + assertThat(captured.get()).isEqualTo("cat"); } @Test @DisplayName("application propagates agent's context") - public void applicationPropagatesAgentsContext() { + void applicationPropagatesAgentsContext() { // Given Runnable runnable = new Runnable() { @WithSpan("test") @Override public void run() { + // using @WithSpan above to make the agent generate a context + // and then using manual propagation below to verify that context can be propagated by + // user Context context = Context.current(); try (Scope ignored = Context.root().makeCurrent()) { Span.current().setAttribute("dog", "no"); @@ -90,7 +91,7 @@ public void run() { @Test @DisplayName("agent propagates application's span") - public void agentPropagatesApplicationsSpan() throws Exception { + void agentPropagatesApplicationsSpan() throws Exception { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); @@ -116,13 +117,15 @@ public void agentPropagatesApplicationsSpan() throws Exception { @Test @DisplayName("application propagates agent's span") - public void applicationPropagatesAgentsSpan() { + void applicationPropagatesAgentsSpan() { // Given Runnable runnable = new Runnable() { @WithSpan("test") @Override public void run() { + // using @WithSpan above to make the agent generate a span + // and then using manual propagation below to verify that span can be propagated by user Span span = Span.current(); try (Scope ignored = Context.root().makeCurrent()) { Span.current().setAttribute("dog", "no"); @@ -153,7 +156,7 @@ public void run() { @Test @DisplayName("agent propagates application's baggage") - public void agentPropagatesApplicationsBaggage() throws Exception { + void agentPropagatesApplicationsBaggage() throws Exception { // When Baggage testBaggage = Baggage.builder().put("cat", "yes").build(); AtomicReference ref = new AtomicReference<>(); @@ -170,15 +173,15 @@ public void agentPropagatesApplicationsBaggage() throws Exception { // Then latch.await(); - assertEquals(1, ref.get().size()); - assertEquals("yes", ref.get().getEntryValue("cat")); + assertThat(ref.get().size()).isEqualTo(1); + assertThat(ref.get().getEntryValue("cat")).isEqualTo("yes"); } @Test @DisplayName("test empty current context is root context") - public void testEmptyCurrentContextIsRootContext() { + void testEmptyCurrentContextIsRootContext() { // Expect - assertEquals(Context.root(), Context.current()); + assertThat(Context.current()).isEqualTo(Context.root()); } // TODO (trask) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java index d8f7f77e7956..43278ba71469 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java @@ -5,9 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.trace.Span; @@ -20,21 +18,20 @@ import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(AgentInstrumentationExtension.class) -public class ContextTest { +class ContextTest { @Test @DisplayName("Span.current() should return invalid") - public void spanCurrentShouldReturnInvalid() { + void spanCurrentShouldReturnInvalid() { // When Span span = Span.current(); - // Then - assertFalse(span.getSpanContext().isValid()); + assertThat(span.getSpanContext().isValid()).isFalse(); } @Test @DisplayName("Span.current() should return span") - public void spanCurrentShouldReturnSpan() { + void spanCurrentShouldReturnSpan() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -42,23 +39,23 @@ public void spanCurrentShouldReturnSpan() { Span span = Span.current(); // Then - assertEquals(testSpan, span); + assertThat(span).isEqualTo(testSpan); } } @Test @DisplayName("Span.fromContext should return invalid") - public void spanFromContextShouldReturnInvalid() { + void spanFromContextShouldReturnInvalid() { // When Span span = Span.fromContext(Context.current()); // Then - assertFalse(span.getSpanContext().isValid()); + assertThat(span.getSpanContext().isValid()).isFalse(); } @Test @DisplayName("getSpan should return span") - public void getSpanShouldReturnSpan() { + void getSpanShouldReturnSpan() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -66,23 +63,23 @@ public void getSpanShouldReturnSpan() { Span span = Span.fromContext(Context.current()); // Then - assertEquals(testSpan, span); + assertThat(span).isEqualTo(testSpan); } } @Test @DisplayName("Span.fromContextOrNull should return null") - public void spanFromContextOrNullShouldReturnNull() { + void spanFromContextOrNullShouldReturnNull() { // When Span span = Span.fromContextOrNull(Context.current()); // Then - assertNull(span); + assertThat(span).isNull(); } @Test @DisplayName("Span.fromContextOrNull should return span") - public void spanFromContextOrNullShouldReturnSpan() { + void spanFromContextOrNullShouldReturnSpan() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -90,7 +87,7 @@ public void spanFromContextOrNullShouldReturnSpan() { Span span = Span.fromContextOrNull(Context.current()); // Then - assertEquals(testSpan, span); + assertThat(span).isEqualTo(testSpan); } } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java index 5a55f14dbdc5..74bd761769ff 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java @@ -13,7 +13,7 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.Attributes; @@ -30,18 +30,16 @@ import java.io.StringWriter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; -@ExtendWith(AgentInstrumentationExtension.class) -public class TracerTest { +class TracerTest { @RegisterExtension private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); @Test @DisplayName("capture span, kind, attributes, and status") - public void captureSpanKindAttributesAndStatus() { + void captureSpanKindAttributesAndStatus() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan(); @@ -70,7 +68,7 @@ public void captureSpanKindAttributesAndStatus() { @Test @DisplayName("capture span with implicit parent using Tracer.withSpan()") - public void captureSpanWithImplicitParentUsingTracerWithSpan() { + void captureSpanWithImplicitParentUsingTracerWithSpan() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span parentSpan = tracer.spanBuilder("parent").startSpan(); @@ -86,17 +84,14 @@ public void captureSpanWithImplicitParentUsingTracerWithSpan() { testing.waitAndAssertTraces( trace -> trace.hasSpansSatisfyingExactly( - span0 -> span0.hasName("parent").hasNoParent().hasAttributesSatisfyingExactly(), - span1 -> - span1 - .hasName("test") - .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly())); + span -> span.hasName("parent").hasNoParent().hasTotalAttributeCount(0), + span -> + span.hasName("test").hasParent(trace.getSpan(0)).hasTotalAttributeCount(0))); } @Test @DisplayName("capture span with implicit parent using makeCurrent") - public void captureSpanWithImplicitParentUsingMakeCurrent() { + void captureSpanWithImplicitParentUsingMakeCurrent() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span parentSpan = tracer.spanBuilder("parent").startSpan(); @@ -112,14 +107,15 @@ public void captureSpanWithImplicitParentUsingMakeCurrent() { testing.waitAndAssertTraces( trace -> trace.hasSpansSatisfyingExactly( - span0 -> span0.hasName("parent").hasNoParent(), - span1 -> span1.hasName("test").hasParent(trace.getSpan(0)))); + span -> span.hasName("parent").hasNoParent().hasTotalAttributeCount(0), + span -> + span.hasName("test").hasParent(trace.getSpan(0)).hasTotalAttributeCount(0))); } @Test @DisplayName( "capture span with implicit parent using TracingContextUtils.withSpan and makeCurrent") - public void captureSpanWithImplicitParentUsingTracingContextUtilsWithSpanAndMakeCurrent() { + void captureSpanWithImplicitParentUsingTracingContextUtilsWithSpanAndMakeCurrent() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span parentSpan = tracer.spanBuilder("parent").startSpan(); @@ -136,13 +132,14 @@ public void captureSpanWithImplicitParentUsingTracingContextUtilsWithSpanAndMake testing.waitAndAssertTraces( trace -> trace.hasSpansSatisfyingExactly( - span0 -> span0.hasName("parent").hasNoParent(), - span1 -> span1.hasName("test").hasParent(trace.getSpan(0)))); + span -> span.hasName("parent").hasNoParent().hasTotalAttributeCount(0), + span -> + span.hasName("test").hasParent(trace.getSpan(0)).hasTotalAttributeCount(0))); } @Test @DisplayName("capture span with explicit parent") - public void captureSpanWithExplicitParent() { + void captureSpanWithExplicitParent() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span parentSpan = tracer.spanBuilder("parent").startSpan(); @@ -155,13 +152,14 @@ public void captureSpanWithExplicitParent() { testing.waitAndAssertTraces( trace -> trace.hasSpansSatisfyingExactly( - span0 -> span0.hasName("parent").hasNoParent(), - span1 -> span1.hasName("test").hasParent(trace.getSpan(0)))); + span -> span.hasName("parent").hasNoParent().hasTotalAttributeCount(0), + span -> + span.hasName("test").hasParent(trace.getSpan(0)).hasTotalAttributeCount(0))); } @Test @DisplayName("capture span with explicit no parent") - public void captureSpanWithExplicitNoParent() { + void captureSpanWithExplicitNoParent() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span parentSpan = tracer.spanBuilder("parent").startSpan(); @@ -174,13 +172,17 @@ public void captureSpanWithExplicitNoParent() { // Then testing.waitAndAssertSortedTraces( orderByRootSpanName("parent", "test"), - trace0 -> trace0.hasSpansSatisfyingExactly(span -> span.hasName("parent").hasNoParent()), - trace1 -> trace1.hasSpansSatisfyingExactly(span -> span.hasName("test").hasNoParent())); + trace0 -> + trace0.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasNoParent().hasTotalAttributeCount(0)), + trace1 -> + trace1.hasSpansSatisfyingExactly( + span -> span.hasName("test").hasNoParent().hasTotalAttributeCount(0))); } @Test @DisplayName("capture name update") - public void captureNameUpdate() { + void captureNameUpdate() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -189,12 +191,14 @@ public void captureNameUpdate() { // Then testing.waitAndAssertTraces( - trace -> trace.hasSpansSatisfyingExactly(span -> span.hasName("test2").hasNoParent())); + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("test2").hasNoParent().hasTotalAttributeCount(0))); } @Test @DisplayName("capture exception()") - public void captureException() { + void captureException() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -211,6 +215,7 @@ public void captureException() { trace.hasSpansSatisfyingExactly( span -> span.hasName("test") + .hasTotalAttributeCount(0) .hasEventsSatisfyingExactly( event -> event @@ -226,7 +231,7 @@ public void captureException() { @Test @DisplayName("capture exception with Attributes()") - public void captureExceptionWithAttributes() { + void captureExceptionWithAttributes() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -243,6 +248,7 @@ public void captureExceptionWithAttributes() { trace.hasSpansSatisfyingExactly( span -> span.hasName("test") + .hasTotalAttributeCount(0) .hasEventsSatisfyingExactly( event -> event @@ -259,7 +265,7 @@ public void captureExceptionWithAttributes() { @Test @DisplayName("capture name update using TracingContextUtils.getCurrentSpan()") - public void captureNameUpdateUsingTracingContextUtilsGetCurrentSpan() { + void captureNameUpdateUsingTracingContextUtilsGetCurrentSpan() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -270,12 +276,14 @@ public void captureNameUpdateUsingTracingContextUtilsGetCurrentSpan() { // Then testing.waitAndAssertTraces( - trace -> trace.hasSpansSatisfyingExactly(span -> span.hasName("test2").hasNoParent())); + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("test2").hasNoParent().hasTotalAttributeCount(0))); } @Test @DisplayName("capture name update using TracingContextUtils.Span.fromContext(Context.current())") - public void captureNameUpdateUsingTracingContextUtilsSpanFromContextCurrent() { + void captureNameUpdateUsingTracingContextUtilsSpanFromContextCurrent() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); Span testSpan = tracer.spanBuilder("test").startSpan(); @@ -286,12 +294,14 @@ public void captureNameUpdateUsingTracingContextUtilsSpanFromContextCurrent() { // Then testing.waitAndAssertTraces( - trace -> trace.hasSpansSatisfyingExactly(span -> span.hasName("test2").hasNoParent())); + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("test2").hasNoParent().hasTotalAttributeCount(0))); } @Test @DisplayName("add wrapped span to context") - public void addWrappedSpanToContext() { + void addWrappedSpanToContext() { // When // Lazy way to get a span context Tracer tracer = GlobalOpenTelemetry.getTracer("test"); @@ -302,13 +312,14 @@ public void addWrappedSpanToContext() { Context context = Context.current().with(span); // Then - assertEquals( - span.getSpanContext().getSpanId(), Span.fromContext(context).getSpanContext().getSpanId()); + assertThat(Span.fromContext(context).getSpanContext().getSpanId()) + .isEqualTo(span.getSpanContext().getSpanId()); } + // this test uses opentelemetry-api-1.4 instrumentation @Test @DisplayName("test tracer builder") - public void testTracerBuilder() { + void testTracerBuilder() { // When Tracer tracer = GlobalOpenTelemetry.get().tracerBuilder("test").setInstrumentationVersion("1.2.3").build(); @@ -323,6 +334,7 @@ public void testTracerBuilder() { span.hasName("test") .hasKind(PRODUCER) .hasNoParent() + .hasTotalAttributeCount(0) .hasInstrumentationScopeInfo( InstrumentationScopeInfo.builder("test").setVersion("1.2.3").build()))); } From de04249cac9efb6cf5941bc1c8f4c8f79dc13972 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Mon, 2 Sep 2024 22:30:40 +0800 Subject: [PATCH 3/4] 1. Remove the () from the @DisplayName 2. Remove @ExtendWith(AgentInstrumentationExtension.class) 3. Rename trace0 and trace1 to trace 4. Use hasException instead of hasEventsSatisfyingExactly --- .../opentelemetryapi/ContextTest.java | 3 --- .../opentelemetryapi/TracerTest.java | 25 +++++-------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java index 43278ba71469..6f90fd3bffea 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextTest.java @@ -12,12 +12,9 @@ import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -@ExtendWith(AgentInstrumentationExtension.class) class ContextTest { @Test diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java index 74bd761769ff..357627307312 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java @@ -172,11 +172,11 @@ void captureSpanWithExplicitNoParent() { // Then testing.waitAndAssertSortedTraces( orderByRootSpanName("parent", "test"), - trace0 -> - trace0.hasSpansSatisfyingExactly( + trace -> + trace.hasSpansSatisfyingExactly( span -> span.hasName("parent").hasNoParent().hasTotalAttributeCount(0)), - trace1 -> - trace1.hasSpansSatisfyingExactly( + trace -> + trace.hasSpansSatisfyingExactly( span -> span.hasName("test").hasNoParent().hasTotalAttributeCount(0))); } @@ -197,7 +197,7 @@ void captureNameUpdate() { } @Test - @DisplayName("capture exception()") + @DisplayName("capture exception") void captureException() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test"); @@ -213,20 +213,7 @@ void captureException() { testing.waitAndAssertTraces( trace -> trace.hasSpansSatisfyingExactly( - span -> - span.hasName("test") - .hasTotalAttributeCount(0) - .hasEventsSatisfyingExactly( - event -> - event - .hasName("exception") - .hasAttributesSatisfyingExactly( - equalTo( - ExceptionAttributes.EXCEPTION_TYPE, - "java.lang.IllegalStateException"), - equalTo( - ExceptionAttributes.EXCEPTION_STACKTRACE, - writer.toString()))))); + span -> span.hasName("test").hasTotalAttributeCount(0).hasException(throwable))); } @Test From 8a8d83740f1598ba62080a8e3c3944bb79786e73 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 3 Sep 2024 12:37:22 +0300 Subject: [PATCH 4/4] Update instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java --- .../javaagent/instrumentation/opentelemetryapi/TracerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java index 357627307312..404d47131fa6 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java @@ -217,7 +217,7 @@ void captureException() { } @Test - @DisplayName("capture exception with Attributes()") + @DisplayName("capture exception with Attributes") void captureExceptionWithAttributes() { // When Tracer tracer = GlobalOpenTelemetry.getTracer("test");