Skip to content

Commit e24f1d7

Browse files
committed
feat(gax): verify T3/T4 span hierarchy and retry aggregation
1 parent 349c14a commit e24f1d7

1 file changed

Lines changed: 95 additions & 0 deletions

File tree

‎sdk-platform-java/gax-java/gax/src/test/java/com/google/api/gax/tracing/OpenTelemetryTracingTracerIntegrationTest.java‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,99 @@ void testAttemptStarted_afterOperationCompleted_doesNotEmitNewSpan() {
257257
assertThat(finishedSpans).hasSize(1);
258258
assertThat(finishedSpans.get(0).getKind()).isEqualTo(SpanKind.INTERNAL);
259259
}
260+
261+
@Test
262+
void testRetrySucceeds_operationAggregatesSuccessAttributes() {
263+
ApiTracer apiTracer = tracingFactory.newTracer(BaseApiTracer.getInstance(), TRACER_CONTEXT);
264+
265+
// Attempt 0 fails with transient error
266+
apiTracer.attemptStarted(new Object(), 0);
267+
apiTracer.attemptFailedDuration(
268+
new RuntimeException("transient 503"), java.time.Duration.ofMillis(10));
269+
270+
// Attempt 1 succeeds
271+
apiTracer.attemptStarted(new Object(), 1);
272+
apiTracer.attemptSucceeded();
273+
apiTracer.operationSucceeded();
274+
275+
List<SpanData> finishedSpans = spanExporter.getFinishedSpanItems();
276+
assertThat(finishedSpans).hasSize(3); // attempt 0, attempt 1, operation
277+
278+
SpanData operationSpan =
279+
finishedSpans.stream()
280+
.filter(s -> s.getKind() == SpanKind.INTERNAL)
281+
.findFirst()
282+
.orElseThrow(() -> new AssertionError("Operation span not found"));
283+
284+
List<SpanData> attemptSpans =
285+
finishedSpans.stream()
286+
.filter(s -> s.getKind() == SpanKind.CLIENT)
287+
.collect(java.util.stream.Collectors.toList());
288+
assertThat(attemptSpans).hasSize(2);
289+
290+
for (SpanData attempt : attemptSpans) {
291+
assertThat(attempt.getParentSpanId()).isEqualTo(operationSpan.getSpanContext().getSpanId());
292+
}
293+
294+
assertThat(operationSpan.getStatus().getStatusCode())
295+
.isEqualTo(io.opentelemetry.api.trace.StatusCode.UNSET);
296+
assertThat(
297+
operationSpan
298+
.getAttributes()
299+
.get(AttributeKey.stringKey(ObservabilityAttributes.RPC_RESPONSE_STATUS_ATTRIBUTE)))
300+
.isEqualTo("OK");
301+
assertThat(
302+
operationSpan
303+
.getAttributes()
304+
.get(AttributeKey.stringKey(ObservabilityAttributes.ERROR_TYPE_ATTRIBUTE)))
305+
.isNull();
306+
}
307+
308+
@Test
309+
void testRetriesExhausted_operationAggregatesFailureAttributes() {
310+
ApiTracer apiTracer = tracingFactory.newTracer(BaseApiTracer.getInstance(), TRACER_CONTEXT);
311+
312+
// Attempt 0 fails with transient error
313+
apiTracer.attemptStarted(new Object(), 0);
314+
apiTracer.attemptFailedDuration(
315+
new RuntimeException("transient 503"), java.time.Duration.ofMillis(10));
316+
317+
// Attempt 1 fails and exhausts retries
318+
apiTracer.attemptStarted(new Object(), 1);
319+
RuntimeException finalError = new RuntimeException("unavailable: retries exhausted");
320+
apiTracer.attemptFailedRetriesExhausted(finalError);
321+
apiTracer.operationFailed(finalError);
322+
323+
List<SpanData> finishedSpans = spanExporter.getFinishedSpanItems();
324+
assertThat(finishedSpans).hasSize(3); // attempt 0, attempt 1, operation
325+
326+
SpanData operationSpan =
327+
finishedSpans.stream()
328+
.filter(s -> s.getKind() == SpanKind.INTERNAL)
329+
.findFirst()
330+
.orElseThrow(() -> new AssertionError("Operation span not found"));
331+
332+
List<SpanData> attemptSpans =
333+
finishedSpans.stream()
334+
.filter(s -> s.getKind() == SpanKind.CLIENT)
335+
.collect(java.util.stream.Collectors.toList());
336+
assertThat(attemptSpans).hasSize(2);
337+
338+
for (SpanData attempt : attemptSpans) {
339+
assertThat(attempt.getParentSpanId()).isEqualTo(operationSpan.getSpanContext().getSpanId());
340+
}
341+
342+
assertThat(operationSpan.getStatus().getStatusCode())
343+
.isEqualTo(io.opentelemetry.api.trace.StatusCode.ERROR);
344+
assertThat(
345+
operationSpan
346+
.getAttributes()
347+
.get(AttributeKey.stringKey(ObservabilityAttributes.STATUS_MESSAGE_ATTRIBUTE)))
348+
.isEqualTo("unavailable: retries exhausted");
349+
assertThat(
350+
operationSpan
351+
.getAttributes()
352+
.get(AttributeKey.stringKey(ObservabilityAttributes.ERROR_TYPE_ATTRIBUTE)))
353+
.isNotNull();
354+
}
260355
}

0 commit comments

Comments
 (0)