@@ -126,3 +126,64 @@ pub async fn grpc_can_be_disabled() -> anyhow::Result<()> {
126126
127127 Ok ( ( ) )
128128}
129+
130+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
131+ pub async fn grpc_reports_client_failure ( ) -> anyhow:: Result < ( ) > {
132+ let mock_collector = MockCollector :: default ( ) ;
133+ let otlp_endpoint: String = mock_collector. start ( ) . await ;
134+
135+ let provider: opentelemetry_sdk:: trace:: SdkTracerProvider =
136+ TracerProviderBuilder :: new ( "test-project" , "integration-tests" )
137+ . with_endpoint ( otlp_endpoint. clone ( ) )
138+ . with_credentials ( Anonymous :: new ( ) . build ( ) )
139+ . build ( )
140+ . await ?;
141+
142+ let _guard = tracing_subscriber:: Registry :: default ( )
143+ . with ( integration_tests_o11y:: tracing:: trace_layer (
144+ provider. clone ( ) ,
145+ ) )
146+ . set_default ( ) ;
147+
148+ // Use a bogus endpoint to trigger a client failure (connection refused)
149+ let endpoint = "http://127.0.0.1:12345" ;
150+
151+ let client = StorageControl :: builder ( )
152+ . with_endpoint ( endpoint)
153+ . with_credentials ( Anonymous :: new ( ) . build ( ) )
154+ . with_retry_policy ( google_cloud_gax:: retry_policy:: NeverRetry )
155+ . with_tracing ( )
156+ . build ( )
157+ . await ?;
158+
159+ let _ = client
160+ . delete_bucket ( )
161+ . set_name ( "projects/_/buckets/test-bucket" )
162+ . send ( )
163+ . await ;
164+
165+ tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( 100 ) ) . await ;
166+ let _ = provider. force_flush ( ) ;
167+
168+ let ( _, _, request) = mock_collector
169+ . traces
170+ . lock ( )
171+ . expect ( "never poisoned" )
172+ . pop ( )
173+ . expect ( "should have received at least one trace request" )
174+ . into_parts ( ) ;
175+
176+ let mut all_spans = Vec :: new ( ) ;
177+ for rs in request. resource_spans {
178+ for ss in rs. scope_spans {
179+ all_spans. extend ( ss. spans ) ;
180+ }
181+ }
182+
183+ let _client_span = all_spans
184+ . iter ( )
185+ . find ( |s| s. name == "delete_bucket" || s. name == "google.storage.v2.Storage/DeleteBucket" )
186+ . expect ( "Should have a DeleteBucket span" ) ;
187+
188+ Ok ( ( ) )
189+ }
0 commit comments