|
5 | 5 |
|
6 | 6 | package io.opentelemetry.instrumentation.testing;
|
7 | 7 |
|
8 |
| -import static io.opentelemetry.instrumentation.testing.internal.AwaitUtil.awaitUntilAsserted; |
9 | 8 | import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
|
| 9 | +import static org.awaitility.Awaitility.await; |
10 | 10 |
|
11 | 11 | import io.opentelemetry.api.OpenTelemetry;
|
12 | 12 | import io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil;
|
|
18 | 18 | import io.opentelemetry.sdk.testing.assertj.TraceAssert;
|
19 | 19 | import io.opentelemetry.sdk.testing.assertj.TracesAssert;
|
20 | 20 | import io.opentelemetry.sdk.trace.data.SpanData;
|
| 21 | +import java.time.Duration; |
21 | 22 | import java.util.ArrayList;
|
22 | 23 | import java.util.Arrays;
|
23 | 24 | import java.util.Collection;
|
|
29 | 30 | import java.util.stream.Collectors;
|
30 | 31 | import javax.annotation.Nullable;
|
31 | 32 | import org.assertj.core.api.ListAssert;
|
| 33 | +import org.awaitility.core.ConditionFactory; |
| 34 | +import org.awaitility.core.ConditionTimeoutException; |
32 | 35 |
|
33 | 36 | /**
|
34 | 37 | * This interface defines a common set of operations for interaction with OpenTelemetry SDK and
|
@@ -171,6 +174,13 @@ public final void waitAndAssertMetrics(
|
171 | 174 | });
|
172 | 175 | }
|
173 | 176 |
|
| 177 | + public final List<LogRecordData> waitForLogRecords(int numberOfLogRecords) { |
| 178 | + awaitUntilAsserted( |
| 179 | + () -> assertThat(getExportedLogRecords().size()).isEqualTo(numberOfLogRecords), |
| 180 | + await().timeout(Duration.ofSeconds(20))); |
| 181 | + return getExportedLogRecords(); |
| 182 | + } |
| 183 | + |
174 | 184 | private List<MetricData> instrumentationMetrics(String instrumentationName) {
|
175 | 185 | return getExportedMetrics().stream()
|
176 | 186 | .filter(m -> m.getInstrumentationScopeInfo().getName().equals(instrumentationName))
|
@@ -250,4 +260,29 @@ public final <T, E extends Throwable> T runWithNonRecordingSpan(ThrowingSupplier
|
250 | 260 | throws E {
|
251 | 261 | return testInstrumenters.runWithNonRecordingSpan(callback);
|
252 | 262 | }
|
| 263 | + |
| 264 | + private static void awaitUntilAsserted(Runnable runnable) { |
| 265 | + awaitUntilAsserted(runnable, await()); |
| 266 | + } |
| 267 | + |
| 268 | + private static void awaitUntilAsserted(Runnable runnable, ConditionFactory conditionFactory) { |
| 269 | + try { |
| 270 | + conditionFactory.untilAsserted(runnable::run); |
| 271 | + } catch (Throwable t) { |
| 272 | + // awaitility is doing a jmx call that is not implemented in GraalVM: |
| 273 | + // call: |
| 274 | + // https://github.com/awaitility/awaitility/blob/fbe16add874b4260dd240108304d5c0be84eabc8/awaitility/src/main/java/org/awaitility/core/ConditionAwaiter.java#L157 |
| 275 | + // see https://github.com/oracle/graal/issues/6101 (spring boot graal native image) |
| 276 | + if (t.getClass().getName().equals("com.oracle.svm.core.jdk.UnsupportedFeatureError") |
| 277 | + || t instanceof ConditionTimeoutException) { |
| 278 | + // Don't throw this failure since the stack is the awaitility thread, causing confusion. |
| 279 | + // Instead, just assert one more time on the test thread, which will fail with a better |
| 280 | + // stack trace - that is on the same thread as the test. |
| 281 | + // TODO: There is probably a better way to do this. |
| 282 | + runnable.run(); |
| 283 | + } else { |
| 284 | + throw t; |
| 285 | + } |
| 286 | + } |
| 287 | + } |
253 | 288 | }
|
0 commit comments