From 2c0274cb7aa5e30567b6268965b034e26e16a416 Mon Sep 17 00:00:00 2001 From: ysaito1001 Date: Thu, 3 Oct 2024 15:43:59 -0500 Subject: [PATCH] Compare query strings based on set of components in ec2 integration tests (#3859) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation and Context Avoids comparing raw strings in ec2 integration tests ## Description With a updated service model for ec2, we have run into the following test failures in its integration tests, ``` ----- paginators_handle_unset_tokens stdout ---- body did not match. left=expected, right=actual Diff < left / right > : Action=DescribeSpotPriceHistory&Version=2016-11-15&InstanceType.1=g5.48xlarge&ProductDescription.1=Linux%2FUNIX·[1;48;5;22;32m&AvailabilityZone=eu-north-1a thread 'paginators_handle_unset_tokens' panicked at sdk/aws-smithy-runtime/src/client/http/test_util/replay.rs:98:43: ---- paginators_handle_empty_tokens stdout ---- body did not match. left=expected, right=actual Diff < left / right > : Action=DescribeSpotPriceHistory&Version=2016-11-15&InstanceType.1=g5.48xlarge&ProductDescription.1=Linux%2FUNIX·[1;48;5;22;32m&AvailabilityZone=eu-north-1a thread 'paginators_handle_empty_tokens' panicked at sdk/aws-smithy-runtime/src/client/http/test_util/replay.rs:98:43: ``` We don't know exactly how a generated ec2 SDK built up query strings in a different order from what it is today, but whatever the root cause is, the ultimate fix remains the same. Comparing raw query strings can be unreliable, so this PR will fix that by comparing sets of strings derived from query strings. ## Testing Ran the edited tests against the generated ec2 SDK in question and it passed (without this PR, it did fail). ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --- .../integration-tests/ec2/tests/paginators.rs | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/aws/sdk/integration-tests/ec2/tests/paginators.rs b/aws/sdk/integration-tests/ec2/tests/paginators.rs index 36dc3152b2..aa6a995f4f 100644 --- a/aws/sdk/integration-tests/ec2/tests/paginators.rs +++ b/aws/sdk/integration-tests/ec2/tests/paginators.rs @@ -5,11 +5,10 @@ use aws_runtime::user_agent::test_util::assert_ua_contains_metric_values; use aws_sdk_ec2::{config::Credentials, config::Region, types::InstanceType, Client, Config}; -use aws_smithy_runtime::client::http::test_util::{ - capture_request, ReplayEvent, StaticReplayClient, -}; +use aws_smithy_runtime::client::http::test_util::capture_request; use aws_smithy_runtime_api::client::http::HttpClient; use aws_smithy_types::body::SdkBody; +use std::collections::HashSet; fn stub_config(http_client: impl HttpClient + 'static) -> Config { Config::builder() @@ -19,28 +18,29 @@ fn stub_config(http_client: impl HttpClient + 'static) -> Config { .build() } +fn validate_query_string(expected: &str, actual: &str) { + let expected = expected.split('&').collect::>(); + let actual = actual.split('&').collect::>(); + assert_eq!(expected, actual); + assert_eq!(expected.len(), actual.len()); +} + /// See https://github.com/awslabs/aws-sdk-rust/issues/391 /// /// EC2 replies with `` which our XML parser parses as empty string and not "none" #[tokio::test] async fn paginators_handle_empty_tokens() { - let request= "Action=DescribeSpotPriceHistory&Version=2016-11-15&AvailabilityZone=eu-north-1a&InstanceType.1=g5.48xlarge&ProductDescription.1=Linux%2FUNIX"; let response = r#" edf3e86c-4baf-47c1-9228-9a5ea09542e8 "#; - let http_client = StaticReplayClient::new(vec![ReplayEvent::new( - http::Request::builder() - .uri("https://ec2.us-east-1.amazonaws.com/") - .body(request.into()) - .unwrap(), - http::Response::builder() - .status(200) - .body(SdkBody::from(response)) - .unwrap(), - )]); + let response = http::Response::builder() + .status(200) + .body(SdkBody::from(response)) + .unwrap(); + let (http_client, captured_request) = capture_request(Some(response)); let client = Client::from_conf(stub_config(http_client.clone())); let instance_type = InstanceType::from("g5.48xlarge"); let mut paginator = client @@ -53,7 +53,10 @@ async fn paginators_handle_empty_tokens() { .send(); let first_item = paginator.try_next().await.expect("success"); assert_eq!(first_item, None); - http_client.assert_requests_match(&[]); + let req = captured_request.expect_request(); + let actual_body = std::str::from_utf8(req.body().bytes().unwrap()).unwrap(); + let expected_body = "Action=DescribeSpotPriceHistory&Version=2016-11-15&AvailabilityZone=eu-north-1a&InstanceType.1=g5.48xlarge&ProductDescription.1=Linux%2FUNIX"; + validate_query_string(expected_body, actual_body); } /// See https://github.com/awslabs/aws-sdk-rust/issues/405 @@ -61,22 +64,16 @@ async fn paginators_handle_empty_tokens() { /// EC2 can also reply with the token truly unset which will be interpreted as `None` #[tokio::test] async fn paginators_handle_unset_tokens() { - let request= "Action=DescribeSpotPriceHistory&Version=2016-11-15&AvailabilityZone=eu-north-1a&InstanceType.1=g5.48xlarge&ProductDescription.1=Linux%2FUNIX"; let response = r#" edf3e86c-4baf-47c1-9228-9a5ea09542e8 "#; - let http_client = StaticReplayClient::new(vec![ReplayEvent::new( - http::Request::builder() - .uri("https://ec2.us-east-1.amazonaws.com/") - .body(request.into()) - .unwrap(), - http::Response::builder() - .status(200) - .body(SdkBody::from(response)) - .unwrap(), - )]); + let response = http::Response::builder() + .status(200) + .body(SdkBody::from(response)) + .unwrap(); + let (http_client, captured_request) = capture_request(Some(response)); let client = Client::from_conf(stub_config(http_client.clone())); let instance_type = InstanceType::from("g5.48xlarge"); let mut paginator = client @@ -89,7 +86,10 @@ async fn paginators_handle_unset_tokens() { .send(); let first_item = paginator.try_next().await.expect("success"); assert_eq!(first_item, None); - http_client.assert_requests_match(&[]); + let req = captured_request.expect_request(); + let actual_body = std::str::from_utf8(req.body().bytes().unwrap()).unwrap(); + let expected_body = "Action=DescribeSpotPriceHistory&Version=2016-11-15&AvailabilityZone=eu-north-1a&InstanceType.1=g5.48xlarge&ProductDescription.1=Linux%2FUNIX"; + validate_query_string(expected_body, actual_body); } #[tokio::test]