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 ;
32
34
import org .awaitility .core .ConditionTimeoutException ;
33
35
34
36
/**
@@ -118,25 +120,7 @@ private <T extends Consumer<TraceAssert>> void waitAndAssertTraces(
118
120
List <T > assertionsList = new ArrayList <>();
119
121
assertions .forEach (assertionsList ::add );
120
122
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 ));
140
124
}
141
125
142
126
private <T extends Consumer <TraceAssert >> void doAssertTraces (
@@ -159,31 +143,42 @@ private <T extends Consumer<TraceAssert>> void doAssertTraces(
159
143
*/
160
144
public final void waitAndAssertMetrics (
161
145
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 ))));
173
158
}
174
159
175
160
@ SafeVarargs
176
161
public final void waitAndAssertMetrics (
177
162
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 ();
187
182
}
188
183
189
184
private List <MetricData > instrumentationMetrics (String instrumentationName ) {
@@ -265,4 +260,29 @@ public final <T, E extends Throwable> T runWithNonRecordingSpan(ThrowingSupplier
265
260
throws E {
266
261
return testInstrumenters .runWithNonRecordingSpan (callback );
267
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
+ }
268
288
}
0 commit comments