Unverified Commit 069ec706 authored by ysaito1001's avatar ysaito1001 Committed by GitHub
Browse files

Render smoke tests for services without support for account ID routing (#3808)

## Motivation and Context
Follow-up on https://github.com/smithy-lang/smithy-rs/pull/3799

## Description
This PR updates the smoke test rendering process for services whose
models specify the `smokeTests` trait
([example](https://github.com/awslabs/aws-sdk-rust/blob/c349073b345a576d18ab7729afc7b75ae273d2ac/aws-models/sns.json#L3392-L3404)).
Previously, `SmokeTestsDecorator` skipped rendering when
`useAccountIdRouting` was set to true in the vendor parameters, which is
the default for `AwsVendorParams`. Even though the Rust SDK does not
currently support the account ID routing, it is safe to render these
tests. This is because existing smoke tests do not rely on this feature,
and when account ID routing is used, the Rust SDK will fall back to
other means to sourcing the identity.

This PR includes a minor fix: it uses `aws_config` to load default
configurations. `config::Builder::new()` would have no credentials
provider chain available, which would then result in test failures at
runtime.
```
---- test_list_certificates_success stdout ----
thread 'test_list_certificates_success' panicked at sdk/acm/tests/smoketests.rs:22:9:
request should succeed: DispatchFailure(DispatchFailure { source: ConnectorError { kind: Other(None), source: NoMatchingAuthSchemeError(ExploredList { items: [ExploredAuthOption { scheme_id: AuthSchemeId { scheme_id: "sigv4" }, result: NoIdentityResolver }], truncated: false }), connection: Unknown } })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

By bringing `aws-config`, the `SmokeTestsDecoratorTest` no longer works,
since the AWS runtime crates required by `aws-config` conflict with
those generated by `awsSdkIntegrationTest` (a known limitation). For
example:
```
error: package collision in the lockfile: packages aws-credential-types v1.2.0 (smithy-rs/aws/rust-runtime/aws-credential-types) and aws-credential-types v1.2.0 (smithy-rs/aws/sdk/build/aws-sdk/sdk/aws-credential-types) are different, but only one can be written to lockfile unambiguously
```
Therefore, we removed `SmokeTestsDecoratorTest.kt` _only_ in this PR to
ship the feature, but are planning to restore it in the next PR by
directly testing `SmokeTestsInstantiator` without using
`awsSdkIntegrationTest`.

## Testing
- [x] Existing tests in CI
- [x] Executed and passed smoke tests for services that support them in
our release pipeline

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 740edcc6
Loading
Loading
Loading
Loading
+11 −9
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.docs
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.core.smithy.PublicImportSymbolProvider
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.generators.BuilderGenerator
import software.amazon.smithy.rust.codegen.core.smithy.generators.BuilderGenerator
import software.amazon.smithy.rust.codegen.core.smithy.generators.Instantiator
import software.amazon.smithy.rust.codegen.core.smithy.generators.Instantiator
@@ -50,12 +51,6 @@ class SmokeTestsDecorator : ClientCodegenDecorator {
                logger.warning("skipping smoketest `${smokeTestCase.id}` with unsupported vendorParam `sigv4aRegionSet`")
                logger.warning("skipping smoketest `${smokeTestCase.id}` with unsupported vendorParam `sigv4aRegionSet`")
                return false
                return false
            }
            }
            // TODO(https://github.com/smithy-lang/smithy-rs/issues/3776) Once Account ID routing is supported,
            //     update the vendorParams setter and remove this check.
            if (vendorParams.useAccountIdRouting()) {
                logger.warning("skipping smoketest `${smokeTestCase.id}` with unsupported vendorParam `useAccountIdRouting`")
                return false
            }
        }
        }
        AwsSmokeTestModel.getS3VendorParams(smokeTestCase)?.orNull()?.let { s3VendorParams ->
        AwsSmokeTestModel.getS3VendorParams(smokeTestCase)?.orNull()?.let { s3VendorParams ->
            if (s3VendorParams.useGlobalEndpoint()) {
            if (s3VendorParams.useGlobalEndpoint()) {
@@ -138,7 +133,7 @@ class SmokeTestsBuilderKindBehavior(val codegenContext: CodegenContext) : Instan
}
}


class SmokeTestsInstantiator(private val codegenContext: ClientCodegenContext) : Instantiator(
class SmokeTestsInstantiator(private val codegenContext: ClientCodegenContext) : Instantiator(
    codegenContext.symbolProvider,
    PublicImportSymbolProvider(codegenContext.symbolProvider, codegenContext.moduleUseName()),
    codegenContext.model,
    codegenContext.model,
    codegenContext.runtimeConfig,
    codegenContext.runtimeConfig,
    SmokeTestsBuilderKindBehavior(codegenContext),
    SmokeTestsBuilderKindBehavior(codegenContext),
@@ -147,9 +142,16 @@ class SmokeTestsInstantiator(private val codegenContext: ClientCodegenContext) :
        writer: RustWriter,
        writer: RustWriter,
        testCase: SmokeTestCase,
        testCase: SmokeTestCase,
    ) {
    ) {
        writer.rust("let conf = config::Builder::new()")
        writer.rust(
            "let config = #{T}::load_defaults(config::BehaviorVersion::latest()).await;",
            AwsCargoDependency.awsConfig(codegenContext.runtimeConfig).toType(),
        )
        writer.rust("let conf = config::Config::from(&config).to_builder()")
        writer.indent()
        writer.indent()
        writer.rust(".behavior_version(config::BehaviorVersion::latest())")

        // TODO(https://github.com/smithy-lang/smithy-rs/issues/3776) Once Account ID routing is supported,
        //  reflect the config setting here, especially to disable it if needed, as it is enabled by default in
        //  `AwsVendorParams`.


        val vendorParams = AwsSmokeTestModel.getAwsVendorParams(testCase)
        val vendorParams = AwsSmokeTestModel.getAwsVendorParams(testCase)
        vendorParams.orNull()?.let { params ->
        vendorParams.orNull()?.let { params ->
+0 −96
Original line number Original line 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 org.junit.jupiter.api.Test
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel

class SmokeTestsDecoratorTest {
    companion object {
        // Can't use the dollar sign in a multiline string with doing it like this.
        private const val PREFIX = "\$version: \"2\""
        val model =
            """
            $PREFIX
            namespace test

            use aws.api#service
            use smithy.test#smokeTests
            use aws.auth#sigv4
            use aws.protocols#restJson1
            use smithy.rules#endpointRuleSet

            @service(sdkId: "dontcare")
            @restJson1
            @sigv4(name: "dontcare")
            @auth([sigv4])
            @endpointRuleSet({
                "version": "1.0",
                "rules": [{ "type": "endpoint", "conditions": [], "endpoint": { "url": "https://example.com" } }],
                "parameters": {
                    "Region": { "required": false, "type": "String", "builtIn": "AWS::Region" },
                }
            })
            service TestService {
                version: "2023-01-01",
                operations: [SomeOperation]
            }

            @smokeTests([
                {
                    id: "SomeOperationSuccess",
                    params: {}
                    vendorParams: {
                        region: "us-west-2"
                    }
                    expect: { success: {} }
                }
                {
                    id: "SomeOperationFailure",
                    params: {}
                    vendorParams: {
                        region: "us-west-2"
                    }
                    expect: { failure: {} }
                }
                {
                    id: "SomeOperationFailureExplicitShape",
                    params: {}
                    vendorParams: {
                        region: "us-west-2"
                    }
                    expect: {
                        failure: { errorId: FooException }
                    }
                }
            ])
            @http(uri: "/SomeOperation", method: "POST")
            @optionalAuth
            operation SomeOperation {
                input: SomeInput,
                output: SomeOutput,
                errors: [FooException]
            }

            @input
            structure SomeInput {}

            @output
            structure SomeOutput {}

            @error("server")
            structure FooException { }
            """.asSmithyModel()
    }

    @Test
    fun smokeTestSdkCodegen() {
        awsSdkIntegrationTest(model) { _, _ ->
            // It should compile. We can't run the tests
            // because they don't target a real service.
        }
    }
}