5151import io .opentelemetry .sdk .trace .export .SimpleSpanProcessor ;
5252import java .util .List ;
5353import java .util .Map ;
54+ import java .util .Objects ;
5455import org .junit .jupiter .api .AfterEach ;
5556import org .junit .jupiter .api .Assertions ;
5657import org .junit .jupiter .api .BeforeEach ;
@@ -101,8 +102,6 @@ void testTracing_successfulEcho_grpc() throws Exception {
101102 .filter (span -> span .getName ().equals ("Echo/Echo/attempt" ))
102103 .findFirst ()
103104 .orElseThrow (() -> new AssertionError ("Attempt span 'Echo/Echo/attempt' not found" ));
104- assertThat (attemptSpan .getAttributes ().get (AttributeKey .stringKey ("attemptNumber" )))
105- .isEqualTo ("0" );
106105 assertThat (
107106 attemptSpan
108107 .getAttributes ()
@@ -111,14 +110,12 @@ void testTracing_successfulEcho_grpc() throws Exception {
111110 assertThat (
112111 attemptSpan
113112 .getAttributes ()
114- .get (AttributeKey .stringKey (OpenTelemetryTracingTracerFactory .PORT_ATTRIBUTE )))
113+ .get (AttributeKey .stringKey (OpenTelemetryTracingTracer .PORT_ATTRIBUTE )))
115114 .isEqualTo (SHOWCASE_SERVER_PORT );
116115 assertThat (
117116 attemptSpan
118117 .getAttributes ()
119- .get (
120- AttributeKey .stringKey (
121- OpenTelemetryTracingTracerFactory .RPC_SYSTEM_ATTRIBUTE )))
118+ .get (AttributeKey .stringKey (OpenTelemetryTracingTracer .RPC_SYSTEM_ATTRIBUTE )))
122119 .isEqualTo ("grpc" );
123120 }
124121 }
@@ -144,9 +141,7 @@ void testTracing_successfulEcho_httpjson() throws Exception {
144141 assertThat (
145142 attemptSpan
146143 .getAttributes ()
147- .get (
148- AttributeKey .stringKey (
149- OpenTelemetryTracingTracerFactory .RPC_SYSTEM_ATTRIBUTE )))
144+ .get (AttributeKey .stringKey (OpenTelemetryTracingTracer .RPC_SYSTEM_ATTRIBUTE )))
150145 .isEqualTo ("http" );
151146 }
152147 }
@@ -201,6 +196,97 @@ void testTracing_errorRecording() throws Exception {
201196 }
202197 }
203198
199+ @ Test
200+ void testTracing_resendCount_grpc () throws Exception {
201+ OpenTelemetryTracingTracerFactory tracingFactory =
202+ new OpenTelemetryTracingTracerFactory (new OpenTelemetryTracingRecorder (openTelemetrySdk ));
203+
204+ try (EchoClient client =
205+ TestClientInitializer .createGrpcEchoClientOpentelemetry (tracingFactory )) {
206+
207+ // Simulate UNAVAILABLE to trigger retries
208+ Assertions .assertThrows (
209+ Exception .class ,
210+ () ->
211+ client .echo (
212+ EchoRequest .newBuilder ()
213+ .setContent ("resend-test-grpc" )
214+ .setError (
215+ Status .newBuilder ()
216+ .setCode (StatusCode .Code .UNAVAILABLE .ordinal ())
217+ .build ())
218+ .build ()));
219+
220+ List <SpanData > spans = spanExporter .getFinishedSpanItems ();
221+ assertThat (spans ).isNotEmpty ();
222+
223+ // Verify that subsequent attempts have gcp.grpc.resend_count
224+ SpanData secondAttempt =
225+ spans .stream ()
226+ .filter (
227+ span ->
228+ span .getName ().equals ("Echo/Echo/attempt" )
229+ && Objects .equals (
230+ span .getAttributes ()
231+ .get (
232+ AttributeKey .stringKey (
233+ OpenTelemetryTracingTracer .GRPC_RESEND_COUNT_ATTRIBUTE )),
234+ "1" ))
235+ .findFirst ()
236+ .orElseThrow (() -> new AssertionError ("Second attempt span not found" ));
237+
238+ assertThat (secondAttempt .getAttributes ().get (AttributeKey .stringKey ("gcp.grpc.resend_count" )))
239+ .isEqualTo ("1" );
240+ }
241+ }
242+
243+ @ Test
244+ void testTracing_resendCount_httpjson () throws Exception {
245+ OpenTelemetryTracingTracerFactory tracingFactory =
246+ new OpenTelemetryTracingTracerFactory (new OpenTelemetryTracingRecorder (openTelemetrySdk ));
247+
248+ try (EchoClient client =
249+ TestClientInitializer .createHttpJsonEchoClientOpentelemetry (tracingFactory )) {
250+
251+ // Simulate UNAVAILABLE to trigger retries
252+ Assertions .assertThrows (
253+ Exception .class ,
254+ () ->
255+ client .echo (
256+ EchoRequest .newBuilder ()
257+ .setContent ("resend-test-http" )
258+ .setError (
259+ Status .newBuilder ()
260+ .setCode (StatusCode .Code .UNAVAILABLE .ordinal ())
261+ .build ())
262+ .build ()));
263+
264+ List <SpanData > spans = spanExporter .getFinishedSpanItems ();
265+ assertThat (spans ).isNotEmpty ();
266+
267+ // Verify that subsequent attempts have http.request.resend_count
268+ SpanData secondAttempt =
269+ spans .stream ()
270+ .filter (
271+ span ->
272+ span .getName ().equals ("google.showcase.v1beta1/Echo/Echo/attempt" )
273+ && Objects .equals (
274+ span .getAttributes ()
275+ .get (
276+ AttributeKey .stringKey (
277+ OpenTelemetryTracingTracer .HTTP_RESEND_COUNT_ATTRIBUTE )),
278+ "1" ))
279+ .findFirst ()
280+ .orElseThrow (() -> new AssertionError ("Second attempt span not found" ));
281+
282+ assertThat (
283+ secondAttempt
284+ .getAttributes ()
285+ .get (AttributeKey .stringKey ("http.request.resend_count" )))
286+ .isEqualTo ("1" );
287+ }
288+ }
289+
204290 @ Test
205291 void testTracing_withCustomAttributes () throws Exception {
206292 Map <String , String > opAttributes = ImmutableMap .of ("op-key" , "op-value" );
0 commit comments