Convert InstrumentationTestRunner from interface to abstract class
MODIFY
testing-common/src/main/java/io/opentelemetry/instrumentation/testing/AgentTestRunner.java
testing-common/src/main/java/io/opentelemetry/instrumentation/testing/AgentTestRunner.java
@@ -10,7 +10,6 @@ import ch.qos.logback.classic.Logger;
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 @@ import org.slf4j.LoggerFactory;
* 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 final class AgentTestRunner implements InstrumentationTestRunner {
return INSTANCE;
}
- private final TestInstrumenters testInstrumenters;
-
private AgentTestRunner() {
- testInstrumenters = new TestInstrumenters(getOpenTelemetry());
+ super(GlobalOpenTelemetry.get());
}
@Override
@@ -95,28 +92,4 @@ public final class AgentTestRunner implements InstrumentationTestRunner {
public boolean forceFlushCalled() {
return AgentTestingExporterAccess.forceFlushCalled();
}
-
- @Override
- public <T, E extends Throwable> T runWithSpan(String spanName, ThrowingSupplier<T, E> callback)
- throws E {
- return testInstrumenters.runWithSpan(spanName, callback);
- }
-
- @Override
- public <T, E extends Throwable> T runWithClientSpan(
- String spanName, ThrowingSupplier<T, E> callback) throws E {
- return testInstrumenters.runWithClientSpan(spanName, callback);
- }
-
- @Override
- public <T, E extends Throwable> T runWithServerSpan(
- String spanName, ThrowingSupplier<T, E> callback) throws E {
- return testInstrumenters.runWithServerSpan(spanName, callback);
- }
-
- @Override
- public <T, E extends Throwable> T runWithNonRecordingSpan(ThrowingSupplier<T, E> callback)
- throws E {
- return testInstrumenters.runWithNonRecordingSpan(callback);
- }
}

MODIFY
testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java
testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java
@@ -16,11 +16,12 @@ import io.opentelemetry.sdk.metrics.data.MetricData;
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 @@ import org.awaitility.core.ConditionTimeoutException;
* @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<SpanData> getExportedSpans();
+ public abstract List<SpanData> getExportedSpans();
- List<MetricData> getExportedMetrics();
+ public abstract List<MetricData> getExportedMetrics();
- List<LogData> getExportedLogs();
+ public abstract List<LogData> 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<List<SpanData>> traces() {
+ public final List<List<SpanData>> traces() {
return TelemetryDataUtil.groupTraces(getExportedSpans());
}
- default List<List<SpanData>> waitForTraces(int numberOfTraces) {
+ public final List<List<SpanData>> waitForTraces(int numberOfTraces) {
try {
return TelemetryDataUtil.waitForTraces(
this::getExportedSpans, numberOfTraces, 20, TimeUnit.SECONDS);
@@ -61,34 +69,37 @@ public interface InstrumentationTestRunner {
}
}
- default void waitAndAssertTraces(Consumer<TraceAssert>... assertions) {
+ @SafeVarargs
+ public final void waitAndAssertTraces(Consumer<TraceAssert>... assertions) {
+ waitAndAssertTraces(Arrays.asList(assertions));
+ }
+
+ public final <T extends Consumer<TraceAssert>> void waitAndAssertTraces(Iterable<T> assertions) {
+ List<T> assertionsList = new ArrayList<>();
+ assertions.forEach(assertionsList::add);
+
try {
await()
.untilAsserted(
() -> {
- List<List<SpanData>> traces = waitForTraces(assertions.length);
- TracesAssert.assertThat(traces).hasTracesSatisfyingExactly(assertions);
+ List<List<SpanData>> 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<List<SpanData>> traces = waitForTraces(assertions.length);
- TracesAssert.assertThat(traces).hasTracesSatisfyingExactly(assertions);
+ List<List<SpanData>> traces = waitForTraces(assertionsList.size());
+ TracesAssert.assertThat(traces).hasTracesSatisfyingExactly(assertionsList);
}
}
- default void waitAndAssertTraces(Iterable<? extends Consumer<TraceAssert>> 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 <E extends Exception> void runWithSpan(String spanName, ThrowingRunnable<E> callback)
+ public final <E extends Exception> void runWithSpan(String spanName, ThrowingRunnable<E> callback)
throws E {
runWithSpan(
spanName,
@@ -102,13 +113,16 @@ public interface InstrumentationTestRunner {
* Runs the provided {@code callback} inside the scope of an INTERNAL span with name {@code
* spanName}.
*/
- <T, E extends Throwable> T runWithSpan(String spanName, ThrowingSupplier<T, E> callback) throws E;
+ public final <T, E extends Throwable> T runWithSpan(
+ String spanName, ThrowingSupplier<T, E> 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 <E extends Throwable> void runWithClientSpan(
+ public final <E extends Throwable> void runWithClientSpan(
String spanName, ThrowingRunnable<E> callback) throws E {
runWithClientSpan(
spanName,
@@ -122,14 +136,16 @@ public interface InstrumentationTestRunner {
* Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code
* spanName}.
*/
- <T, E extends Throwable> T runWithClientSpan(String spanName, ThrowingSupplier<T, E> callback)
- throws E;
+ public final <T, E extends Throwable> T runWithClientSpan(
+ String spanName, ThrowingSupplier<T, E> 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 <E extends Throwable> void runWithServerSpan(
+ public final <E extends Throwable> void runWithServerSpan(
String spanName, ThrowingRunnable<E> callback) throws E {
runWithServerSpan(
spanName,
@@ -143,9 +159,14 @@ public interface InstrumentationTestRunner {
* Runs the provided {@code callback} inside the scope of an CLIENT span with name {@code
* spanName}.
*/
- <T, E extends Throwable> T runWithServerSpan(String spanName, ThrowingSupplier<T, E> callback)
- throws E;
+ public final <T, E extends Throwable> T runWithServerSpan(
+ String spanName, ThrowingSupplier<T, E> callback) throws E {
+ return testInstrumenters.runWithServerSpan(spanName, callback);
+ }
/** Runs the provided {@code callback} inside the scope of a non-recording span. */
- <T, E extends Throwable> T runWithNonRecordingSpan(ThrowingSupplier<T, E> callback) throws E;
+ public final <T, E extends Throwable> T runWithNonRecordingSpan(ThrowingSupplier<T, E> callback)
+ throws E {
+ return testInstrumenters.runWithNonRecordingSpan(callback);
+ }
}

MODIFY
testing-common/src/main/java/io/opentelemetry/instrumentation/testing/LibraryTestRunner.java
testing-common/src/main/java/io/opentelemetry/instrumentation/testing/LibraryTestRunner.java
@@ -11,7 +11,6 @@ import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
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 @@ import java.util.List;
* 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 final class LibraryTestRunner implements InstrumentationTestRunner {
return INSTANCE;
}
- private final TestInstrumenters testInstrumenters;
-
private LibraryTestRunner() {
- testInstrumenters = new TestInstrumenters(openTelemetry);
+ super(openTelemetry);
}
@Override
@@ -127,30 +124,6 @@ public final class LibraryTestRunner implements InstrumentationTestRunner {
return forceFlushCalled;
}
- @Override
- public <T, E extends Throwable> T runWithSpan(String spanName, ThrowingSupplier<T, E> callback)
- throws E {
- return testInstrumenters.runWithSpan(spanName, callback);
- }
-
- @Override
- public <T, E extends Throwable> T runWithClientSpan(
- String spanName, ThrowingSupplier<T, E> callback) throws E {
- return testInstrumenters.runWithClientSpan(spanName, callback);
- }
-
- @Override
- public <T, E extends Throwable> T runWithServerSpan(
- String spanName, ThrowingSupplier<T, E> callback) throws E {
- return testInstrumenters.runWithServerSpan(spanName, callback);
- }
-
- @Override
- public <T, E extends Throwable> T runWithNonRecordingSpan(ThrowingSupplier<T, E> callback)
- throws E {
- return testInstrumenters.runWithNonRecordingSpan(callback);
- }
-
private static class FlushTrackingSpanProcessor implements SpanProcessor {
@Override
public void onStart(Context parentContext, ReadWriteSpan span) {}

Convert InstrumentationTestRunner from interface to abstract class (#5112)