diff --git a/aws/rust-runtime/aws-runtime/src/user_agent/test_util.rs b/aws/rust-runtime/aws-runtime/src/user_agent/test_util.rs index a0a5679b63..de8013454f 100644 --- a/aws/rust-runtime/aws-runtime/src/user_agent/test_util.rs +++ b/aws/rust-runtime/aws-runtime/src/user_agent/test_util.rs @@ -17,13 +17,8 @@ static RE: Lazy = Lazy::new(|| Regex::new(r"m/([A-Za-z0-9+/=_,-]+)").unwr /// Refer to the end of the parent module file `user_agent.rs` for the complete ABNF specification /// of `business-metrics`. pub fn assert_ua_contains_metric_values(user_agent: &str, values: &[&str]) { - match RE.find(user_agent) { - Some(matched) => { - let csv = matched - .as_str() - .strip_prefix("m/") - .expect("prefix `m/` is guaranteed to exist by regex match"); - let metrics: Vec<&str> = csv.split(',').collect(); + match extract_ua_values(user_agent) { + Some(metrics) => { let mut missed = vec![]; for value in values.iter() { @@ -43,6 +38,18 @@ pub fn assert_ua_contains_metric_values(user_agent: &str, values: &[&str]) { } } +/// Extract the metric values from the `user_agent` string +pub fn extract_ua_values(user_agent: &str) -> Option> { + RE.find(user_agent).map(|matched| { + matched + .as_str() + .strip_prefix("m/") + .expect("prefix `m/` is guaranteed to exist by regex match") + .split(',') + .collect() + }) +} + #[cfg(test)] mod tests { use super::*; diff --git a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/HttpChecksumTest.kt b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/HttpChecksumTest.kt index e7b2c897d5..3c2684ff4c 100644 --- a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/HttpChecksumTest.kt +++ b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/HttpChecksumTest.kt @@ -8,6 +8,7 @@ package software.amazon.smithy.rustsdk import org.junit.jupiter.api.Test import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency +import software.amazon.smithy.rust.codegen.core.rustlang.Feature import software.amazon.smithy.rust.codegen.core.rustlang.Writable import software.amazon.smithy.rust.codegen.core.rustlang.join import software.amazon.smithy.rust.codegen.core.rustlang.plus @@ -130,8 +131,10 @@ internal class HttpChecksumTest { @Test fun requestChecksumWorks() { awsSdkIntegrationTest(model) { context, rustCrate -> - + // Allows us to use the user-agent test-utils in aws-runtime + rustCrate.mergeFeature(Feature("test-util", true, listOf("aws-runtime/test-util"))) val rc = context.runtimeConfig + // Create Writables for all test types val checksumRequestTestWritables = checksumRequestTests.map { createRequestChecksumCalculationTest(it, context) }.join("\n") @@ -158,6 +161,8 @@ internal class HttpChecksumTest { use std::io::Write; use http_body::Body; use #{HttpRequest}; + use #{UaAssert}; + use #{UaExtract}; """, *preludeScope, "Blob" to RuntimeType.smithyTypes(rc).resolve("Blob"), @@ -165,34 +170,40 @@ internal class HttpChecksumTest { "pretty_assertions" to CargoDependency.PrettyAssertions.toType(), "SdkBody" to RuntimeType.smithyTypes(rc).resolve("body::SdkBody"), "HttpRequest" to RuntimeType.smithyRuntimeApi(rc).resolve("client::orchestrator::HttpRequest"), + "UaAssert" to + AwsRuntimeType.awsRuntime(rc) + .resolve("user_agent::test_util::assert_ua_contains_metric_values"), + "UaExtract" to + AwsRuntimeType.awsRuntime(rc) + .resolve("user_agent::test_util::extract_ua_values"), ) } - 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::>()[0] - } - """.trimIndent(), - ) - } +// 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::>()[0] +// } +// """.trimIndent(), +// ) +// } // Create one integ test per test type rustCrate.integrationTest("request_checksums") { - testBase.plus(checksumRequestTestWritables).plus(uaExtractor)() + testBase.plus(checksumRequestTestWritables)() } rustCrate.integrationTest("response_checksums_success") { @@ -208,7 +219,7 @@ internal class HttpChecksumTest { } rustCrate.integrationTest("misc_tests") { - testBase.plus(uaExtractor).plus(miscTests)() + testBase.plus(miscTests)() } } } @@ -263,8 +274,13 @@ internal class HttpChecksumTest { assert_eq!(algo_header, "${testDef.algoHeader}"); // Check the user-agent metrics for the selected algo - let sdk_metrics = get_sdk_metric_str(&request); - assert!(sdk_metrics.contains("${testDef.algoFeatureId}")); + assert_ua_contains_metric_values( + &request + .headers() + .get("x-amz-user-agent") + .expect("UA header should be present"), + &["${testDef.algoFeatureId}"], + ); } """, *preludeScope, @@ -462,7 +478,8 @@ internal class HttpChecksumTest { } /** - * Generate miscellaneous tests + * Generate miscellaneous tests, currently mostly focused on the inclusion of the checksum config metrics in the + * user-agent header */ private fun createMiscellaneousTests(context: ClientCodegenContext): Writable { val rc = context.runtimeConfig @@ -492,9 +509,14 @@ internal class HttpChecksumTest { .await; let request = rx.expect_request(); - let sdk_metrics = get_sdk_metric_str(&request); - assert!(sdk_metrics.contains("a")); - assert!(!sdk_metrics.contains("Z")); + let sdk_metrics = extract_ua_values( + &request + .headers() + .get("x-amz-user-agent") + .expect("UA header should be present"), + ).expect("UA header should be present"); + assert!(sdk_metrics.contains(&"a")); + assert!(!sdk_metrics.contains(&"Z")); } ##[::tokio::test] @@ -514,9 +536,14 @@ internal class HttpChecksumTest { .await; let request = rx.expect_request(); - let sdk_metrics = get_sdk_metric_str(&request); - assert!(sdk_metrics.contains("Z")); - assert!(!sdk_metrics.contains("a")); + let sdk_metrics = extract_ua_values( + &request + .headers() + .get("x-amz-user-agent") + .expect("UA header should be present"), + ).expect("UA header should be present"); + assert!(sdk_metrics.contains(&"Z")); + assert!(!sdk_metrics.contains(&"a")); } ##[::tokio::test] @@ -541,9 +568,14 @@ internal class HttpChecksumTest { .await; let request = rx.expect_request(); - let sdk_metrics = get_sdk_metric_str(&request); - assert!(sdk_metrics.contains("b")); - assert!(!sdk_metrics.contains("c")); + let sdk_metrics = extract_ua_values( + &request + .headers() + .get("x-amz-user-agent") + .expect("UA header should be present"), + ).expect("UA header should be present"); + assert!(sdk_metrics.contains(&"b")); + assert!(!sdk_metrics.contains(&"c")); } ##[::tokio::test] @@ -571,9 +603,14 @@ internal class HttpChecksumTest { .await; let request = rx.expect_request(); - let sdk_metrics = get_sdk_metric_str(&request); - assert!(sdk_metrics.contains("c")); - assert!(!sdk_metrics.contains("b")); + let sdk_metrics = extract_ua_values( + &request + .headers() + .get("x-amz-user-agent") + .expect("UA header should be present"), + ).expect("UA header should be present"); + assert!(sdk_metrics.contains(&"c")); + assert!(!sdk_metrics.contains(&"b")); } """, *preludeScope,