diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/AgentTestRunner.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/AgentTestRunner.java index c2eb5806c623..5b9dd20cbc5f 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/AgentTestRunner.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/AgentTestRunner.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.test.utils.LoggerUtils; -import io.opentelemetry.instrumentation.testing.util.ThrowingSupplier; import io.opentelemetry.javaagent.testing.common.AgentTestingExporterAccess; import io.opentelemetry.javaagent.testing.common.TestAgentListenerAccess; import io.opentelemetry.sdk.logs.data.LogData; @@ -25,7 +24,7 @@ * AgentTestingExporterAccess} bridge class to retrieve exported traces and metrics data from the * agent classloader. */ -public final class AgentTestRunner implements InstrumentationTestRunner { +public final class AgentTestRunner extends InstrumentationTestRunner { static { LoggerUtils.setLevel(LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME), Level.WARN); LoggerUtils.setLevel(LoggerFactory.getLogger("io.opentelemetry"), Level.DEBUG); @@ -37,10 +36,8 @@ public static InstrumentationTestRunner instance() { return INSTANCE; } - private final TestInstrumenters testInstrumenters; - private AgentTestRunner() { - testInstrumenters = new TestInstrumenters(getOpenTelemetry()); + super(GlobalOpenTelemetry.get()); } @Override @@ -95,28 +92,4 @@ public List getExportedLogs() { public boolean forceFlushCalled() { return AgentTestingExporterAccess.forceFlushCalled(); } - - @Override - public T runWithSpan(String spanName, ThrowingSupplier callback) - throws E { - return testInstrumenters.runWithSpan(spanName, callback); - } - - @Override - public T runWithClientSpan( - String spanName, ThrowingSupplier callback) throws E { - return testInstrumenters.runWithClientSpan(spanName, callback); - } - - @Override - public T runWithServerSpan( - String spanName, ThrowingSupplier callback) throws E { - return testInstrumenters.runWithServerSpan(spanName, callback); - } - - @Override - public T runWithNonRecordingSpan(ThrowingSupplier callback) - throws E { - return testInstrumenters.runWithNonRecordingSpan(callback); - } } diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java index 0bd22eef6e44..9648b10859f3 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java @@ -16,11 +16,12 @@ import io.opentelemetry.sdk.testing.assertj.TraceAssert; import io.opentelemetry.sdk.testing.assertj.TracesAssert; import io.opentelemetry.sdk.trace.data.SpanData; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; -import java.util.stream.StreamSupport; import org.awaitility.core.ConditionTimeoutException; /** @@ -30,29 +31,36 @@ * @see LibraryTestRunner * @see AgentTestRunner */ -public interface InstrumentationTestRunner { - void beforeTestClass(); +public abstract class InstrumentationTestRunner { - void afterTestClass(); + private final TestInstrumenters testInstrumenters; - void clearAllExportedData(); + protected InstrumentationTestRunner(OpenTelemetry openTelemetry) { + testInstrumenters = new TestInstrumenters(openTelemetry); + } + + public abstract void beforeTestClass(); + + public abstract void afterTestClass(); + + public abstract void clearAllExportedData(); - OpenTelemetry getOpenTelemetry(); + public abstract OpenTelemetry getOpenTelemetry(); - List getExportedSpans(); + public abstract List getExportedSpans(); - List getExportedMetrics(); + public abstract List getExportedMetrics(); - List getExportedLogs(); + public abstract List getExportedLogs(); - boolean forceFlushCalled(); + public abstract boolean forceFlushCalled(); /** Return a list of all captured traces, where each trace is a sorted list of spans. */ - default List> traces() { + public final List> traces() { return TelemetryDataUtil.groupTraces(getExportedSpans()); } - default List> waitForTraces(int numberOfTraces) { + public final List> waitForTraces(int numberOfTraces) { try { return TelemetryDataUtil.waitForTraces( this::getExportedSpans, numberOfTraces, 20, TimeUnit.SECONDS); @@ -61,34 +69,37 @@ default List> waitForTraces(int numberOfTraces) { } } - default void waitAndAssertTraces(Consumer... assertions) { + @SafeVarargs + public final void waitAndAssertTraces(Consumer... assertions) { + waitAndAssertTraces(Arrays.asList(assertions)); + } + + public final > void waitAndAssertTraces(Iterable assertions) { + List assertionsList = new ArrayList<>(); + assertions.forEach(assertionsList::add); + try { await() .untilAsserted( () -> { - List> traces = waitForTraces(assertions.length); - TracesAssert.assertThat(traces).hasTracesSatisfyingExactly(assertions); + List> traces = waitForTraces(assertionsList.size()); + TracesAssert.assertThat(traces).hasTracesSatisfyingExactly(assertionsList); }); } catch (ConditionTimeoutException e) { // Don't throw this failure since the stack is the awaitility thread, causing confusion. // Instead, just assert one more time on the test thread, which will fail with a better stack // trace. // TODO(anuraaga): There is probably a better way to do this. - List> traces = waitForTraces(assertions.length); - TracesAssert.assertThat(traces).hasTracesSatisfyingExactly(assertions); + List> traces = waitForTraces(assertionsList.size()); + TracesAssert.assertThat(traces).hasTracesSatisfyingExactly(assertionsList); } } - default void waitAndAssertTraces(Iterable> assertions) { - waitAndAssertTraces( - StreamSupport.stream(assertions.spliterator(), false).toArray(Consumer[]::new)); - } - /** * Runs the provided {@code callback} inside the scope of an INTERNAL span with name {@code * spanName}. */ - default void runWithSpan(String spanName, ThrowingRunnable callback) + public final void runWithSpan(String spanName, ThrowingRunnable callback) throws E { runWithSpan( spanName, @@ -102,13 +113,16 @@ default void runWithSpan(String spanName, ThrowingRunnable * Runs the provided {@code callback} inside the scope of an INTERNAL span with name {@code * spanName}. */ - T runWithSpan(String spanName, ThrowingSupplier callback) throws E; + public final T runWithSpan( + String spanName, ThrowingSupplier callback) throws E { + return testInstrumenters.runWithSpan(spanName, callback); + } /** * Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code * spanName}. */ - default void runWithClientSpan( + public final void runWithClientSpan( String spanName, ThrowingRunnable callback) throws E { runWithClientSpan( spanName, @@ -122,14 +136,16 @@ default void runWithClientSpan( * Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code * spanName}. */ - T runWithClientSpan(String spanName, ThrowingSupplier callback) - throws E; + public final T runWithClientSpan( + String spanName, ThrowingSupplier callback) throws E { + return testInstrumenters.runWithClientSpan(spanName, callback); + } /** * Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code * spanName}. */ - default void runWithServerSpan( + public final void runWithServerSpan( String spanName, ThrowingRunnable callback) throws E { runWithServerSpan( spanName, @@ -143,9 +159,14 @@ default void runWithServerSpan( * Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code * spanName}. */ - T runWithServerSpan(String spanName, ThrowingSupplier callback) - throws E; + public final T runWithServerSpan( + String spanName, ThrowingSupplier callback) throws E { + return testInstrumenters.runWithServerSpan(spanName, callback); + } /** Runs the provided {@code callback} inside the scope of a non-recording span. */ - T runWithNonRecordingSpan(ThrowingSupplier callback) throws E; + public final T runWithNonRecordingSpan(ThrowingSupplier callback) + throws E { + return testInstrumenters.runWithNonRecordingSpan(callback); + } } diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/LibraryTestRunner.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/LibraryTestRunner.java index 2f1ca9f66e0d..180a5fb0a96a 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/LibraryTestRunner.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/LibraryTestRunner.java @@ -11,7 +11,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.exporter.logging.LoggingSpanExporter; -import io.opentelemetry.instrumentation.testing.util.ThrowingSupplier; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.data.LogData; @@ -34,7 +33,7 @@ * An implementation of {@link InstrumentationTestRunner} that initializes OpenTelemetry SDK and * uses in-memory exporter to collect traces and metrics. */ -public final class LibraryTestRunner implements InstrumentationTestRunner { +public final class LibraryTestRunner extends InstrumentationTestRunner { private static final OpenTelemetrySdk openTelemetry; private static final InMemorySpanExporter testSpanExporter; @@ -72,10 +71,8 @@ public static LibraryTestRunner instance() { return INSTANCE; } - private final TestInstrumenters testInstrumenters; - private LibraryTestRunner() { - testInstrumenters = new TestInstrumenters(openTelemetry); + super(openTelemetry); } @Override @@ -127,30 +124,6 @@ public boolean forceFlushCalled() { return forceFlushCalled; } - @Override - public T runWithSpan(String spanName, ThrowingSupplier callback) - throws E { - return testInstrumenters.runWithSpan(spanName, callback); - } - - @Override - public T runWithClientSpan( - String spanName, ThrowingSupplier callback) throws E { - return testInstrumenters.runWithClientSpan(spanName, callback); - } - - @Override - public T runWithServerSpan( - String spanName, ThrowingSupplier callback) throws E { - return testInstrumenters.runWithServerSpan(spanName, callback); - } - - @Override - public T runWithNonRecordingSpan(ThrowingSupplier callback) - throws E { - return testInstrumenters.runWithNonRecordingSpan(callback); - } - private static class FlushTrackingSpanProcessor implements SpanProcessor { @Override public void onStart(Context parentContext, ReadWriteSpan span) {}