-
Notifications
You must be signed in to change notification settings - Fork 80
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
feat: Smoke Tests V2 #1791
feat: Smoke Tests V2 #1791
Conversation
…ass SmokeTestGenerator in smithy-swift.
…swift package manifeset generation command.
…test tag. Also, add rm -rf for previously generated smoke test artifacts to codegen.sh script.
…_SMOKE_TEST_SERVICE_IDS environment variable.
…oke tests with each new release.
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.
Comments for reviewers.
@@ -26,6 +26,7 @@ let package = Package( | |||
resources: [ | |||
.process("Resources/Package.Prefix.txt"), | |||
.process("Resources/Package.Base.txt"), | |||
.process("Resources/SmokeTestsPackage.Base.txt"), |
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.
The package manifest for SmokeTests
module will also be generated along with the Package.swift
for aws-sdk-swift
project. The static file SmokeTestsPackage.Base.txt
is appended after generated content during manifest generation, similar to how it's done for root project. Both manifests will use same file for prefix (Package.Prefix.txt
).
/// Returns the list of services that have smoke tests and test runner generated for them. | ||
/// Service names are extracted from service name prefix of directory names under `SmokeTests/`. | ||
/// E.g., extract `AWSS3` from `SmokeTests/AWSS3SmokeTestRunner/`. | ||
/// | ||
/// - Returns: The list of services with generated smoke tests. | ||
func servicesWithSmokeTests() throws -> [String] { | ||
try FileManager.default | ||
.contentsOfDirectory(atPath: "SmokeTests") | ||
.sorted() | ||
.filter { !$0.hasPrefix(".") && $0.hasSuffix("SmokeTestRunner") } | ||
.map { $0.replacingOccurrences(of: "SmokeTestRunner", with: "") } | ||
} | ||
|
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.
Similar logic to getting enabled services - by looking at generated directories.
/// - Parameter contents: The contents of the package manifest. | ||
func savePackageManifest(_ contents: String) throws { | ||
log("Saving package manifest to \(packageFileName)...") | ||
func savePackageManifest(_ contents: String, _ packageFilePath: String) throws { | ||
log("Saving package manifest to \(packageFilePath)...") | ||
try contents.write( | ||
toFile: packageFileName, | ||
toFile: packageFilePath, | ||
atomically: true, | ||
encoding: .utf8 | ||
) |
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.
A small refactor to make this function reusable for different manifest filepaths.
// Generate package manifest for smoke tests and save it as aws-sdk-swift/SmokeTests/Package.swift | ||
let smokeTestsContents = try generateSmokeTestsPackageManifestContents() | ||
try savePackageManifest(smokeTestsContents, "SmokeTests/\(packageFileName)") |
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.
Generate manifest for smoke tests module at SmokeTests/Package.manifest
.
@@ -0,0 +1,39 @@ | |||
// MARK: - Static Content |
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.
The static content of package manifest. The only generated content, which comes right before this, is serviceNames
array which will contain names of all services that have smoke tests. Then, that array is used in this static content for adding all the executable targets and executable products needed to build & run our test runners.
@@ -203,13 +203,23 @@ val AwsService.modelExtrasDir: String | |||
|
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.
Changes in this file adds staging logic for moving generated smoke tests for each service to corresponding directory under SmokeTests/
.
open val protocolTestsToIgnore: Set<String> = setOf() | ||
open val protocolTestTagsToIgnore: Set<String> = setOf() |
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.
Small rename for specifying type of tests these apply to, just for additional clarity.
@@ -0,0 +1,77 @@ | |||
package software.amazon.smithy.aws.swift.codegen |
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.
Extends generic smoke test generator in smithy-swift. Overrides methods to provide AWS specific logic.
// Converts trait definition vendor param key:value pairs to Swift SDK config field:value pairs. | ||
private fun getFormattedVendorParams(vendorParams: ObjectNode): Map<String, String> { | ||
val formattedMapping = mutableMapOf<String, String>() | ||
vendorParams.members.forEach { originalMapping -> | ||
when (originalMapping.key.value) { | ||
/* BaseAwsVendorParams members */ | ||
"region" -> { | ||
// Take region value retrieved from environment variable if present; otherwise, take from trait definition. | ||
val regionValue = "regionFromEnv ?? \"${originalMapping.value.expectStringNode().value}\"" | ||
formattedMapping.put("region", regionValue) | ||
formattedMapping.put("signingRegion", regionValue) | ||
} | ||
"sigv4aRegionSet" -> { /* no-op; setting multiple signing regions in config is unsupported atm. */ } | ||
"uri" -> { formattedMapping.put("endpoint", "\"${originalMapping.value.expectStringNode().value}\"") } | ||
"useFips" -> { formattedMapping.put("useFIPS", originalMapping.value.expectBooleanNode().value.toString()) } | ||
"useDualstack" -> { formattedMapping.put("useDualStack", originalMapping.value.expectBooleanNode().value.toString()) } | ||
"useAccountIdRouting" -> { /* no-op; setting account ID routing in config is unsupported atm. */ } | ||
|
||
/* S3VendorParams members */ | ||
"useAccelerate" -> { formattedMapping.put("accelerate", originalMapping.value.expectBooleanNode().value.toString()) } | ||
"useMultiRegionAccessPoints" -> { | ||
// Name for corresponding config in Swift SDK is: `disableMultiRegionAccessPoints`; value needs to be flipped. | ||
formattedMapping.put("disableMultiRegionAccessPoints", (!(originalMapping.value.expectBooleanNode().value)).toString()) | ||
} | ||
"useGlobalEndpoint", "forcePathStyle", "useArnRegion" -> { | ||
// No change needed for these | ||
formattedMapping.put(originalMapping.key.value, originalMapping.value.expectBooleanNode().value.toString()) | ||
} | ||
} | ||
} | ||
return formattedMapping | ||
} |
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.
This "translates" vendor params officially defined in Smithy vendor param shapes that service teams can use to specify client config values in their smoke tests. There're a couple that we don't have config bindings for yet.
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.
What is the behavior if they use a param we haven't supported yet? Fail codegen or generate without it & presumably fail the test later?
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.
If they use a param we haven't supported yet, the test will be generated without it and test will most likely fail later. If that happens we'll need to disable smoke test temporarily.
@@ -0,0 +1,83 @@ | |||
#!/bin/bash |
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.
Convenience script for running multiple test runner executables based on the comma separated string value of the AWS_SMOKE_TEST_SERVICE_IDS
environment variable. This will be used in internal build system down the line as well.
SmokeTests/placeholder.txt
Outdated
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.
This is a place holder file just to add SmokeTests/
directory to the repo. In Catapult, with each new release, contents of this directory will be cleared out and filled with most up-to-date package manifest and test runners.
… bug. Add convenience script for running every smoke test.
@@ -0,0 +1,46 @@ | |||
#!/bin/bash |
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.
Convenience script for developers to run every smoke test generated under SmokeTests/
with overall test summary printed at the end.
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.
As discussed:
- move smoke test manifest generation to its own CLI command
- .gitignore the generated smoke tests, and we will generate them when we need to run them.
// Converts trait definition vendor param key:value pairs to Swift SDK config field:value pairs. | ||
private fun getFormattedVendorParams(vendorParams: ObjectNode): Map<String, String> { | ||
val formattedMapping = mutableMapOf<String, String>() | ||
vendorParams.members.forEach { originalMapping -> | ||
when (originalMapping.key.value) { | ||
/* BaseAwsVendorParams members */ | ||
"region" -> { | ||
// Take region value retrieved from environment variable if present; otherwise, take from trait definition. | ||
val regionValue = "regionFromEnv ?? \"${originalMapping.value.expectStringNode().value}\"" | ||
formattedMapping.put("region", regionValue) | ||
formattedMapping.put("signingRegion", regionValue) | ||
} | ||
"sigv4aRegionSet" -> { /* no-op; setting multiple signing regions in config is unsupported atm. */ } | ||
"uri" -> { formattedMapping.put("endpoint", "\"${originalMapping.value.expectStringNode().value}\"") } | ||
"useFips" -> { formattedMapping.put("useFIPS", originalMapping.value.expectBooleanNode().value.toString()) } | ||
"useDualstack" -> { formattedMapping.put("useDualStack", originalMapping.value.expectBooleanNode().value.toString()) } | ||
"useAccountIdRouting" -> { /* no-op; setting account ID routing in config is unsupported atm. */ } | ||
|
||
/* S3VendorParams members */ | ||
"useAccelerate" -> { formattedMapping.put("accelerate", originalMapping.value.expectBooleanNode().value.toString()) } | ||
"useMultiRegionAccessPoints" -> { | ||
// Name for corresponding config in Swift SDK is: `disableMultiRegionAccessPoints`; value needs to be flipped. | ||
formattedMapping.put("disableMultiRegionAccessPoints", (!(originalMapping.value.expectBooleanNode().value)).toString()) | ||
} | ||
"useGlobalEndpoint", "forcePathStyle", "useArnRegion" -> { | ||
// No change needed for these | ||
formattedMapping.put(originalMapping.key.value, originalMapping.value.expectBooleanNode().value.toString()) | ||
} | ||
} | ||
} | ||
return formattedMapping | ||
} |
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.
What is the behavior if they use a param we haven't supported yet? Fail codegen or generate without it & presumably fail the test later?
@@ -13,7 +13,7 @@ import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator | |||
class RestXMLProtocolGenerator : AWSHTTPBindingProtocolGenerator(RestXMLCustomizations()) { | |||
override val defaultContentType: String = "application/xml" | |||
override val protocol: ShapeId = RestXmlTrait.ID | |||
override val testsToIgnore: Set<String> = setOf( | |||
override val protocolTestsToIgnore: Set<String> = setOf( |
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.
Is there also a list of smokeTestsToIgnore
or are you just renaming this for clarity?
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.
The latter, just renaming this to clarify.
…ests package manifest generation to its independent subcommand GenerateSmokeTestsPackageManifest.swift.
@@ -0,0 +1,72 @@ | |||
// |
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.
Separate subcommand for generating package manifest for SmokeTests module.
Companion smithy-swift PR: smithy-lang/smithy-swift#841
Issue #
1779
Description of changes
Package.swift
codegen for the new smoke tests moduleNew/existing dependencies impact assessment, if applicable
Conventional Commits
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.