Skip to content

Commit

Permalink
Convert InstrumentationTestRunner from interface to abstract class (o…
Browse files Browse the repository at this point in the history
  • Loading branch information
anuraaga authored and RashmiRam committed May 23, 2022
1 parent d24f227 commit 95cb34b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 89 deletions.
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

0 comments on commit 95cb34b

Please sign in to comment.