Skip to content
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!: Standalone integration test package #1585

Merged
merged 20 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,13 @@ jobs:
TOKEN_ESCAPED=`echo -n "$AWS_SESSION_TOKEN" | jq -Rsa .`
# Insert the credentials into the .xctestplan file, write the modified JSON
# to a temp file, then move the temp over the original.
jq ".defaultOptions.environmentVariableEntries += [{\"key\": \"AWS_ACCESS_KEY_ID\", \"value\": $AKID_ESCAPED}, {\"key\": \"AWS_SECRET_ACCESS_KEY\", \"value\": $SECRET_ESCAPED}, {\"key\": \"AWS_DEFAULT_REGION\", \"value\": $REGION_ESCAPED}, {\"key\": \"AWS_SESSION_TOKEN\", \"value\": $TOKEN_ESCAPED}]" XCTestPlans/AWSIntegrationTestsOnCI.xctestplan > testplan.tmp
mv testplan.tmp XCTestPlans/AWSIntegrationTestsOnCI.xctestplan
jq ".defaultOptions.environmentVariableEntries += [{\"key\": \"AWS_ACCESS_KEY_ID\", \"value\": $AKID_ESCAPED}, {\"key\": \"AWS_SECRET_ACCESS_KEY\", \"value\": $SECRET_ESCAPED}, {\"key\": \"AWS_DEFAULT_REGION\", \"value\": $REGION_ESCAPED}, {\"key\": \"AWS_SESSION_TOKEN\", \"value\": $TOKEN_ESCAPED}]" IntegrationTests/XCTestPlans/AWSIntegrationTestsOnCI.xctestplan > testplan.tmp
mv testplan.tmp IntegrationTests/XCTestPlans/AWSIntegrationTestsOnCI.xctestplan
- name: Prepare Integration Tests
run: ./scripts/ci_steps/prepare_integration_tests.sh
- name: Run Integration Tests
run: |
cd IntegrationTests
set -o pipefail && \
NSUnbufferedIO=YES xcodebuild \
-scheme AWSIntegrationTestsOnCI \
Expand Down Expand Up @@ -192,6 +193,12 @@ jobs:
- name: Prepare Integration Tests
run: ./scripts/ci_steps/prepare_integration_tests.sh
- name: Build Integration Tests
run: swift build --build-tests
run: |
cd IntegrationTests
swift build --build-tests
cd ..
- name: Run Integration Tests
run: swift test
run: |
cd IntegrationTests
swift test
cd ..
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ struct GeneratePackageManifestCommand: ParsableCommand {
@Option(help: "The names of the services to include in the package manifest. This defaults to all services located in aws-sdk-swift/Sources/Services")
var services: [String] = []

@Flag(help: "If the package manifest should include the integration tests.")
var includeIntegrationTests: Bool = false

@Flag(help: "If the package manifest should include the protocol tests.")
var includeProtocolTests: Bool = false

Expand All @@ -51,7 +48,6 @@ struct GeneratePackageManifestCommand: ParsableCommand {
clientRuntimeVersion: clientRuntimeVersion,
crtVersion: crtVersion,
services: services.isEmpty ? nil : services,
includeIntegrationTests: includeIntegrationTests,
includeProtocolTests: includeProtocolTests,
excludeAWSServices: excludeAWSServices,
excludeRuntimeTests: excludeRuntimeTests
Expand All @@ -77,8 +73,6 @@ struct GeneratePackageManifest {
/// The list of services to include as products
/// If `nil` then the list is populated with the names of all items within the `Sources/Services` directory
let services: [String]?
/// If the package manifest should include the integration tests.
let includeIntegrationTests: Bool
/// If the package manifest should include the protocol tests.
let includeProtocolTests: Bool
/// If the package manifest should exclude the AWS services.
Expand All @@ -93,7 +87,7 @@ struct GeneratePackageManifest {
) throws -> String
/// Returns the contents of the package manifest file given the versions of dependencies and the list of services.
let buildPackageManifest: BuildPackageManifest

/// Generates a package manifest file and saves it to `packageFileName`
func run() throws {
try FileManager.default.changeWorkingDirectory(repoPath)
Expand All @@ -109,19 +103,13 @@ struct GeneratePackageManifest {
/// - Returns: The contents of the generated package manifest.
func generatePackageManifestContents() throws -> String {
let versions = try resolveVersions()
let servicesWithIntegrationTests = try resolveServicesWithIntegrationTests()
let services = try resolveServices().map {
PackageManifestBuilder.Service(
name: $0,
includeIntegrationTests: servicesWithIntegrationTests.contains($0)
)
}
let services = try resolveServices().map { PackageManifestBuilder.Service(name: $0) }
log("Creating package manifest contents...")
let contents = try buildPackageManifest(versions.clientRuntime, versions.crt, services)
log("Successfully created package manifest contents")
return contents
}

/// Saves the package manifest file.
/// If no file exists, then this will create a new file. Otherwise, this will overwrite the existing file.
///
Expand All @@ -135,7 +123,7 @@ struct GeneratePackageManifest {
)
log("Successfully saved package manifest to \(packageFileName)")
}

/// Returns the versions for ClientRuntime and CRT.
/// If explcit versions are provided by the command, then this returns the specified versions.
/// Otherwise, this returns the versions defined in `packageDependencies.plist`.
Expand All @@ -153,35 +141,35 @@ struct GeneratePackageManifest {
}
let resolvedClientRuntime: Version
let resolvedCRT: Version

if let explicitVersion = self.clientRuntimeVersion {
resolvedClientRuntime = explicitVersion
log("Using ClientRuntime version provided: \(resolvedClientRuntime.description)")
} else {
resolvedClientRuntime = packageDependencies.value.clientRuntimeVersion
log("Using ClientRuntime version loaded from file: \(resolvedClientRuntime.description)")
}

if let explicitVersion = self.crtVersion {
resolvedCRT = explicitVersion
log("Using CRT version provided: \(resolvedCRT.description)")
} else {
resolvedCRT = packageDependencies.value.awsCRTSwiftVersion
log("Using CRT version loaded from file: \(resolvedCRT.description)")
}

log("""
Resolved versions of dependencies:
* ClientRuntime: \(resolvedClientRuntime.description)
* CRT: \(resolvedCRT.description)
""")

return (
clientRuntime: resolvedClientRuntime,
crt: resolvedCRT
)
}

/// Returns the list of services to include in the package manifest.
/// If an explicit list of services was provided by the command, then this returns the specified services.
/// Otherwise, this returns the list of services that exist within `Sources/Services`
Expand All @@ -200,21 +188,6 @@ struct GeneratePackageManifest {
log("Resolved list of services: \(resolvedServices.count)")
return resolvedServices
}

/// Returns the list of services to include in the package manifest.
/// If an explicit list of services was provided by the command, then this returns the specified services.
/// Otherwise, this returns the list of services that exist within `Sources/Services`
///
/// - Returns: The list of services to include in the package manifest
func resolveServicesWithIntegrationTests() throws -> [String] {
log("Resolving services with integration tests...")
let resolvedServices = try FileManager
.default
.integrationTests()
.map { $0.replacingOccurrences(of: "IntegrationTests", with: "") }
log("List of services with integration tests: \(resolvedServices.count)")
return resolvedServices
}
}

// MARK: - Factory
Expand All @@ -237,7 +210,6 @@ extension GeneratePackageManifest {
clientRuntimeVersion: Version? = nil,
crtVersion: Version? = nil,
services: [String]? = nil,
includeIntegrationTests: Bool = false,
includeProtocolTests: Bool = false,
excludeAWSServices: Bool = false,
excludeRuntimeTests: Bool = false
Expand All @@ -248,7 +220,6 @@ extension GeneratePackageManifest {
clientRuntimeVersion: clientRuntimeVersion,
crtVersion: crtVersion,
services: services,
includeIntegrationTests: includeIntegrationTests,
includeProtocolTests: includeProtocolTests,
excludeAWSServices: excludeAWSServices,
excludeRuntimeTests: excludeRuntimeTests
Expand All @@ -258,7 +229,6 @@ extension GeneratePackageManifest {
crtVersion: _crtVersion,
services: _services,
includeProtocolTests: includeProtocolTests,
includeIntegrationTests: includeIntegrationTests,
excludeAWSServices: excludeAWSServices,
excludeRuntimeTests: excludeRuntimeTests
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ import PackageDescription
struct PackageManifestBuilder {
struct Service {
let name: String
let includeIntegrationTests: Bool
}

let clientRuntimeVersion: Version
let crtVersion: Version
let services: [Service]
let includeProtocolTests: Bool
let includeIntegrationTests: Bool
let excludeAWSServices: Bool
let excludeRuntimeTests: Bool
let basePackageContents: () throws -> String
Expand All @@ -29,7 +27,6 @@ struct PackageManifestBuilder {
crtVersion: Version,
services: [Service],
includeProtocolTests: Bool,
includeIntegrationTests: Bool,
excludeAWSServices: Bool,
excludeRuntimeTests: Bool,
basePackageContents: @escaping () throws -> String
Expand All @@ -38,7 +35,6 @@ struct PackageManifestBuilder {
self.crtVersion = crtVersion
self.services = services
self.includeProtocolTests = includeProtocolTests
self.includeIntegrationTests = includeIntegrationTests
self.excludeAWSServices = excludeAWSServices
self.basePackageContents = basePackageContents
self.excludeRuntimeTests = excludeRuntimeTests
Expand All @@ -49,11 +45,10 @@ struct PackageManifestBuilder {
crtVersion: Version,
services: [Service],
includeProtocolTests: Bool,
includeIntegrationTests: Bool,
excludeAWSServices: Bool,
excludeRuntimeTests: Bool
) {
self.init(clientRuntimeVersion: clientRuntimeVersion, crtVersion: crtVersion, services: services, includeProtocolTests: includeProtocolTests, includeIntegrationTests: includeIntegrationTests, excludeAWSServices: excludeAWSServices, excludeRuntimeTests: excludeRuntimeTests) {
self.init(clientRuntimeVersion: clientRuntimeVersion, crtVersion: crtVersion, services: services, includeProtocolTests: includeProtocolTests, excludeAWSServices: excludeAWSServices, excludeRuntimeTests: excludeRuntimeTests) {
// Returns the contents of the base package manifest stored in the bundle at `Resources/Package.Base.swift`
let basePackageName = "Package.Base"

Expand Down Expand Up @@ -101,9 +96,6 @@ struct PackageManifestBuilder {
// Add the generated content that defines the list of services to include
buildServiceTargets(),
"",
// Add the generated content that defines the list of services with integration tests to include
buildIntegrationTestsTargets(),
"",
buildProtocolTests(),
"",
buildResolvedServices(),
Expand Down Expand Up @@ -152,21 +144,6 @@ struct PackageManifestBuilder {
return lines.joined(separator: .newline)
}

/// Builds the list of services to add integration test targets for..
/// This generates an array of strings, where the each item is a name of a service
/// and calls the `addIntegrationTestTarget` for each item.
private func buildIntegrationTestsTargets() -> String {
var lines: [String] = []
lines += ["let servicesWithIntegrationTests: [String] = ["]
lines += services.filter(\.includeIntegrationTests).map { " \($0.name.wrappedInQuotes())," }
lines += ["]"]
lines += [""]
lines += ["// Uncomment this line to enable integration tests"]
lines += ["\(includeIntegrationTests ? "" : "// ")addIntegrationTests()"]

return lines.joined(separator: .newline)
}

/// Calls the method to include protocol tests in the manifest.
private func buildProtocolTests() -> String {
return [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,46 +228,6 @@ func addServiceUnitTestTarget(_ name: String) {
]
}

func addIntegrationTestTarget(_ name: String) {
let integrationTestName = "\(name)IntegrationTests"
var additionalDependencies: [String] = []
var exclusions: [String] = []
switch name {
case "AWSEC2":
additionalDependencies = ["AWSIAM", "AWSSTS", "AWSCloudWatchLogs"]
exclusions = [
"Resources/IMDSIntegTestApp"
]
case "AWSECS":
additionalDependencies = ["AWSCloudWatchLogs", "AWSEC2", "AWSIAM", "AWSSTS"]
exclusions = [
"README.md",
"Resources/ECSIntegTestApp/"
]
case "AWSS3":
additionalDependencies = ["AWSSSOAdmin", "AWSS3Control", "AWSSTS"]
case "AWSEventBridge":
additionalDependencies = ["AWSRoute53"]
case "AWSCloudFrontKeyValueStore":
additionalDependencies = ["AWSCloudFront"]
case "AWSSTS":
additionalDependencies = ["AWSIAM", "AWSCognitoIdentity"]
default:
break
}
integrationTestServices.insert(name)
additionalDependencies.forEach { integrationTestServices.insert($0) }
package.targets += [
.testTarget(
name: integrationTestName,
dependencies: [.crt, .clientRuntime, .awsClientRuntime, .byName(name: name), .smithyTestUtils, .awsSDKIdentity, .smithyIdentity, .awsSDKCommon] + additionalDependencies.map { Target.Dependency.target(name: $0, condition: nil) },
path: "./IntegrationTests/Services/\(integrationTestName)",
exclude: exclusions,
resources: [.process("Resources")]
)
]
}

var enabledServices = Set<String>()
var enabledServiceUnitTests = Set<String>()

Expand All @@ -276,12 +236,6 @@ func addAllServices() {
enabledServiceUnitTests = Set(serviceTargets)
}

var integrationTestServices = Set<String>()

func addIntegrationTests() {
servicesWithIntegrationTests.forEach { addIntegrationTestTarget($0) }
}

func excludeRuntimeUnitTests() {
package.targets.removeAll {
$0.name == "AWSClientRuntimeTests" ||
Expand Down Expand Up @@ -344,6 +298,6 @@ func addProtocolTests() {
}

func addResolvedTargets() {
enabledServices.union(integrationTestServices).forEach(addServiceTarget)
enabledServices.forEach(addServiceTarget)
enabledServiceUnitTests.forEach(addServiceUnitTestTarget)
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ extension GeneratePackageManifest {
clientRuntimeVersion: Version? = nil,
crtVersion: Version? = nil,
services: [String]? = nil,
includesIntegrationTests: Bool = false,
includeProtocolTests: Bool = false,
excludeAWSServices: Bool = false,
excludeRuntimeTests: Bool = false,
Expand All @@ -126,7 +125,6 @@ extension GeneratePackageManifest {
clientRuntimeVersion: clientRuntimeVersion,
crtVersion: crtVersion,
services: services,
includeIntegrationTests: includesIntegrationTests,
includeProtocolTests: includeProtocolTests,
excludeAWSServices: excludeAWSServices,
excludeRuntimeTests: excludeRuntimeTests,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@ let serviceTargets: [String] = [
// Uncomment this line to enable all services
addAllServices()

let servicesWithIntegrationTests: [String] = [
"A",
"B",
"C",
"D",
"E",
]

// Uncomment this line to enable integration tests
// addIntegrationTests()

// Uncomment this line to enable protocol tests
// addProtocolTests()

Expand All @@ -57,9 +46,8 @@ addResolvedTargets()
let subject = PackageManifestBuilder(
clientRuntimeVersion: .init("1.2.3"),
crtVersion: .init("4.5.6"),
services: ["A","B","C","D","E"].map { PackageManifestBuilder.Service(name: $0, includeIntegrationTests: true) },
services: ["A","B","C","D","E"].map { PackageManifestBuilder.Service(name: $0) },
includeProtocolTests: false,
includeIntegrationTests: false,
excludeAWSServices: false,
excludeRuntimeTests: false,
basePackageContents: { "<contents of base package>" }
Expand Down
Loading
Loading