@@ -18,7 +18,7 @@ use gaxi::observability::RequestRecorder;
1818use gaxi:: options:: InstrumentationClientInfo ;
1919use google_cloud_auth:: credentials:: anonymous:: Builder as Anonymous ;
2020use google_cloud_gax:: options:: RequestOptionsBuilder ;
21- use google_cloud_storage:: client:: StorageControl ;
21+ use google_cloud_storage:: client:: { Storage , StorageControl } ;
2222use integration_tests_o11y:: mock_collector:: MockCollector ;
2323use integration_tests_o11y:: otlp:: logs:: Builder as LoggerProviderBuilder ;
2424use integration_tests_o11y:: otlp:: metrics:: Builder as MeterProviderBuilder ;
@@ -365,13 +365,13 @@ async fn grpc_reports_server_error() -> anyhow::Result<()> {
365365 let setup = setup_o11y ( ) . await ?;
366366
367367 let mut mock = MockStorage :: new ( ) ;
368- mock. expect_delete_bucket ( )
368+ mock. expect_bidi_read_object ( )
369369 . return_once ( |_| Err ( Status :: new ( Code :: NotFound , "Object not found" ) ) ) ;
370370
371371 let ( endpoint, _server) = start ( "0.0.0.0:0" , mock) . await ?;
372372 let endpoint = endpoint. trim_end_matches ( '/' ) ;
373373
374- let client = StorageControl :: builder ( )
374+ let client = Storage :: builder ( )
375375 . with_endpoint ( endpoint)
376376 . with_credentials ( Anonymous :: new ( ) . build ( ) )
377377 . with_tracing ( )
@@ -388,8 +388,7 @@ async fn grpc_reports_server_error() -> anyhow::Result<()> {
388388 recorder
389389 . scope ( async {
390390 client
391- . delete_bucket ( )
392- . set_name ( "projects/_/buckets/test-bucket" )
391+ . open_object ( "projects/_/buckets/test-bucket" , "test-object" )
393392 . send ( )
394393 . await
395394 } )
@@ -419,11 +418,80 @@ async fn grpc_reports_server_error() -> anyhow::Result<()> {
419418
420419 let client_span = all_spans
421420 . iter ( )
422- . find ( |s| {
423- ( s. name == "delete_bucket" || s. name == "google.storage.v2.Storage/DeleteBucket" )
424- && ( s. kind == 1 || s. kind == 3 )
421+ . find ( |s| s. name == "google.storage.v2.Storage/BidiReadObject" )
422+ . expect ( "Should have a BidiReadObject span" ) ;
423+
424+ // Assert Span Kind and Status
425+ assert_eq ! ( client_span. kind, 3 , "Span kind should be CLIENT (3)" ) ;
426+ let status_code = client_span. status . as_ref ( ) . map ( |s| s. code ) . unwrap_or ( 0 ) ;
427+ assert_eq ! ( status_code, 2 , "Status code should be ERROR (2)" ) ;
428+
429+ let attributes: std:: collections:: HashMap < String , _ > = client_span
430+ . attributes
431+ . iter ( )
432+ . map ( |kv| ( kv. key . clone ( ) , kv. value . clone ( ) . unwrap ( ) ) )
433+ . collect ( ) ;
434+
435+ let get_string = |key : & str | -> Option < String > {
436+ attributes. get ( key) . and_then ( |v| match & v. value {
437+ Some ( opentelemetry_proto:: tonic:: common:: v1:: any_value:: Value :: StringValue ( s) ) => {
438+ Some ( s. clone ( ) )
439+ }
440+ _ => None ,
425441 } )
426- . expect ( "Should have a DeleteBucket span" ) ;
442+ } ;
443+
444+ let get_int = |key : & str | -> Option < i64 > {
445+ attributes. get ( key) . and_then ( |v| match & v. value {
446+ Some ( opentelemetry_proto:: tonic:: common:: v1:: any_value:: Value :: IntValue ( i) ) => Some ( * i) ,
447+ _ => None ,
448+ } )
449+ } ;
450+
451+ println ! ( "ATTRIBUTES = {:?}" , attributes. keys( ) ) ;
452+ println ! (
453+ "rpc.response.status_code (int) = {:?}" ,
454+ get_int( "rpc.response.status_code" )
455+ ) ;
456+ println ! (
457+ "rpc.response.status_code (str) = {:?}" ,
458+ get_string( "rpc.response.status_code" )
459+ ) ;
460+
461+ assert_eq ! ( get_string( "rpc.system.name" ) . as_deref( ) , Some ( "grpc" ) ) ;
462+ assert_eq ! (
463+ get_string( "rpc.method" ) . as_deref( ) ,
464+ Some ( "google.storage.v2.Storage/BidiReadObject" )
465+ ) ;
466+ assert_eq ! (
467+ get_string( "rpc.response.status_code" ) . as_deref( ) ,
468+ Some ( "NOT_FOUND" )
469+ ) ;
470+ assert_eq ! ( get_string( "error.type" ) . as_deref( ) , Some ( "NOT_FOUND" ) ) ;
471+
472+ assert_eq ! (
473+ get_string( "gcp.client.repo" ) . as_deref( ) ,
474+ Some ( "googleapis/google-cloud-rust" )
475+ ) ;
476+ assert_eq ! (
477+ get_string( "gcp.client.artifact" ) . as_deref( ) ,
478+ Some ( "google-cloud-storage" )
479+ ) ;
480+ assert ! ( get_string( "gcp.client.version" ) . is_some( ) ) ;
481+ assert_eq ! ( get_string( "gcp.client.service" ) . as_deref( ) , Some ( "storage" ) ) ;
482+
483+ let actual_addr = get_string ( "server.address" ) . unwrap ( ) ;
484+ assert ! (
485+ actual_addr == "127.0.0.1" || actual_addr == "::1" || actual_addr == "0.0.0.0" ,
486+ "address was {}" ,
487+ actual_addr
488+ ) ;
489+ assert ! ( get_int( "server.port" ) . is_some( ) ) ;
490+
491+ assert_eq ! (
492+ get_string( "gcp.resource.destination.id" ) . as_deref( ) ,
493+ Some ( "//storage.googleapis.com/projects/_/buckets/test-bucket" )
494+ ) ;
427495
428496 verify_metrics ( & setup. mock_collector ) ;
429497 verify_logs ( & setup. mock_collector , client_span) ;
0 commit comments