1818import io .opentelemetry .sdk .testing .assertj .TraceAssert ;
1919import io .opentelemetry .sdk .testing .assertj .TracesAssert ;
2020import io .opentelemetry .sdk .trace .data .SpanData ;
21+ import java .time .Duration ;
2122import java .util .ArrayList ;
2223import java .util .Arrays ;
2324import java .util .Collection ;
2930import java .util .stream .Collectors ;
3031import javax .annotation .Nullable ;
3132import org .assertj .core .api .ListAssert ;
33+ import org .awaitility .core .ConditionFactory ;
3234import org .awaitility .core .ConditionTimeoutException ;
3335
3436/**
@@ -118,25 +120,7 @@ private <T extends Consumer<TraceAssert>> void waitAndAssertTraces(
118120 List <T > assertionsList = new ArrayList <>();
119121 assertions .forEach (assertionsList ::add );
120122
121- try {
122- await ()
123- .untilAsserted (() -> doAssertTraces (traceComparator , assertionsList , verifyScopeVersion ));
124- } catch (Throwable t ) {
125- // awaitility is doing a jmx call that is not implemented in GraalVM:
126- // call:
127- // https://github.com/awaitility/awaitility/blob/fbe16add874b4260dd240108304d5c0be84eabc8/awaitility/src/main/java/org/awaitility/core/ConditionAwaiter.java#L157
128- // see https://github.com/oracle/graal/issues/6101 (spring boot graal native image)
129- if (t .getClass ().getName ().equals ("com.oracle.svm.core.jdk.UnsupportedFeatureError" )
130- || t instanceof ConditionTimeoutException ) {
131- // Don't throw this failure since the stack is the awaitility thread, causing confusion.
132- // Instead, just assert one more time on the test thread, which will fail with a better
133- // stack trace.
134- // TODO: There is probably a better way to do this.
135- doAssertTraces (traceComparator , assertionsList , verifyScopeVersion );
136- } else {
137- throw t ;
138- }
139- }
123+ awaitUntilAsserted (() -> doAssertTraces (traceComparator , assertionsList , verifyScopeVersion ));
140124 }
141125
142126 private <T extends Consumer <TraceAssert >> void doAssertTraces (
@@ -159,31 +143,42 @@ private <T extends Consumer<TraceAssert>> void doAssertTraces(
159143 */
160144 public final void waitAndAssertMetrics (
161145 String instrumentationName , String metricName , Consumer <ListAssert <MetricData >> assertion ) {
162- await ()
163- .untilAsserted (
164- () ->
165- assertion .accept (
166- assertThat (getExportedMetrics ())
167- .filteredOn (
168- data ->
169- data .getInstrumentationScopeInfo ()
170- .getName ()
171- .equals (instrumentationName )
172- && data .getName ().equals (metricName ))));
146+
147+ awaitUntilAsserted (
148+ () ->
149+ assertion .accept (
150+ assertThat (getExportedMetrics ())
151+ .describedAs (
152+ "Metrics for instrumentation %s and metric name %s" ,
153+ instrumentationName , metricName )
154+ .filteredOn (
155+ data ->
156+ data .getInstrumentationScopeInfo ().getName ().equals (instrumentationName )
157+ && data .getName ().equals (metricName ))));
173158 }
174159
175160 @ SafeVarargs
176161 public final void waitAndAssertMetrics (
177162 String instrumentationName , Consumer <MetricAssert >... assertions ) {
178- await ()
179- .untilAsserted (
180- () -> {
181- Collection <MetricData > metrics = instrumentationMetrics (instrumentationName );
182- assertThat (metrics ).isNotEmpty ();
183- for (Consumer <MetricAssert > assertion : assertions ) {
184- assertThat (metrics ).anySatisfy (metric -> assertion .accept (assertThat (metric )));
185- }
186- });
163+ awaitUntilAsserted (
164+ () -> {
165+ Collection <MetricData > metrics = instrumentationMetrics (instrumentationName );
166+ assertThat (metrics ).isNotEmpty ();
167+ for (int i = 0 ; i < assertions .length ; i ++) {
168+ int index = i ;
169+ assertThat (metrics )
170+ .describedAs (
171+ "Metrics for instrumentation %s and assertion %d" , instrumentationName , index )
172+ .anySatisfy (metric -> assertions [index ].accept (assertThat (metric )));
173+ }
174+ });
175+ }
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 ();
187182 }
188183
189184 private List <MetricData > instrumentationMetrics (String instrumentationName ) {
@@ -265,4 +260,29 @@ public final <T, E extends Throwable> T runWithNonRecordingSpan(ThrowingSupplier
265260 throws E {
266261 return testInstrumenters .runWithNonRecordingSpan (callback );
267262 }
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+ }
268288}
0 commit comments