-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: aws smoke tests support (#1437)
- Loading branch information
Showing
17 changed files
with
805 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
...dk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/model/traits/testing/SmokeTestTraits.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
} | ||
} |
160 changes: 160 additions & 0 deletions
160
.../main/kotlin/aws/sdk/kotlin/codegen/smoketests/AwsSmokeTestsRunnerGeneratorIntegration.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
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 | ||
|
||
/** | ||
* Generates AWS specific code for smoke test runners | ||
*/ | ||
class AwsSmokeTestsRunnerGeneratorIntegration : KotlinIntegration { | ||
override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = | ||
model.topDownOperations(settings.service).any { it.hasTrait<SmokeTestsTrait>() } | ||
|
||
override val sectionWriters: List<SectionWriterBinding> | ||
get() = listOf( | ||
AwsSmokeTestsRunnerGenerator.regionEnvironmentVariable, | ||
AwsSmokeTestsRunnerGenerator.clientConfig, | ||
AwsSmokeTestsRunnerGenerator.defaultClientConfig, | ||
AwsSmokeTestsRunnerGenerator.skipTagsEnvironmentVariable, | ||
AwsSmokeTestsRunnerGenerator.serviceFilterEnvironmentVariable, | ||
) | ||
} | ||
|
||
/** | ||
* The section writer bindings used by [AwsSmokeTestsRunnerGeneratorIntegration] | ||
*/ | ||
private object AwsSmokeTestsRunnerGenerator { | ||
/** | ||
* Adds region environment variable support to AWS smoke test runners. | ||
* Preserves other environment variables added via section writer binding, if any. | ||
*/ | ||
val regionEnvironmentVariable = | ||
SectionWriterBinding(SmokeTestSectionIds.AdditionalEnvironmentVariables) { writer, previous -> | ||
writer.write("#L", previous) | ||
writer.write( | ||
"private val regionOverride = #T.System.getenv(#S)", | ||
RuntimeTypes.Core.Utils.PlatformProvider, | ||
AWS_REGION, | ||
) | ||
} | ||
|
||
/** | ||
* Add AWS specific client config support to AWS smoke test runners | ||
*/ | ||
val clientConfig = | ||
SectionWriterBinding(SmokeTestSectionIds.ClientConfig) { writer, _ -> | ||
val name = writer.getContextValue(SmokeTestSectionIds.ClientConfig.Name) | ||
val value = writer.getContextValue(SmokeTestSectionIds.ClientConfig.Value) | ||
|
||
// Normalize client config names | ||
val newName = when (name) { | ||
"uri" -> "endpointProvider" | ||
"useDualstack" -> "useDualStack" | ||
"sigv4aRegionSet" -> "sigV4aSigningRegionSet" | ||
"useAccountIdRouting" -> "accountIdEndpointMode" | ||
"useAccelerate" -> "enableAccelerate" | ||
"useMultiRegionAccessPoints" -> "disableMrap" | ||
"useGlobalEndpoint" -> { | ||
writer.write("throw #T(#S)", RuntimeTypes.Core.SmokeTests.SmokeTestsException, "'useGlobalEndpoint' is not supported by the SDK") | ||
return@SectionWriterBinding | ||
} | ||
else -> name | ||
} | ||
writer.writeInline("#L = ", newName) | ||
|
||
// Normalize client values | ||
when (newName) { | ||
"endpointProvider" -> { | ||
val endpointProvider = writer.getContextValue(SmokeTestSectionIds.ClientConfig.EndpointProvider) | ||
val endpointParameters = writer.getContextValue(SmokeTestSectionIds.ClientConfig.EndpointParams) | ||
|
||
writer.withBlock("object : #T {", "}", endpointProvider) { | ||
write( | ||
"override suspend fun resolveEndpoint(params: #1T): #2T = #2T(#3L)", | ||
endpointParameters, | ||
RuntimeTypes.SmithyClient.Endpoints.Endpoint, | ||
value, | ||
) | ||
} | ||
} | ||
"sigV4aSigningRegionSet" -> { | ||
// Render new value | ||
writer.write("#L.toSet()", value) | ||
// Also configure sigV4a - TODO: Remove once sigV4a is supported for default signer. | ||
writer.write( | ||
"authSchemes = listOf(#T(#T))", | ||
RuntimeTypes.Auth.HttpAuthAws.SigV4AsymmetricAuthScheme, | ||
RuntimeTypes.Auth.AwsSigningCrt.CrtAwsSigner, | ||
) | ||
} | ||
"accountIdEndpointMode" -> { | ||
when (value) { | ||
"true" -> writer.write("#T.REQUIRED", AwsRuntimeTypes.Config.Endpoints.AccountIdEndpointMode) | ||
"false" -> writer.write("#T.DISABLED", AwsRuntimeTypes.Config.Endpoints.AccountIdEndpointMode) | ||
} | ||
} | ||
"disableMrap" -> { | ||
when (value) { | ||
"true" -> writer.write("false") | ||
"false" -> writer.write("true") | ||
} | ||
} | ||
"region" -> { | ||
writer.write("regionOverride ?: #L", value) | ||
} | ||
else -> writer.write("#L", value) | ||
} | ||
} | ||
|
||
/** | ||
* Add default client config to AWS smoke test runners. | ||
* Preserves previous default config if any. | ||
*/ | ||
val defaultClientConfig = | ||
SectionWriterBinding(SmokeTestSectionIds.DefaultClientConfig) { writer, previous -> | ||
writer.write("#L", previous) | ||
writer.write("region = regionOverride") | ||
} | ||
|
||
/** | ||
* Replaces environment variable with one specific to AWS smoke test runners | ||
*/ | ||
val skipTagsEnvironmentVariable = | ||
SectionWriterBinding(SmokeTestSectionIds.SkipTags) { writer, _ -> writer.writeInline("#S", AWS_SKIP_TAGS) } | ||
|
||
/** | ||
* Replaces environment variable with one specific to AWS smoke test runners | ||
*/ | ||
val serviceFilterEnvironmentVariable = | ||
SectionWriterBinding(SmokeTestSectionIds.ServiceFilter) { writer, _ -> writer.writeInline("#S", AWS_SERVICE_FILTER) } | ||
} | ||
|
||
/** | ||
* Env var for AWS smoke test runners. | ||
* Should be a string that corresponds to an AWS region. | ||
* The region to use when executing smoke tests. This value MUST override any value supplied in the smoke tests themselves. | ||
*/ | ||
private const val AWS_REGION = "AWS_SMOKE_TEST_REGION" | ||
|
||
/** | ||
* Env var for AWS smoke test runners. | ||
* Should be a comma-delimited list of strings that correspond to tags on the test cases. | ||
* If a test case is tagged with one of the tags indicated by AWS_SMOKE_TEST_SKIP_TAGS, it MUST be skipped by the smoke test runner. | ||
*/ | ||
const val AWS_SKIP_TAGS = "AWS_SMOKE_TEST_SKIP_TAGS" | ||
|
||
/** | ||
* Env var for AWS smoke test runners. | ||
* Should be a comma-separated list of service identifiers to test. | ||
*/ | ||
const val AWS_SERVICE_FILTER = "AWS_SMOKE_TEST_SERVICE_IDS" |
37 changes: 0 additions & 37 deletions
37
...odegen/src/main/kotlin/aws/sdk/kotlin/codegen/smoketests/SmokeTestsDenyListIntegration.kt
This file was deleted.
Oops, something went wrong.
50 changes: 50 additions & 0 deletions
50
...in/kotlin/aws/sdk/kotlin/codegen/smoketests/testing/SmokeTestFailHttpEngineIntegration.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.SmokeTestSectionIds | ||
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(SmokeTestSectionIds.HttpEngineOverride, 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) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.