Merge Java TraceUtils into extension and switch to Instrumenter API. (#3532)
* Merge Java TraceUtils into extension and switch to Instrumenter API. * Woah
This commit is contained in:
parent
9be9e40556
commit
f601863d12
|
@ -96,11 +96,11 @@ afterEvaluate {
|
||||||
|
|
||||||
// If agent depends on some shared instrumentation module that is not a testing module, it will
|
// If agent depends on some shared instrumentation module that is not a testing module, it will
|
||||||
// be packaged into the testing jar so we need to make sure to exclude from the test classpath.
|
// be packaged into the testing jar so we need to make sure to exclude from the test classpath.
|
||||||
val libPath = it.absolutePath
|
val lib = it.absoluteFile
|
||||||
val instrumentationPath = file("${rootDir}/instrumentation/").absolutePath
|
val instrumentationDir = file("${rootDir}/instrumentation/").absoluteFile
|
||||||
if (libPath.startsWith(instrumentationPath) &&
|
if (lib.startsWith(instrumentationDir) &&
|
||||||
libPath.endsWith(".jar") &&
|
lib.extension == "jar" &&
|
||||||
!libPath.substring(instrumentationPath.length).contains("testing")) {
|
!lib.absolutePath.substring(instrumentationDir.absolutePath.length).contains("testing")) {
|
||||||
return@filter false
|
return@filter false
|
||||||
}
|
}
|
||||||
return@filter true
|
return@filter true
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.testing.util.TraceUtils.withClientSpan;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import com.amazonaws.DefaultRequest;
|
import com.amazonaws.DefaultRequest;
|
||||||
|
@ -12,12 +11,14 @@ import com.amazonaws.Response;
|
||||||
import com.amazonaws.http.HttpResponse;
|
import com.amazonaws.http.HttpResponse;
|
||||||
import com.amazonaws.services.sqs.model.SendMessageRequest;
|
import com.amazonaws.services.sqs.model.SendMessageRequest;
|
||||||
import com.amazonaws.services.sqs.model.SendMessageResult;
|
import com.amazonaws.services.sqs.model.SendMessageResult;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
|
||||||
import io.opentelemetry.javaagent.instrumentation.awssdk.v1_11.TracingRequestHandler;
|
import io.opentelemetry.javaagent.instrumentation.awssdk.v1_11.TracingRequestHandler;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
public class TracingRequestHandlerTest {
|
class TracingRequestHandlerTest {
|
||||||
|
|
||||||
private static Response<SendMessageResult> response(Request request) {
|
private static Response<SendMessageResult> response(Request request) {
|
||||||
return new Response<>(new SendMessageResult(), new HttpResponse(request, new HttpGet()));
|
return new Response<>(new SendMessageResult(), new HttpResponse(request, new HttpGet()));
|
||||||
|
@ -29,13 +30,16 @@ public class TracingRequestHandlerTest {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final LibraryInstrumentationExtension testing = LibraryInstrumentationExtension.create();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotSetScopeAndNotFailIfClientSpanAlreadyPresent() {
|
void shouldNotSetScopeAndNotFailIfClientSpanAlreadyPresent() {
|
||||||
// given
|
// given
|
||||||
TracingRequestHandler underTest = new TracingRequestHandler();
|
TracingRequestHandler underTest = new TracingRequestHandler();
|
||||||
Request<SendMessageRequest> request = request();
|
Request<SendMessageRequest> request = request();
|
||||||
|
|
||||||
withClientSpan(
|
testing.runWithClientSpan(
|
||||||
"test",
|
"test",
|
||||||
() -> {
|
() -> {
|
||||||
// when
|
// when
|
||||||
|
@ -47,7 +51,7 @@ public class TracingRequestHandlerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldSetScopeIfClientSpanNotPresent() {
|
void shouldSetScopeIfClientSpanNotPresent() {
|
||||||
// given
|
// given
|
||||||
TracingRequestHandler underTest = new TracingRequestHandler();
|
TracingRequestHandler underTest = new TracingRequestHandler();
|
||||||
Request<SendMessageRequest> request = request();
|
Request<SendMessageRequest> request = request();
|
||||||
|
|
|
@ -8,9 +8,6 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.aspects;
|
||||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
|
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
|
||||||
import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
|
import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
|
||||||
import static io.opentelemetry.api.trace.SpanKind.SERVER;
|
import static io.opentelemetry.api.trace.SpanKind.SERVER;
|
||||||
import static io.opentelemetry.instrumentation.testing.util.TraceUtils.withClientSpan;
|
|
||||||
import static io.opentelemetry.instrumentation.testing.util.TraceUtils.withServerSpan;
|
|
||||||
import static io.opentelemetry.instrumentation.testing.util.TraceUtils.withSpan;
|
|
||||||
import static io.opentelemetry.sdk.testing.assertj.TracesAssert.assertThat;
|
import static io.opentelemetry.sdk.testing.assertj.TracesAssert.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
@ -34,8 +31,7 @@ import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
|
||||||
/** Spring AOP Test for {@link WithSpanAspect}. */
|
/** Spring AOP Test for {@link WithSpanAspect}. */
|
||||||
public class WithSpanAspectTest {
|
public class WithSpanAspectTest {
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
static final LibraryInstrumentationExtension instrumentation =
|
static final LibraryInstrumentationExtension testing = LibraryInstrumentationExtension.create();
|
||||||
LibraryInstrumentationExtension.create();
|
|
||||||
|
|
||||||
static class WithSpanTester {
|
static class WithSpanTester {
|
||||||
@WithSpan
|
@WithSpan
|
||||||
|
@ -79,7 +75,7 @@ public class WithSpanAspectTest {
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
AspectJProxyFactory factory = new AspectJProxyFactory(new WithSpanTester());
|
AspectJProxyFactory factory = new AspectJProxyFactory(new WithSpanTester());
|
||||||
WithSpanAspect aspect = new WithSpanAspect(instrumentation.getOpenTelemetry());
|
WithSpanAspect aspect = new WithSpanAspect(testing.getOpenTelemetry());
|
||||||
factory.addAspect(aspect);
|
factory.addAspect(aspect);
|
||||||
|
|
||||||
withSpanTester = factory.getProxy();
|
withSpanTester = factory.getProxy();
|
||||||
|
@ -94,10 +90,10 @@ public class WithSpanAspectTest {
|
||||||
@DisplayName("when method is annotated with @WithSpan should wrap method execution in a Span")
|
@DisplayName("when method is annotated with @WithSpan should wrap method execution in a Span")
|
||||||
void withSpanWithDefaults() throws Throwable {
|
void withSpanWithDefaults() throws Throwable {
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testWithSpan());
|
testing.runWithSpan("parent", withSpanTester::testWithSpan);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -116,10 +112,10 @@ public class WithSpanAspectTest {
|
||||||
"when @WithSpan value is set should wrap method execution in a Span with custom name")
|
"when @WithSpan value is set should wrap method execution in a Span with custom name")
|
||||||
void withSpanName() throws Throwable {
|
void withSpanName() throws Throwable {
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testWithSpanWithValue());
|
testing.runWithSpan("parent", () -> withSpanTester.testWithSpanWithValue());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -138,7 +134,7 @@ public class WithSpanAspectTest {
|
||||||
assertThatThrownBy(() -> withSpanTester.testWithSpanWithException())
|
assertThatThrownBy(() -> withSpanTester.testWithSpanWithException())
|
||||||
.isInstanceOf(Exception.class);
|
.isInstanceOf(Exception.class);
|
||||||
|
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -154,10 +150,10 @@ public class WithSpanAspectTest {
|
||||||
"when method is annotated with @WithSpan(kind=CLIENT) should build span with the declared SpanKind")
|
"when method is annotated with @WithSpan(kind=CLIENT) should build span with the declared SpanKind")
|
||||||
void withSpanKind() throws Throwable {
|
void withSpanKind() throws Throwable {
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testWithClientSpan());
|
testing.runWithSpan("parent", () -> withSpanTester.testWithClientSpan());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -174,10 +170,10 @@ public class WithSpanAspectTest {
|
||||||
"when method is annotated with @WithSpan(kind=CLIENT) and context already contains a CLIENT span should suppress span")
|
"when method is annotated with @WithSpan(kind=CLIENT) and context already contains a CLIENT span should suppress span")
|
||||||
void suppressClientSpan() throws Throwable {
|
void suppressClientSpan() throws Throwable {
|
||||||
// when
|
// when
|
||||||
withClientSpan("parent", () -> withSpanTester.testWithClientSpan());
|
testing.runWithClientSpan("parent", withSpanTester::testWithClientSpan);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -190,10 +186,10 @@ public class WithSpanAspectTest {
|
||||||
"when method is annotated with @WithSpan(kind=SERVER) and context already contains a SERVER span should suppress span")
|
"when method is annotated with @WithSpan(kind=SERVER) and context already contains a SERVER span should suppress span")
|
||||||
void suppressServerSpan() throws Throwable {
|
void suppressServerSpan() throws Throwable {
|
||||||
// when
|
// when
|
||||||
withServerSpan("parent", () -> withSpanTester.testWithServerSpan());
|
testing.runWithServerSpan("parent", withSpanTester::testWithServerSpan);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -211,10 +207,10 @@ public class WithSpanAspectTest {
|
||||||
CompletableFuture<String> future = new CompletableFuture<>();
|
CompletableFuture<String> future = new CompletableFuture<>();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletionStage(future));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletionStage(future));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(instrumentation.waitForTraces(1))
|
assertThat(testing.waitForTraces(1))
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
trace
|
trace
|
||||||
|
@ -225,7 +221,7 @@ public class WithSpanAspectTest {
|
||||||
future.complete("DONE");
|
future.complete("DONE");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -243,10 +239,10 @@ public class WithSpanAspectTest {
|
||||||
CompletableFuture<String> future = new CompletableFuture<>();
|
CompletableFuture<String> future = new CompletableFuture<>();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletionStage(future));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletionStage(future));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(instrumentation.waitForTraces(1))
|
assertThat(testing.waitForTraces(1))
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
trace
|
trace
|
||||||
|
@ -257,7 +253,7 @@ public class WithSpanAspectTest {
|
||||||
future.completeExceptionally(new Exception("Test @WithSpan With completeExceptionally"));
|
future.completeExceptionally(new Exception("Test @WithSpan With completeExceptionally"));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -274,10 +270,10 @@ public class WithSpanAspectTest {
|
||||||
@DisplayName("should end Span on incompatible return value")
|
@DisplayName("should end Span on incompatible return value")
|
||||||
void onIncompatibleReturnValue() throws Throwable {
|
void onIncompatibleReturnValue() throws Throwable {
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletionStage(null));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletionStage(null));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -300,10 +296,10 @@ public class WithSpanAspectTest {
|
||||||
CompletableFuture<String> future = new CompletableFuture<>();
|
CompletableFuture<String> future = new CompletableFuture<>();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(instrumentation.waitForTraces(1))
|
assertThat(testing.waitForTraces(1))
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
trace
|
trace
|
||||||
|
@ -314,7 +310,7 @@ public class WithSpanAspectTest {
|
||||||
future.complete("DONE");
|
future.complete("DONE");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -332,10 +328,10 @@ public class WithSpanAspectTest {
|
||||||
CompletableFuture<String> future = new CompletableFuture<>();
|
CompletableFuture<String> future = new CompletableFuture<>();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(instrumentation.waitForTraces(1))
|
assertThat(testing.waitForTraces(1))
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
trace
|
trace
|
||||||
|
@ -346,7 +342,7 @@ public class WithSpanAspectTest {
|
||||||
future.completeExceptionally(new Exception("Test @WithSpan With completeExceptionally"));
|
future.completeExceptionally(new Exception("Test @WithSpan With completeExceptionally"));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -365,10 +361,10 @@ public class WithSpanAspectTest {
|
||||||
CompletableFuture<String> future = CompletableFuture.completedFuture("Done");
|
CompletableFuture<String> future = CompletableFuture.completedFuture("Done");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -387,10 +383,10 @@ public class WithSpanAspectTest {
|
||||||
future.completeExceptionally(new Exception("Test @WithSpan With completeExceptionally"));
|
future.completeExceptionally(new Exception("Test @WithSpan With completeExceptionally"));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(future));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
@ -407,10 +403,10 @@ public class WithSpanAspectTest {
|
||||||
@DisplayName("should end Span on incompatible return value")
|
@DisplayName("should end Span on incompatible return value")
|
||||||
void onIncompatibleReturnValue() throws Throwable {
|
void onIncompatibleReturnValue() throws Throwable {
|
||||||
// when
|
// when
|
||||||
withSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(null));
|
testing.runWithSpan("parent", () -> withSpanTester.testAsyncCompletableFuture(null));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
List<List<SpanData>> traces = instrumentation.waitForTraces(1);
|
List<List<SpanData>> traces = testing.waitForTraces(1);
|
||||||
assertThat(traces)
|
assertThat(traces)
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.spring.httpclients;
|
package io.opentelemetry.instrumentation.spring.httpclients;
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.testing.util.TraceUtils.withClientSpan;
|
|
||||||
import static io.opentelemetry.sdk.testing.assertj.TracesAssert.assertThat;
|
import static io.opentelemetry.sdk.testing.assertj.TracesAssert.assertThat;
|
||||||
import static org.mockito.BDDMockito.then;
|
import static org.mockito.BDDMockito.then;
|
||||||
|
|
||||||
|
@ -22,8 +21,7 @@ import org.springframework.http.client.ClientHttpRequestExecution;
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class RestTemplateInterceptorTest {
|
class RestTemplateInterceptorTest {
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
static final LibraryInstrumentationExtension instrumentation =
|
static final LibraryInstrumentationExtension testing = LibraryInstrumentationExtension.create();
|
||||||
LibraryInstrumentationExtension.create();
|
|
||||||
|
|
||||||
@Mock HttpRequest httpRequestMock;
|
@Mock HttpRequest httpRequestMock;
|
||||||
@Mock ClientHttpRequestExecution requestExecutionMock;
|
@Mock ClientHttpRequestExecution requestExecutionMock;
|
||||||
|
@ -32,11 +30,10 @@ class RestTemplateInterceptorTest {
|
||||||
@Test
|
@Test
|
||||||
void shouldSkipWhenContextHasClientSpan() throws Exception {
|
void shouldSkipWhenContextHasClientSpan() throws Exception {
|
||||||
// given
|
// given
|
||||||
RestTemplateInterceptor interceptor =
|
RestTemplateInterceptor interceptor = new RestTemplateInterceptor(testing.getOpenTelemetry());
|
||||||
new RestTemplateInterceptor(instrumentation.getOpenTelemetry());
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
withClientSpan(
|
testing.runWithClientSpan(
|
||||||
"parent",
|
"parent",
|
||||||
() -> {
|
() -> {
|
||||||
interceptor.intercept(httpRequestMock, requestBody, requestExecutionMock);
|
interceptor.intercept(httpRequestMock, requestBody, requestExecutionMock);
|
||||||
|
@ -45,7 +42,7 @@ class RestTemplateInterceptorTest {
|
||||||
// then
|
// then
|
||||||
then(requestExecutionMock).should().execute(httpRequestMock, requestBody);
|
then(requestExecutionMock).should().execute(httpRequestMock, requestBody);
|
||||||
|
|
||||||
assertThat(instrumentation.waitForTraces(1))
|
assertThat(testing.waitForTraces(1))
|
||||||
.hasTracesSatisfyingExactly(
|
.hasTracesSatisfyingExactly(
|
||||||
trace ->
|
trace ->
|
||||||
trace.hasSpansSatisfyingExactly(
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
|
|
@ -6,9 +6,15 @@
|
||||||
package io.opentelemetry.instrumentation.testing.junit;
|
package io.opentelemetry.instrumentation.testing.junit;
|
||||||
|
|
||||||
import io.opentelemetry.api.OpenTelemetry;
|
import io.opentelemetry.api.OpenTelemetry;
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.context.ContextStorage;
|
import io.opentelemetry.context.ContextStorage;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||||
import io.opentelemetry.instrumentation.testing.InstrumentationTestRunner;
|
import io.opentelemetry.instrumentation.testing.InstrumentationTestRunner;
|
||||||
import io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil;
|
import io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil;
|
||||||
|
import io.opentelemetry.instrumentation.testing.util.ThrowingRunnable;
|
||||||
|
import io.opentelemetry.instrumentation.testing.util.ThrowingSupplier;
|
||||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||||
import io.opentelemetry.sdk.trace.data.SpanData;
|
import io.opentelemetry.sdk.trace.data.SpanData;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -26,8 +32,21 @@ public abstract class InstrumentationExtension
|
||||||
|
|
||||||
private final InstrumentationTestRunner testRunner;
|
private final InstrumentationTestRunner testRunner;
|
||||||
|
|
||||||
|
private final Instrumenter<String, Void> testInstrumenter;
|
||||||
|
private final Instrumenter<String, Void> testClientInstrumenter;
|
||||||
|
private final Instrumenter<String, Void> testServerInstrumenter;
|
||||||
|
|
||||||
protected InstrumentationExtension(InstrumentationTestRunner testRunner) {
|
protected InstrumentationExtension(InstrumentationTestRunner testRunner) {
|
||||||
this.testRunner = testRunner;
|
this.testRunner = testRunner;
|
||||||
|
testInstrumenter =
|
||||||
|
Instrumenter.<String, Void>newBuilder(testRunner.getOpenTelemetry(), "test", name -> name)
|
||||||
|
.newInstrumenter(SpanKindExtractor.alwaysInternal());
|
||||||
|
testClientInstrumenter =
|
||||||
|
Instrumenter.<String, Void>newBuilder(testRunner.getOpenTelemetry(), "test", name -> name)
|
||||||
|
.newInstrumenter(SpanKindExtractor.alwaysClient());
|
||||||
|
testServerInstrumenter =
|
||||||
|
Instrumenter.<String, Void>newBuilder(testRunner.getOpenTelemetry(), "test", name -> name)
|
||||||
|
.newInstrumenter(SpanKindExtractor.alwaysServer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,4 +125,88 @@ public abstract class InstrumentationExtension
|
||||||
throws TimeoutException, InterruptedException {
|
throws TimeoutException, InterruptedException {
|
||||||
return TelemetryDataUtil.waitForTraces(this::spans, numberOfTraces, timeout, unit);
|
return TelemetryDataUtil.waitForTraces(this::spans, numberOfTraces, timeout, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the provided {@code callback} inside the scope of an INTERNAL span with name {@code
|
||||||
|
* spanName}.
|
||||||
|
*/
|
||||||
|
public <E extends Exception> void runWithSpan(String spanName, ThrowingRunnable<E> callback)
|
||||||
|
throws E {
|
||||||
|
runWithSpan(
|
||||||
|
spanName,
|
||||||
|
() -> {
|
||||||
|
callback.run();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the provided {@code callback} inside the scope of an INTERNAL span with name {@code
|
||||||
|
* spanName}.
|
||||||
|
*/
|
||||||
|
public <T, E extends Throwable> T runWithSpan(String spanName, ThrowingSupplier<T, E> callback)
|
||||||
|
throws E {
|
||||||
|
return runWithInstrumenter(spanName, testInstrumenter, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code
|
||||||
|
* spanName}.
|
||||||
|
*/
|
||||||
|
public <E extends Throwable> void runWithClientSpan(String spanName, ThrowingRunnable<E> callback)
|
||||||
|
throws E {
|
||||||
|
runWithClientSpan(
|
||||||
|
spanName,
|
||||||
|
() -> {
|
||||||
|
callback.run();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code
|
||||||
|
* spanName}.
|
||||||
|
*/
|
||||||
|
public <T, E extends Throwable> T runWithClientSpan(
|
||||||
|
String spanName, ThrowingSupplier<T, E> callback) throws E {
|
||||||
|
return runWithInstrumenter(spanName, testClientInstrumenter, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code
|
||||||
|
* spanName}.
|
||||||
|
*/
|
||||||
|
public <E extends Throwable> void runWithServerSpan(String spanName, ThrowingRunnable<E> callback)
|
||||||
|
throws E {
|
||||||
|
runWithServerSpan(
|
||||||
|
spanName,
|
||||||
|
() -> {
|
||||||
|
callback.run();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code
|
||||||
|
* spanName}.
|
||||||
|
*/
|
||||||
|
public <T, E extends Throwable> T runWithServerSpan(
|
||||||
|
String spanName, ThrowingSupplier<T, E> callback) throws E {
|
||||||
|
return runWithInstrumenter(spanName, testServerInstrumenter, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T, E extends Throwable> T runWithInstrumenter(
|
||||||
|
String spanName, Instrumenter<String, Void> instrumenter, ThrowingSupplier<T, E> callback)
|
||||||
|
throws E {
|
||||||
|
Context context = instrumenter.start(Context.current(), spanName);
|
||||||
|
Throwable err = null;
|
||||||
|
try (Scope ignored = context.makeCurrent()) {
|
||||||
|
return callback.get();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
err = t;
|
||||||
|
throw t;
|
||||||
|
} finally {
|
||||||
|
instrumenter.end(context, spanName, null, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.testing.util;
|
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
|
||||||
import io.opentelemetry.api.trace.SpanKind;
|
|
||||||
import io.opentelemetry.context.Context;
|
|
||||||
import io.opentelemetry.context.Scope;
|
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
|
||||||
|
|
||||||
/** Utility class for creating spans in tests. */
|
|
||||||
public final class TraceUtils {
|
|
||||||
|
|
||||||
private static final TestTracer TRACER = new TestTracer();
|
|
||||||
|
|
||||||
public static <E extends Exception> void withSpan(String spanName, ThrowingRunnable<E> callback)
|
|
||||||
throws E {
|
|
||||||
withSpan(
|
|
||||||
spanName,
|
|
||||||
() -> {
|
|
||||||
callback.run();
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, E extends Throwable> T withSpan(
|
|
||||||
String spanName, ThrowingSupplier<T, E> callback) throws E {
|
|
||||||
Context context = TRACER.startSpan(spanName);
|
|
||||||
try (Scope ignored = context.makeCurrent()) {
|
|
||||||
T result = callback.get();
|
|
||||||
TRACER.end(context);
|
|
||||||
return result;
|
|
||||||
} catch (Throwable t) {
|
|
||||||
TRACER.endExceptionally(context, t);
|
|
||||||
throw t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <E extends Throwable> void withClientSpan(
|
|
||||||
String spanName, ThrowingRunnable<E> callback) throws E {
|
|
||||||
withClientSpan(
|
|
||||||
spanName,
|
|
||||||
() -> {
|
|
||||||
callback.run();
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, E extends Throwable> T withClientSpan(
|
|
||||||
String spanName, ThrowingSupplier<T, E> callback) throws E {
|
|
||||||
Context context = TRACER.startClientSpan(spanName);
|
|
||||||
try (Scope ignored = context.makeCurrent()) {
|
|
||||||
T result = callback.get();
|
|
||||||
TRACER.end(context);
|
|
||||||
return result;
|
|
||||||
} catch (Throwable t) {
|
|
||||||
TRACER.endExceptionally(context, t);
|
|
||||||
throw t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <E extends Throwable> void withServerSpan(
|
|
||||||
String spanName, ThrowingRunnable<E> callback) throws E {
|
|
||||||
withServerSpan(
|
|
||||||
spanName,
|
|
||||||
() -> {
|
|
||||||
callback.run();
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, E extends Throwable> T withServerSpan(
|
|
||||||
String spanName, ThrowingSupplier<T, E> callback) throws E {
|
|
||||||
Context context = TRACER.startServerSpan(spanName);
|
|
||||||
try (Scope ignored = context.makeCurrent()) {
|
|
||||||
T result = callback.get();
|
|
||||||
TRACER.end(context);
|
|
||||||
return result;
|
|
||||||
} catch (Throwable t) {
|
|
||||||
TRACER.endExceptionally(context, t);
|
|
||||||
throw t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class TestTracer extends BaseTracer {
|
|
||||||
@Override
|
|
||||||
protected String getInstrumentationName() {
|
|
||||||
return "test";
|
|
||||||
}
|
|
||||||
|
|
||||||
Context startClientSpan(String name) {
|
|
||||||
Context parentContext = Context.current();
|
|
||||||
Span span = spanBuilder(parentContext, name, SpanKind.CLIENT).startSpan();
|
|
||||||
return withClientSpan(parentContext, span);
|
|
||||||
}
|
|
||||||
|
|
||||||
Context startServerSpan(String name) {
|
|
||||||
Context parentContext = Context.current();
|
|
||||||
Span span = spanBuilder(parentContext, name, SpanKind.SERVER).startSpan();
|
|
||||||
return withServerSpan(parentContext, span);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TraceUtils() {}
|
|
||||||
}
|
|
Loading…
Reference in New Issue