Skip to content

Commit c5ac6fa

Browse files
committed
test(o11y): verify gRPC spans are recorded on server failure
1 parent 239c1de commit c5ac6fa

1 file changed

Lines changed: 77 additions & 9 deletions

File tree

tests/o11y/tests/storage_grpc_tracing.rs

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use gaxi::observability::RequestRecorder;
1818
use gaxi::options::InstrumentationClientInfo;
1919
use google_cloud_auth::credentials::anonymous::Builder as Anonymous;
2020
use google_cloud_gax::options::RequestOptionsBuilder;
21-
use google_cloud_storage::client::StorageControl;
21+
use google_cloud_storage::client::{Storage, StorageControl};
2222
use integration_tests_o11y::mock_collector::MockCollector;
2323
use integration_tests_o11y::otlp::logs::Builder as LoggerProviderBuilder;
2424
use 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

Comments
 (0)