Unverified Commit 547b6317 authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Remove temporary test customizations (#3044)

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 38375a5a
Loading
Loading
Loading
Loading
+0 −134
Original line number Diff line number Diff line
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

package software.amazon.smithy.rustsdk

import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.generators.client.CustomizableOperationCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.client.CustomizableOperationSection
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType

class CustomizableOperationTestHelpers(runtimeConfig: RuntimeConfig) :
    CustomizableOperationCustomization() {
    private val codegenScope = arrayOf(
        *RuntimeType.preludeScope,
        "AwsUserAgent" to AwsRuntimeType.awsHttp(runtimeConfig).resolve("user_agent::AwsUserAgent"),
        "BeforeTransmitInterceptorContextMut" to RuntimeType.beforeTransmitInterceptorContextMut(runtimeConfig),
        "ConfigBag" to RuntimeType.configBag(runtimeConfig),
        "http" to CargoDependency.Http.toType(),
        "InterceptorContext" to RuntimeType.interceptorContext(runtimeConfig),
        "RuntimeComponentsBuilder" to RuntimeType.runtimeComponentsBuilder(runtimeConfig),
        "SharedInterceptor" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::interceptors::SharedInterceptor"),
        "StaticRuntimePlugin" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::runtime_plugin::StaticRuntimePlugin"),
        "StaticTimeSource" to CargoDependency.smithyAsync(runtimeConfig).toType().resolve("time::StaticTimeSource"),
        "TestParamsSetterInterceptor" to testParamsSetterInterceptor(),
    )

    // TODO(enableNewSmithyRuntimeCleanup): Delete this once test helpers on `CustomizableOperation` have been removed
    private fun testParamsSetterInterceptor(): RuntimeType = RuntimeType.forInlineFun("TestParamsSetterInterceptor", ClientRustModule.Client.customize) {
        rustTemplate(
            """
            mod test_params_setter_interceptor {
                use aws_smithy_runtime_api::box_error::BoxError;
                use aws_smithy_runtime_api::client::interceptors::context::BeforeTransmitInterceptorContextMut;
                use aws_smithy_runtime_api::client::interceptors::Interceptor;
                use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
                use aws_smithy_types::config_bag::ConfigBag;
                use std::fmt;

                pub(super) struct TestParamsSetterInterceptor<F> { f: F }

                impl<F> fmt::Debug for TestParamsSetterInterceptor<F> {
                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                        write!(f, "TestParamsSetterInterceptor")
                    }
                }

                impl<F> TestParamsSetterInterceptor<F> {
                    pub fn new(f: F) -> Self { Self { f } }
                }

                impl<F> Interceptor for TestParamsSetterInterceptor<F>
                where
                    F: Fn(&mut BeforeTransmitInterceptorContextMut<'_>, &mut ConfigBag) + Send + Sync + 'static,
                {
                    fn name(&self) -> &'static str {
                        "TestParamsSetterInterceptor"
                    }

                    fn modify_before_signing(
                        &self,
                        context: &mut BeforeTransmitInterceptorContextMut<'_>,
                        _runtime_components: &RuntimeComponents,
                        cfg: &mut ConfigBag,
                    ) -> Result<(), BoxError> {
                        (self.f)(context, cfg);
                        Ok(())
                    }
                }
            }
            use test_params_setter_interceptor::TestParamsSetterInterceptor;
            """,
            *codegenScope,
        )
    }

    override fun section(section: CustomizableOperationSection): Writable =
        writable {
            if (section is CustomizableOperationSection.CustomizableOperationImpl) {
                // TODO(enableNewSmithyRuntimeCleanup): Delete these utilities
                rustTemplate(
                    """
                    ##[doc(hidden)]
                    // This is a temporary method for testing. NEVER use it in production
                    pub fn request_time_for_tests(self, request_time: ::std::time::SystemTime) -> Self {
                        self.runtime_plugin(
                            #{StaticRuntimePlugin}::new()
                                .with_runtime_components(
                                    #{RuntimeComponentsBuilder}::new("request_time_for_tests")
                                        .with_time_source(Some(#{StaticTimeSource}::new(request_time)))
                                )
                        )
                    }

                    ##[doc(hidden)]
                    // This is a temporary method for testing. NEVER use it in production
                    pub fn user_agent_for_tests(mut self) -> Self {
                        let interceptor = #{TestParamsSetterInterceptor}::new(|context: &mut #{BeforeTransmitInterceptorContextMut}<'_>, _: &mut #{ConfigBag}| {
                            let headers = context.request_mut().headers_mut();
                            let user_agent = #{AwsUserAgent}::for_tests();
                            headers.insert(
                                #{http}::header::USER_AGENT,
                                #{http}::HeaderValue::try_from(user_agent.ua_header()).unwrap(),
                            );
                            headers.insert(
                                #{http}::HeaderName::from_static("x-amz-user-agent"),
                                #{http}::HeaderValue::try_from(user_agent.aws_ua_header()).unwrap(),
                            );
                        });
                        self.interceptors.push(#{SharedInterceptor}::new(interceptor));
                        self
                    }

                    ##[doc(hidden)]
                    // This is a temporary method for testing. NEVER use it in production
                    pub fn remove_invocation_id_for_tests(mut self) -> Self {
                        let interceptor = #{TestParamsSetterInterceptor}::new(|context: &mut #{BeforeTransmitInterceptorContextMut}<'_>, _: &mut #{ConfigBag}| {
                            context.request_mut().headers_mut().remove("amz-sdk-invocation-id");
                        });
                        self.interceptors.push(#{SharedInterceptor}::new(interceptor));
                        self
                    }
                    """,
                    *codegenScope,
                )
            }
        }
}
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ class AwsFluentClientDecorator : ClientCodegenDecorator {
                AwsPresignedFluentBuilderMethod(codegenContext),
                AwsFluentClientDocs(codegenContext),
            ),
        ).render(rustCrate, listOf(CustomizableOperationTestHelpers(runtimeConfig)))
        ).render(rustCrate, emptyList())
        rustCrate.withModule(ClientRustModule.client) {
            AwsFluentClientExtensions(codegenContext, types).render(this)
        }
+10 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ class UserAgentDecorator : ClientCodegenDecorator {
        private val codegenScope = arrayOf(
            *preludeScope,
            "AppName" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("app_name::AppName"),
            "AwsUserAgent" to AwsRuntimeType.awsHttp(runtimeConfig).resolve("user_agent::AwsUserAgent"),
        )

        override fun section(section: ServiceConfig): Writable =
@@ -158,6 +159,15 @@ class UserAgentDecorator : ClientCodegenDecorator {
                    )
                }

                is ServiceConfig.DefaultForTests -> writable {
                    rustTemplate(
                        """
                        self.config.store_put(#{AwsUserAgent}::for_tests());
                        """,
                        *codegenScope,
                    )
                }

                else -> emptySection
            }
    }
+5 −1
Original line number Diff line number Diff line
@@ -10,11 +10,15 @@ publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = ["test-util"]
test-util = []

[dev-dependencies]
aws-credential-types = { path = "../../build/aws-sdk/sdk/aws-credential-types", features = ["test-util"] }
aws-http = { path = "../../build/aws-sdk/sdk/aws-http" }
aws-runtime = { path = "../../build/aws-sdk/sdk/aws-runtime" }
aws-sdk-kms = { path = "../../build/aws-sdk/sdk/kms" }
aws-sdk-kms = { path = "../../build/aws-sdk/sdk/kms", features = ["test-util"] }
aws-smithy-async = { path = "../../build/aws-sdk/sdk/aws-smithy-async", features = ["test-util"] }
aws-smithy-http = { path = "../../build/aws-sdk/sdk/aws-smithy-http" }
aws-smithy-types = { path = "../../build/aws-sdk/sdk/aws-smithy-types" }
+8 −12
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@ use aws_smithy_runtime::client::http::test_util::{ReplayEvent, StaticReplayClien
use http::header::AUTHORIZATION;
use http::Uri;
use kms::config::{Config, Credentials, Region};
use std::time::{Duration, UNIX_EPOCH};

// TODO(DVR): having the full HTTP requests right in the code is a bit gross, consider something
// like https://github.com/davidbarsky/sigv4/blob/master/aws-sigv4/src/lib.rs#L283-L315 to store
@@ -45,6 +44,7 @@ async fn generate_random_cn() {
    http_client.assert_requests_match(&[]);
}

#[cfg(feature = "test-util")]
#[tokio::test]
async fn generate_random() {
    let http_client = StaticReplayClient::new(vec![ReplayEvent::new(
@@ -52,9 +52,8 @@ async fn generate_random() {
            .header("content-type", "application/x-amz-json-1.1")
            .header("x-amz-target", "TrentService.GenerateRandom")
            .header("content-length", "20")
            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20210305/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, Signature=2e0dd7259fba92523d553173c452eba8a6ee7990fb5b1f8e2eccdeb75309e9e1")
            .header("x-amz-date", "20210305T134922Z")
            .header("x-amz-security-token", "notarealsessiontoken")
            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target;x-amz-user-agent, Signature=53dcf70f6f852cb576185dcabef5aaa3d068704cf1b7ea7dc644efeaa46674d7")
            .header("x-amz-date", "20090213T233130Z")
            .header("user-agent", "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0")
            .header("x-amz-user-agent", "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0")
            .uri(Uri::from_static("https://kms.us-east-1.amazonaws.com/"))
@@ -67,6 +66,7 @@ async fn generate_random() {
        .http_client(http_client.clone())
        .region(Region::new("us-east-1"))
        .credentials_provider(Credentials::for_tests_with_session_token())
        .with_test_defaults()
        .build();
    let client = kms::Client::from_conf(conf);
    let resp = client
@@ -77,8 +77,6 @@ async fn generate_random() {
            // Remove the invocation ID since the signed request above doesn't have it
            req.headers_mut().remove("amz-sdk-invocation-id");
        })
        .request_time_for_tests(UNIX_EPOCH + Duration::from_secs(1614952162))
        .user_agent_for_tests()
        .send()
        .await
        .expect("request should succeed");
@@ -118,6 +116,7 @@ async fn generate_random_malformed_response() {
        .expect_err("response was malformed");
}

#[cfg(feature = "test-util")]
#[tokio::test]
async fn generate_random_keystore_not_found() {
    let http_client = StaticReplayClient::new(vec![ReplayEvent::new(
@@ -125,9 +124,8 @@ async fn generate_random_keystore_not_found() {
            .header("content-type", "application/x-amz-json-1.1")
            .header("x-amz-target", "TrentService.GenerateRandom")
            .header("content-length", "56")
            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20210305/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-target, Signature=4ca5cde61676c0ee49fde9ba3c886967e8af16461b6aafdfaee18033eb4ac7a5")
            .header("x-amz-date", "20210305T144724Z")
            .header("x-amz-security-token", "notarealsessiontoken")
            .header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-target, Signature=ffef92c6b75d66cc511daa896eb4a085ec053a2592e17d1f22ecaf167f2fa4bb")
            .header("x-amz-date", "20090213T233130Z")
            .header("user-agent", "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0")
            .header("x-amz-user-agent", "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0")
            .uri(Uri::from_static("https://kms.us-east-1.amazonaws.com/"))
@@ -147,6 +145,7 @@ async fn generate_random_keystore_not_found() {
        .http_client(http_client.clone())
        .region(Region::new("us-east-1"))
        .credentials_provider(Credentials::for_tests_with_session_token())
        .with_test_defaults()
        .build();
    let client = kms::Client::from_conf(conf);

@@ -154,9 +153,6 @@ async fn generate_random_keystore_not_found() {
        .generate_random()
        .number_of_bytes(64)
        .custom_key_store_id("does not exist")
        .customize()
        .request_time_for_tests(UNIX_EPOCH + Duration::from_secs(1614955644))
        .user_agent_for_tests()
        .send()
        .await
        .expect_err("key store doesn't exist");
Loading