-
Notifications
You must be signed in to change notification settings - Fork 55
feat: aws smoke tests support #1437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 38 commits
602bac1
989d8ec
9ca8f2e
b00ec1f
35708df
2399355
2d98a99
d7a4877
f390f6a
90a93ac
6b288ed
c6701cb
95b553d
5ac3db2
ca30211
08356db
e7fdeff
8f0dec1
431e63e
1706764
bb53c3d
e13e9fc
afc5168
c39f3fe
5dfd004
87fa6bb
c1e0edf
dfcffbb
25b8e8e
8aae6e4
5687f7e
1e35fc7
d465c50
73f694a
774a856
578350b
e2107d7
408b3cf
ecec7e3
ca2fa02
f7c17d6
ea40b9b
c9d266f
d427f65
dc5c114
c6ab629
93c850b
e784343
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package aws.sdk.kotlin.codegen.model.traits.testing | ||
|
|
||
| import software.amazon.smithy.model.node.ObjectNode | ||
| import software.amazon.smithy.model.shapes.ShapeId | ||
| import software.amazon.smithy.model.traits.AnnotationTrait | ||
|
|
||
| /** | ||
| * Indicates the annotated service should always return a failed response. | ||
| * IMPORTANT: This trait is intended for use in integration or E2E tests only, not in real-life smoke tests that run | ||
| * against a service endpoint. | ||
| */ | ||
| class TestFailedResponseTrait(node: ObjectNode) : AnnotationTrait(ID, node) { | ||
| companion object { | ||
| val ID: ShapeId = ShapeId.from("smithy.kotlin.traits#failedResponseTrait") | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Indicates the annotated service should always return a success response. | ||
| * IMPORTANT: This trait is intended for use in integration or E2E tests only, not in real-life smoke tests that run | ||
| * against a service endpoint. | ||
| */ | ||
| class TestSuccessResponseTrait(node: ObjectNode) : AnnotationTrait(ID, node) { | ||
| companion object { | ||
| val ID: ShapeId = ShapeId.from("smithy.kotlin.traits#successResponseTrait") | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| package aws.sdk.kotlin.codegen.smoketests | ||
|
|
||
| import aws.sdk.kotlin.codegen.AwsRuntimeTypes | ||
| import software.amazon.smithy.kotlin.codegen.KotlinSettings | ||
| import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes | ||
| import software.amazon.smithy.kotlin.codegen.core.getContextValue | ||
| import software.amazon.smithy.kotlin.codegen.core.withBlock | ||
| import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration | ||
| import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding | ||
| import software.amazon.smithy.kotlin.codegen.model.hasTrait | ||
| import software.amazon.smithy.kotlin.codegen.rendering.smoketests.* | ||
| import software.amazon.smithy.kotlin.codegen.utils.topDownOperations | ||
| import software.amazon.smithy.model.Model | ||
| import software.amazon.smithy.smoketests.traits.SmokeTestsTrait | ||
|
|
||
| /** | ||
| * Adds support for AWS specific client config during smoke tests code generation. | ||
| */ | ||
| class SmokeTestAwsVendorParamsIntegration : KotlinIntegration { | ||
| override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = | ||
| model.topDownOperations(settings.service).any { it.hasTrait<SmokeTestsTrait>() } | ||
|
|
||
| override val sectionWriters: List<SectionWriterBinding> | ||
| get() = | ||
| dualStackSectionWriters + | ||
| sigv4aRegionSetSectionWriters + | ||
| uriSectionWriters + | ||
| accountIdEndpointSectionWriters + | ||
| regionSectionWriters + | ||
| useAccelerateSectionWriters + | ||
| useMultiRegionAccessPointsSectionWriters + | ||
| useGlobalEndpointSectionWriters | ||
| } | ||
|
|
||
| /** | ||
| * Uses the AWS Kotlin SDK specific name for the dual stack config option i.e. `useDualstack` -> `useDualStack` | ||
| */ | ||
| private val dualStackSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestUseDualStackKey) { writer, _ -> writer.writeInline("useDualStack") }, | ||
| ) | ||
|
|
||
| /** | ||
| * Uses the AWS Kotlin SDK specific name for the sigV4a signing region set option i.e. | ||
| * `sigv4aRegionSet` -> `sigV4aSigningRegionSet`. | ||
| * | ||
| * Converts the modeled sigV4a signing region set from a list to a set. | ||
| * | ||
| * Adds additional config needed for the SDK to make sigV4a calls | ||
| */ | ||
| private val sigv4aRegionSetSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestSigv4aRegionSetKey) { writer, _ -> writer.writeInline("sigV4aSigningRegionSet") }, | ||
| SectionWriterBinding(SmokeTestSigv4aRegionSetValue) { writer, value -> | ||
| writer.write("#L.toSet()", value) | ||
| // TODO: Remove once sigV4a is supported for default signer. | ||
| writer.write( | ||
| "authSchemes = listOf(#T(#T))", | ||
| RuntimeTypes.Auth.HttpAuthAws.SigV4AsymmetricAuthScheme, | ||
| RuntimeTypes.Auth.AwsSigningCrt.CrtAwsSigner, | ||
| ) | ||
| }, | ||
| ) | ||
|
|
||
| /** | ||
| * Ensures we use the provided URI | ||
| */ | ||
| private val uriSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestUriKey) { writer, _ -> writer.writeInline("endpointProvider") }, | ||
| SectionWriterBinding(SmokeTestUriValue) { writer, value -> | ||
| val endpointProvider = writer.getContextValue(SmokeTestUriValue.EndpointProvider) | ||
| val endpointParameters = writer.getContextValue(SmokeTestUriValue.EndpointParameters) | ||
| writer.withBlock("object : #T {", "}", endpointProvider) { | ||
| write( | ||
| "override suspend fun resolveEndpoint(params: #T): #T = #T(#L)", | ||
| endpointParameters, | ||
| RuntimeTypes.SmithyClient.Endpoints.Endpoint, | ||
| RuntimeTypes.SmithyClient.Endpoints.Endpoint, | ||
| value, | ||
| ) | ||
| } | ||
| }, | ||
| ) | ||
|
|
||
| /** | ||
| * Uses the AWS Kotlin SDK specific way of configuring `accountIdEndpointMode` | ||
|
||
| */ | ||
| private val accountIdEndpointSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestAccountIdBasedRoutingKey) { writer, _ -> writer.writeInline("accountIdEndpointMode") }, | ||
| SectionWriterBinding(SmokeTestAccountIdBasedRoutingValue) { writer, value -> | ||
| when (value) { | ||
| "true" -> writer.write("#T.REQUIRED", AwsRuntimeTypes.Config.Endpoints.AccountIdEndpointMode) | ||
| "false" -> writer.write("#T.DISABLED", AwsRuntimeTypes.Config.Endpoints.AccountIdEndpointMode) | ||
| } | ||
| }, | ||
| ) | ||
|
|
||
| /** | ||
| * Gets region override environment variable. | ||
| * | ||
| * Sets region override as default. | ||
| * | ||
| * Sets region override as default client config if no other client config is modelled. | ||
| */ | ||
| private val regionSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestAdditionalEnvVars) { writer, _ -> | ||
| writer.write( | ||
| "private val regionOverride = #T.System.getenv(#S)", | ||
| RuntimeTypes.Core.Utils.PlatformProvider, | ||
| "AWS_SMOKE_TEST_REGION", | ||
| ) | ||
| }, | ||
| SectionWriterBinding(SmokeTestRegionDefault) { writer, _ -> | ||
| writer.writeInline("regionOverride ?: ") | ||
| }, | ||
| SectionWriterBinding(SmokeTestDefaultConfig) { writer, _ -> writer.write("region = regionOverride") }, | ||
| ) | ||
|
|
||
| /** | ||
| * Uses the AWS Kotlin SDK specific name for the S3 accelerate config option i.e. `useAccelerate` -> `enableAccelerate` | ||
| */ | ||
| private val useAccelerateSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestUseAccelerateKey) { writer, _ -> writer.writeInline("enableAccelerate") }, | ||
| ) | ||
|
|
||
| /** | ||
| * Uses the AWS Kotlin SDK specific name for the S3 multi region access points (MRAP) config option i.e. | ||
| * `useMultiRegionAccessPoints` -> `disableMrap`. | ||
| * | ||
| * Our config option is opt out while the modeled config is opt in so we invert the boolean values. | ||
| */ | ||
| private val useMultiRegionAccessPointsSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestUseMultiRegionAccessPointsKey) { writer, _ -> writer.writeInline("disableMrap") }, | ||
| SectionWriterBinding(SmokeTestUseMultiRegionAccessPointsValue) { writer, value -> | ||
| when (value) { | ||
| "true" -> writer.write("false") | ||
| "false" -> writer.write("true") | ||
| } | ||
| }, | ||
| ) | ||
|
|
||
| /** | ||
| * Leaves a comment in the client config whenever the use of the `useGlobalEndpoint` S3 config option is modeled. | ||
| * | ||
| * The SDK does not support this config option. | ||
| * See `BindAwsEndpointBuiltins` & `S3_USE_GLOBAL_ENDPOINT` | ||
| */ | ||
| private val useGlobalEndpointSectionWriters = listOf( | ||
| SectionWriterBinding(SmokeTestUseGlobalEndpoint) { writer, _ -> | ||
| writer.write("// Smoke tests modeled the use of `useGlobalEndpoint` config, but it's not supported by the SDK") | ||
| }, | ||
| ) | ||
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| package aws.sdk.kotlin.codegen.smoketests.testing | ||
|
|
||
| import aws.sdk.kotlin.codegen.model.traits.testing.TestFailedResponseTrait | ||
| import aws.sdk.kotlin.codegen.model.traits.testing.TestSuccessResponseTrait | ||
| import software.amazon.smithy.kotlin.codegen.KotlinSettings | ||
| import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes | ||
| import software.amazon.smithy.kotlin.codegen.core.withBlock | ||
| import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration | ||
| import software.amazon.smithy.kotlin.codegen.integration.SectionWriter | ||
| import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding | ||
| import software.amazon.smithy.kotlin.codegen.model.expectShape | ||
| import software.amazon.smithy.kotlin.codegen.model.hasTrait | ||
| import software.amazon.smithy.kotlin.codegen.rendering.smoketests.SmokeTestHttpEngineOverride | ||
| import software.amazon.smithy.kotlin.codegen.utils.topDownOperations | ||
| import software.amazon.smithy.model.Model | ||
| import software.amazon.smithy.model.shapes.ServiceShape | ||
| import software.amazon.smithy.smoketests.traits.SmokeTestsTrait | ||
|
|
||
| /** | ||
| * Adds [TestFailedResponseTrait] support to smoke tests | ||
| * IMPORTANT: This integration is intended for use in integration or E2E tests only, not in real-life smoke tests that run | ||
| * against a service endpoint. | ||
| */ | ||
| class SmokeTestFailHttpEngineIntegration : KotlinIntegration { | ||
| override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = | ||
| model.topDownOperations(settings.service).any { it.hasTrait<SmokeTestsTrait>() } && | ||
| !model.expectShape<ServiceShape>(settings.service).hasTrait(TestSuccessResponseTrait.ID) && | ||
| model.expectShape<ServiceShape>(settings.service).hasTrait(TestFailedResponseTrait.ID) | ||
|
|
||
| override val sectionWriters: List<SectionWriterBinding> | ||
| get() = listOf( | ||
| SectionWriterBinding(SmokeTestHttpEngineOverride, httpClientOverride), | ||
| ) | ||
|
|
||
| private val httpClientOverride = SectionWriter { writer, _ -> | ||
| writer.withBlock("httpClient = #T(", ")", RuntimeTypes.HttpTest.TestEngine) { | ||
| withBlock("roundTripImpl = { _, request ->", "}") { | ||
| write( | ||
| "val resp = #T(#T.BadRequest, #T.Empty, #T.Empty)", | ||
| RuntimeTypes.Http.Response.HttpResponse, | ||
| RuntimeTypes.Http.StatusCode, | ||
| RuntimeTypes.Http.Headers, | ||
| RuntimeTypes.Http.HttpBody, | ||
| ) | ||
| write("val now = #T.now()", RuntimeTypes.Core.Instant) | ||
| write("#T(request, resp, now, now)", RuntimeTypes.Http.HttpCall) | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package aws.sdk.kotlin.codegen.smoketests.testing | ||
|
|
||
| import aws.sdk.kotlin.codegen.model.traits.testing.TestFailedResponseTrait | ||
| import aws.sdk.kotlin.codegen.model.traits.testing.TestSuccessResponseTrait | ||
| import software.amazon.smithy.kotlin.codegen.KotlinSettings | ||
| import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes | ||
| import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration | ||
| import software.amazon.smithy.kotlin.codegen.integration.SectionWriter | ||
| import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding | ||
| import software.amazon.smithy.kotlin.codegen.model.expectShape | ||
| import software.amazon.smithy.kotlin.codegen.model.hasTrait | ||
| import software.amazon.smithy.kotlin.codegen.rendering.smoketests.SmokeTestHttpEngineOverride | ||
| import software.amazon.smithy.kotlin.codegen.utils.topDownOperations | ||
| import software.amazon.smithy.model.Model | ||
| import software.amazon.smithy.model.shapes.ServiceShape | ||
| import software.amazon.smithy.smoketests.traits.SmokeTestsTrait | ||
|
|
||
| /** | ||
| * Adds [TestSuccessResponseTrait] support to smoke tests | ||
| * IMPORTANT: This integration is intended for use in integration or E2E tests only, not in real-life smoke tests that run | ||
| * against a service endpoint. | ||
| */ | ||
| class SmokeTestSuccessHttpEngineIntegration : KotlinIntegration { | ||
| override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = | ||
| model.topDownOperations(settings.service).any { it.hasTrait<SmokeTestsTrait>() } && | ||
| model.expectShape<ServiceShape>(settings.service).hasTrait(TestSuccessResponseTrait.ID) && | ||
| !model.expectShape<ServiceShape>(settings.service).hasTrait(TestFailedResponseTrait.ID) | ||
|
|
||
| override val sectionWriters: List<SectionWriterBinding> | ||
| get() = listOf( | ||
| SectionWriterBinding(SmokeTestHttpEngineOverride, httpClientOverride), | ||
| ) | ||
|
|
||
| private val httpClientOverride = SectionWriter { writer, _ -> | ||
| writer.write("httpClient = #T()", RuntimeTypes.HttpTest.TestEngine) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consistency:
Configures static endpoint on an SDK client