Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert InstrumentationTestRunner from interface to abstract class #5112

Merged
merged 1 commit into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -37,10 +36,8 @@ public static InstrumentationTestRunner instance() {
return INSTANCE;
}

private final TestInstrumenters testInstrumenters;

private AgentTestRunner() {
testInstrumenters = new TestInstrumenters(getOpenTelemetry());
super(GlobalOpenTelemetry.get());
}

@Override
Expand Down Expand Up @@ -95,28 +92,4 @@ public List<LogData> getExportedLogs() {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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<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);
Expand All @@ -61,34 +69,37 @@ default List<List<SpanData>> waitForTraces(int numberOfTraces) {
}
}

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,
Expand All @@ -102,13 +113,16 @@ default <E extends Exception> void runWithSpan(String spanName, ThrowingRunnable
* 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,
Expand All @@ -122,14 +136,16 @@ default <E extends Throwable> void runWithClientSpan(
* 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,
Expand All @@ -143,9 +159,14 @@ default <E extends Throwable> void runWithServerSpan(
* 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -72,10 +71,8 @@ public static LibraryTestRunner instance() {
return INSTANCE;
}

private final TestInstrumenters testInstrumenters;

private LibraryTestRunner() {
testInstrumenters = new TestInstrumenters(openTelemetry);
super(openTelemetry);
}

@Override
Expand Down Expand Up @@ -127,30 +124,6 @@ public boolean forceFlushCalled() {
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) {}
Expand Down