Skip to content

Commit

Permalink
Add tests for checksum user-agent business metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
landonxjames committed Sep 28, 2024
1 parent 7be1e00 commit 6b09dd9
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 58 deletions.
6 changes: 3 additions & 3 deletions aws/rust-runtime/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aws-config"
version = "1.5.7"
version = "1.5.8"
authors = [
"AWS Rust SDK Team <aws-sdk-rust@amazon.com>",
"Russell Cohen <rcoh@amazon.com>",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ where
cfg.interceptor_state()
.store_append(SmithySdkFeature::FlexibleChecksumsReqCrc32c);
}
#[allow(deprecated)]
ChecksumAlgorithm::Md5 => {
tracing::warn!(more_info = "Unsupported ChecksumAlgorithm MD5 set");
}
Expand Down
34 changes: 19 additions & 15 deletions aws/rust-runtime/aws-inlineable/src/http_response_checksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,25 @@ where
layer.store_put(ResponseChecksumInterceptorState { validation_enabled });
cfg.push_layer(layer);

let response_checksum_validation = cfg
.load::<ResponseChecksumValidation>()
.unwrap_or(&ResponseChecksumValidation::WhenSupported);

// Set the user-agent feature metric for the response checksum config
match response_checksum_validation {
ResponseChecksumValidation::WhenSupported => {
cfg.interceptor_state()
.store_append(SmithySdkFeature::FlexibleChecksumsResWhenSupported);
}
ResponseChecksumValidation::WhenRequired => {
cfg.interceptor_state()
.store_append(SmithySdkFeature::FlexibleChecksumsResWhenRequired);
}
unsupported => tracing::warn!(
more_info = "Unsupported value of ResponseChecksumValidation when setting user-agent metrics",
unsupported = ?unsupported),
};

Ok(())
}

Expand Down Expand Up @@ -127,21 +146,6 @@ where
}
}

// Set the user-agent feature metric for the response checksum config
match response_checksum_validation {
ResponseChecksumValidation::WhenSupported => {
cfg.interceptor_state()
.store_append(SmithySdkFeature::FlexibleChecksumsResWhenSupported);
}
ResponseChecksumValidation::WhenRequired => {
cfg.interceptor_state()
.store_append(SmithySdkFeature::FlexibleChecksumsResWhenRequired);
}
unsupported => tracing::warn!(
more_info = "Unsupported value of ResponseChecksumValidation when setting user-agent metrics",
unsupported = ?unsupported),
};

Ok(())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ internal class HttpChecksumTest {
checksumResponseFailTests.map { createResponseChecksumValidationFailureTest(it, context) }.join("\n")
val checksumStreamingRequestTestWritables =
streamingRequestTests.map { createStreamingRequestChecksumCalculationTest(it, context) }.join("\n")
val miscTests = createMiscellaneousTests(context)

// Shared imports for all test types
val testBase =
Expand All @@ -156,12 +157,36 @@ internal class HttpChecksumTest {
use #{SdkBody};
use std::io::Write;
use http_body::Body;
use #{HttpRequest};
""",
*preludeScope,
"Blob" to RuntimeType.smithyTypes(rc).resolve("Blob"),
"Region" to AwsRuntimeType.awsTypes(rc).resolve("region::Region"),
"pretty_assertions" to CargoDependency.PrettyAssertions.toType(),
"SdkBody" to RuntimeType.smithyTypes(rc).resolve("body::SdkBody"),
"HttpRequest" to RuntimeType.smithyRuntimeApi(rc).resolve("client::orchestrator::HttpRequest"),
)
}

val uaExtractor =
writable {
rustTemplate(
"""
fn get_sdk_metric_str(req: &HttpRequest) -> &str {
req.headers()
.get("x-amz-user-agent")
.unwrap()
.split(" ")
.filter_map(|sec| {
if sec.starts_with("m/") {
Some(&sec[2..])
} else {
None
}
})
.collect::<Vec<&str>>()[0]
}
""".trimIndent(),
)
}

Expand All @@ -181,6 +206,10 @@ internal class HttpChecksumTest {
rustCrate.integrationTest("streaming_request_checksums") {
testBase.plus(checksumStreamingRequestTestWritables)()
}

rustCrate.integrationTest("misc_tests") {
testBase.plus(uaExtractor).plus(miscTests)()
}
}
}

Expand Down Expand Up @@ -427,6 +456,128 @@ internal class HttpChecksumTest {
)
}
}

/**
* Generate miscellaneous tests
*/
private fun createMiscellaneousTests(context: ClientCodegenContext): Writable {
val rc = context.runtimeConfig
val moduleName = context.moduleUseName()
return writable {
rustTemplate(
"""
// The following tests confirm that the user-agent business metrics header is correctly
// set for the request/response checksum config values
##[::tokio::test]
async fn request_config_ua_required() {
let (http_client, rx) = #{capture_request}(None);
let config = $moduleName::Config::builder()
.region(Region::from_static("doesntmatter"))
.with_test_defaults()
.http_client(http_client)
.request_checksum_calculation(
aws_types::sdk_config::RequestChecksumCalculation::WhenRequired,
)
.build();
let client = $moduleName::Client::from_conf(config);
let _ = client
.some_operation()
.body(Blob::new(b"Doesn't matter"))
.send()
.await;
let request = rx.expect_request();
let sdk_metrics = get_sdk_metric_str(&request);
assert!(sdk_metrics.contains("a"));
assert!(!sdk_metrics.contains("Z"));
}
##[::tokio::test]
async fn request_config_ua_supported() {
let (http_client, rx) = #{capture_request}(None);
let config = $moduleName::Config::builder()
.region(Region::from_static("doesntmatter"))
.with_test_defaults()
.http_client(http_client)
.build();
let client = $moduleName::Client::from_conf(config);
let _ = client
.some_operation()
.body(Blob::new(b"Doesn't matter"))
.send()
.await;
let request = rx.expect_request();
let sdk_metrics = get_sdk_metric_str(&request);
assert!(sdk_metrics.contains("Z"));
assert!(!sdk_metrics.contains("a"));
}
##[::tokio::test]
async fn response_config_ua_supported() {
let (http_client, rx) = #{capture_request}(Some(
http::Response::builder()
.header("x-amz-checksum-crc32", "i9aeUg==")
.body(SdkBody::from("Hello world"))
.unwrap(),
));
let config = $moduleName::Config::builder()
.region(Region::from_static("doesntmatter"))
.with_test_defaults()
.http_client(http_client)
.build();
let client = $moduleName::Client::from_conf(config);
let _ = client
.some_operation()
.body(Blob::new(b"Doesn't matter"))
.send()
.await;
let request = rx.expect_request();
let sdk_metrics = get_sdk_metric_str(&request);
assert!(sdk_metrics.contains("b"));
assert!(!sdk_metrics.contains("c"));
}
##[::tokio::test]
async fn response_config_ua_required() {
let (http_client, rx) = #{capture_request}(Some(
http::Response::builder()
.header("x-amz-checksum-crc32", "i9aeUg==")
.body(SdkBody::from("Hello world"))
.unwrap(),
));
let config = $moduleName::Config::builder()
.region(Region::from_static("doesntmatter"))
.with_test_defaults()
.http_client(http_client)
.response_checksum_validation(
aws_types::sdk_config::ResponseChecksumValidation::WhenRequired,
)
.build();
let client = $moduleName::Client::from_conf(config);
let _ = client
.some_operation()
.body(Blob::new(b"Doesn't matter"))
.send()
.await;
let request = rx.expect_request();
let sdk_metrics = get_sdk_metric_str(&request);
assert!(sdk_metrics.contains("c"));
assert!(!sdk_metrics.contains("b"));
}
""",
*preludeScope,
"tokio" to CargoDependency.Tokio.toType(),
"capture_request" to RuntimeType.captureRequest(rc),
)
}
}
}

// Classes and data for test definitions
Expand Down
Loading

0 comments on commit 6b09dd9

Please sign in to comment.