diff --git a/AWSSDKSwiftCLI/Sources/AWSCLIUtils/Process+Swift.swift b/AWSSDKSwiftCLI/Sources/AWSCLIUtils/Process+Swift.swift deleted file mode 100644 index b4213a3a227..00000000000 --- a/AWSSDKSwiftCLI/Sources/AWSCLIUtils/Process+Swift.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation - -public extension Process { - struct Swift { - /// Returns a process for executing swift commands. - private func swiftProcess(_ args: [String]) -> Process { - Process(["swift"] + args) - } - - /// Returns a process for executing `swift test` - public func test() -> Process { - swiftProcess(["test"]) - } - } - - static var swift: Swift { Swift() } -} diff --git a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/AWSSDKSwiftCLI.swift b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/AWSSDKSwiftCLI.swift index af3d28df8dc..2fe34a07ef4 100644 --- a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/AWSSDKSwiftCLI.swift +++ b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/AWSSDKSwiftCLI.swift @@ -16,7 +16,6 @@ struct AWSSDKSwiftCLI: ParsableCommand { GeneratePackageManifestCommand.self, PrepareReleaseCommand.self, SyncClientRuntimeVersionCommand.self, - TestAWSSDKCommand.self, GenerateDocIndexCommand.self, GenerateSmokeTestsPackageManifestCommand.self ] diff --git a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/Subcommands/TestAWSSDK.swift b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/Subcommands/TestAWSSDK.swift deleted file mode 100644 index d8a507b02b7..00000000000 --- a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/Subcommands/TestAWSSDK.swift +++ /dev/null @@ -1,195 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -import Algorithms -import ArgumentParser -import Foundation -import AWSCLIUtils - -// MARK: - Command - -struct TestAWSSDKCommand: ParsableCommand { - static var configuration = CommandConfiguration( - commandName: "test-aws-sdk", - abstract: "Builds the package and executes its tests", - discussion: "swift test" - ) - - @Argument(help: "The path to the aws-sdk-swift repository") - var repoPath: String - - @Option(help: "The number of test batches") - var batches: UInt = 1 - - func run() throws { - let testAWSSDK = TestAWSSDK.standard(repoPath: repoPath, batches: batches) - try testAWSSDK.run() - } -} - -// MARK: - TestAWSSDK - -struct TestAWSSDK { - /// The path to the aws-sdk-swift repository - let repoPath: String - - /// The number of test batches - /// The actual number of batches may be smaller depending on the number of services. - /// For example, if the total number of services is 8, and the number of batches is 5, then the actual number of test batches will be 4 - let batches: UInt - - typealias PackageManifestGenerator = ( - _ packageFileName: String, - _ services: [String] - ) throws -> Void - /// Generates a package manifest using the proivide file name and list of services - let generatePackageManifest: PackageManifestGenerator - - private let packageFileName = "Package.swift" - private let copiedPackageFileName = "Package.copy.swift" - - func run() throws { - try FileManager.default.changeWorkingDirectory(repoPath) - - // If batches is 1, then run `swift test` with the current Package.swift - guard batches > 1 else { - log("Testing Package.swift...") - let task = Process.swift.test() - try _run(task) - return - } - - // Create batches of services - let serviceBatches = try createBatches(Int(batches)) - - // Create package manifests for each batch - let packageManifests = try createPackageManifests(serviceBatches) - - // Test each package manifest - try testAllPackages(packageManifests) - } - - // MARK: - Helpers - - /// Returns batches of services - /// Attempts to create `batches` number of batches, but the actual number of batches may be smaller. For example, if the total number of services is 8, and the provided number of batches is 5, this will return 4 batches. - func createBatches(_ batches: Int) throws -> ChunksOfCountCollection<[String]> { - log("Attempting to create \(batches) batches...") - let services = try FileManager.default.enabledServices() - let chunkSize: Int = { - guard services.count >= batches else { - log("Number of batches (\(batches)) provided is greater than the number of services (\(services.count)). Using \(services.count) instead.") - return 1 - } - return Int(ceil(Double(services.count) / Double(batches))) - }() - let serviceBatches = services.chunks(ofCount: chunkSize) - log("Created \(serviceBatches.count) batches...") - return serviceBatches - } - - /// Creates package manifests for each batch in the provided list. - /// Returns a list of the package manifests file names - func createPackageManifests(_ serviceBatches: ChunksOfCountCollection<[String]>) throws -> [String] { - var packageManifests: [String] = [] - - for (index, serviceList) in serviceBatches.enumerated() { - // Create the package manifest for each batch - let packageManifest = "Package.TestBatch\(index + 1).swift" - let services = Array(serviceList) - try generatePackageManifest(packageManifest, services) - packageManifests.append(packageManifest) - log(""" - Created batch \(index + 1) - * Manifest: \(packageManifest) - * Size: \(services.count) - * First Service: \(services.first!) - * Last Service: \(services.last!) - """) - } - - return packageManifests - } - - /// Runs tests for each package manifest in the provided list - func testAllPackages(_ packageManifests: [String]) throws { - // Move the current Package.swift to a new file to be restored later - try renamePackageManifest() - - // Run 'swift test' for each package manifest - try packageManifests.forEach(testPackage) - - // Restor the original package manifest - try restorePackageManifest() - } - - /// Runs tests using the provided package manifest - /// - /// This renames the provided package to `Package.swift` and then runs `swift test` - /// When finished, it renames `Package.swift` back to the provided package file name. - /// - func testPackage(_ package: String) throws { - log("Testing \(package)...") - // Set this package as the Package.swift - try FileManager.default.moveItem( - atPath: package, - toPath: packageFileName - ) - let task = Process.swift.test() - try _run(task) - - // Move the file back when we are finished - try FileManager.default.moveItem( - atPath: packageFileName, - toPath: package - ) - } - - /// Moves the original `Package.swift` to `Package.copy.swift` - func renamePackageManifest() throws { - try FileManager.default.moveItem( - atPath: packageFileName, - toPath: copiedPackageFileName - ) - } - - /// Restores the original package manifest to `Package.swift` - func restorePackageManifest() throws { - try FileManager.default.moveItem( - atPath: copiedPackageFileName, - toPath: packageFileName - ) - } -} - -// MARK: - Factory - -extension TestAWSSDK { - /// Returns the standard aws sdk tester - /// - /// - Parameters: - /// - repoPath: The path to the aws-sdk-swift respository - /// - batches: The number of test batches - /// - /// - Returns: The standard aws sdk tester - static func standard( - repoPath: String, - batches: UInt - ) -> Self { - TestAWSSDK( - repoPath: repoPath, - batches: batches - ) { packageFileName, services in - let command = GeneratePackageManifest.standard( - repoPath: ".", - packageFileName: packageFileName, - services: services - ) - try command.run() - } - } -} diff --git a/AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Commands/TestAWSSDKTests.swift b/AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Commands/TestAWSSDKTests.swift deleted file mode 100644 index 98364600c18..00000000000 --- a/AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Commands/TestAWSSDKTests.swift +++ /dev/null @@ -1,239 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -@testable import AWSSDKSwiftCLI -import Algorithms -import XCTest -import AWSCLIUtils - -class TestAWSSDKTests: CLITestCase { - - // MARK: - Helpers - - func createServiceFolders(_ services: [String]) { - services.forEach { - try! FileManager.default.createDirectory( - atPath: "Sources/Services/\($0)", - withIntermediateDirectories: true - ) - } - } - - func createGoldenPathEnvironment() throws { - let services = ["A", "B", "C", "D", "E", "F", "G", "H"] - - // Create services - createServiceFolders(services) - - // Create packageDependencies.plist - let deps = try PackageDependencies( - awsCRTSwiftVersion: .init("1.2.3"), - clientRuntimeVersion: .init("3.2.1") - ) - try! deps.save() - - // Create Package.swift - let contents = "// package manifest" - try! contents.write( - toFile: "Package.swift", - atomically: true, encoding: .utf8 - ) - } - - // MARK: - Tests - - // MARK: Golden Path - - func testGoldenPath() throws { - try createGoldenPathEnvironment() - - var commands: [String] = [] - let runner = ProcessRunner { - commands.append($0.commandString) - } - ProcessRunner.testRunner = runner - - var packages: [String] = [] - - let subject = TestAWSSDK.mock(batches: 4) { packageFileName, services in - packages.append("\(packageFileName) \(services.joined(separator: "-"))") - try! "\(packageFileName)".write( - toFile: packageFileName, - atomically: true, encoding: .utf8 - ) - } - try! subject.run() - - XCTAssertEqual(commands.count, 4) - XCTAssertTrue(commands.allSatisfy { $0.hasSuffix("swift test") }) - XCTAssertEqual(packages, [ - "Package.TestBatch1.swift A-B", - "Package.TestBatch2.swift C-D", - "Package.TestBatch3.swift E-F", - "Package.TestBatch4.swift G-H", - ]) - } - - func testRunWhenBatchesIsOne() { - let services = ["A", "B", "C", "D", "E", "F", "G", "H"] - createServiceFolders(services) - var commands: [String] = [] - let runner = ProcessRunner { - commands.append($0.commandString) - } - ProcessRunner.testRunner = runner - let subject = TestAWSSDK.mock(batches: 1) - try! subject.run() - - XCTAssertEqual(commands.count, 1) - XCTAssertTrue(commands[0].hasSuffix("swift test")) - } - - // MARK: createBatches() - - func testCreateBatches() { - let services = ["A", "B", "C", "D", "E", "F", "G", "H"] - createServiceFolders(services) - let subject = TestAWSSDK.mock() - - let result1 = try! subject.createBatches(1) - XCTAssertServiceBatchEquals(result1, [["A", "B", "C", "D", "E", "F", "G", "H"]]) - - let result2 = try! subject.createBatches(2) - XCTAssertServiceBatchEquals(result2, [["A", "B", "C", "D"], ["E", "F", "G", "H"]]) - - let result3 = try! subject.createBatches(3) - XCTAssertServiceBatchEquals(result3, [["A", "B", "C"], ["D", "E", "F"], ["G", "H"]]) - - let result4 = try! subject.createBatches(4) - XCTAssertServiceBatchEquals(result4, [["A", "B"], ["C", "D"], ["E", "F"], ["G", "H"]]) - - let result5 = try! subject.createBatches(5) - XCTAssertServiceBatchEquals(result5, [["A", "B"], ["C", "D"], ["E", "F"], ["G", "H"]]) - - let result6 = try! subject.createBatches(6) - XCTAssertServiceBatchEquals(result6, [["A", "B"], ["C", "D"], ["E", "F"], ["G", "H"]]) - - let result7 = try! subject.createBatches(7) - XCTAssertServiceBatchEquals(result7, [["A", "B"], ["C", "D"], ["E", "F"], ["G", "H"]]) - - let result8 = try! subject.createBatches(8) - XCTAssertServiceBatchEquals(result8, [["A"], ["B"], ["C"], ["D"], ["E"], ["F"], ["G"], ["H"]]) - - let result9 = try! subject.createBatches(100) - XCTAssertServiceBatchEquals(result9, [["A"], ["B"], ["C"], ["D"], ["E"], ["F"], ["G"], ["H"]]) - } - - // MARK: testPackage() - - func testPackage() { - let packageName = "Package.TestBatch1.swift" - let contents = "// package manifest" - try! contents.write( - toFile: packageName, - atomically: true, encoding: .utf8 - ) - var command: String! - var testBatchContents: String! - let runner = ProcessRunner { - command = $0.commandString - testBatchContents = try! String( - contentsOfFile: "Package.swift", - encoding: .utf8 - ) - } - ProcessRunner.testRunner = runner - - let subject = TestAWSSDK.mock() - try! subject.testPackage(packageName) - - let packageContents = try? String( - contentsOfFile: "Package.swift", - encoding: .utf8 - ) - - XCTAssertTrue(command.hasSuffix("swift test")) - XCTAssertEqual(testBatchContents, contents) - XCTAssertNil(packageContents) - } - - // MARK: renamePackageManifest() - - func testRenamePackageManifest() { - let contents = "// package manifest" - try! contents.write( - toFile: "Package.swift", - atomically: true, encoding: .utf8 - ) - let subject = TestAWSSDK.mock() - try! subject.renamePackageManifest() - let newPackage = try! String( - contentsOfFile: "Package.copy.swift", - encoding: .utf8 - ) - let oldPackage = try? String( - contentsOfFile: "Package.swift", - encoding: .utf8 - ) - XCTAssertEqual(newPackage, contents) - XCTAssertNil(oldPackage) - } - - // MARK: - restorePackageManifest() - - func testRestorePackageManifest() { - let contents = "// package manifest" - try! contents.write( - toFile: "Package.copy.swift", - atomically: true, encoding: .utf8 - ) - let subject = TestAWSSDK.mock() - try! subject.restorePackageManifest() - let copy = try? String( - contentsOfFile: "Package.copy.swift", - encoding: .utf8 - ) - let original = try! String( - contentsOfFile: "Package.swift", - encoding: .utf8 - ) - XCTAssertEqual(original, contents) - XCTAssertNil(copy) - } -} - -// MARK: - Mocks - -extension TestAWSSDK { - static func mock( - repoPath: String = ".", - batches: UInt = 1, - generatePackageManifest: @escaping PackageManifestGenerator = { _,_ in } - ) -> Self { - TestAWSSDK( - repoPath: repoPath, - batches: batches, - generatePackageManifest: generatePackageManifest - ) - } -} - -// MARK: - XCTAssert - -func XCTAssertServiceBatchEquals( - _ batches: @autoclosure () throws -> ChunksOfCountCollection<[String]>, - _ expected: @autoclosure () throws -> [[String]], - _ message: @autoclosure () -> String = "", - file: StaticString = #filePath, - line: UInt = #line -) { - let _batches = try! batches() - let _expected = try! expected() - for (i, batch) in _batches.enumerated() { - XCTAssertEqual(Array(batch), _expected[i]) - } -}