diff --git a/IntegrationTests/Tests/IntegrationTests/SwiftPMTests.swift b/IntegrationTests/Tests/IntegrationTests/SwiftPMTests.swift index 8ef4c6e9504..e34bc16fc25 100644 --- a/IntegrationTests/Tests/IntegrationTests/SwiftPMTests.swift +++ b/IntegrationTests/Tests/IntegrationTests/SwiftPMTests.swift @@ -57,11 +57,27 @@ final class SwiftPMTests: XCTestCase { #endif // Test SwiftBuildSystem - try withTemporaryDirectory { tmpDir in - let packagePath = tmpDir.appending(component: "foo") - try localFileSystem.createDirectory(packagePath) - try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "executable") - try sh(swiftBuild, "--package-path", packagePath, "--build-system", "swiftbuild") + do { + try withTemporaryDirectory { tmpDir in + let packagePath = tmpDir.appending(component: "foo") + try localFileSystem.createDirectory(packagePath) + try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "executable") + try sh(swiftBuild, "--package-path", packagePath, "--build-system", "swiftbuild") + // SWBINTTODO: Path issues related to swift run of the output from swiftbuild buildsystem + //let (stdout, stderr) = try sh(swiftRun, "--package-path", packagePath, "--build-system", "swiftbuild") + //XCTAssertMatch(stdout, .contains("Hello, world!")) + } + } + + do { + try withTemporaryDirectory { tmpDir in + let packagePath = tmpDir.appending(component: "foo") + try localFileSystem.createDirectory(packagePath) + try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "library") + try sh(swiftBuild, "--package-path", packagePath, "--build-system", "swiftbuild") + // SWBINTTODO: Path issues related to swift test of the output from a swiftbuild buildsystem + //try sh(swiftTest, "--package-path", packagePath, "--build-system", "swiftbuild") + } } } diff --git a/Sources/CoreCommands/SwiftCommandState.swift b/Sources/CoreCommands/SwiftCommandState.swift index 70a7ce9699b..e3d9d6a89ae 100644 --- a/Sources/CoreCommands/SwiftCommandState.swift +++ b/Sources/CoreCommands/SwiftCommandState.swift @@ -1029,7 +1029,7 @@ extension BuildSystemProvider.Kind { return false } } - + fileprivate var additionalFileRules: [FileRuleDescription] { switch self { case .xcode, .swiftbuild: diff --git a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift index 712ecbf5018..2055628f179 100644 --- a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift +++ b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift @@ -256,16 +256,18 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { header: "" ) - do { - try await withSession(service: service, name: self.buildParameters.pifManifest.pathString) { session, _ in - // Load the workspace, and set the system information to the default - do { - try await session.loadWorkspace(containerPath: self.buildParameters.pifManifest.pathString) - try await session.setSystemInfo(.default()) - } catch { - self.observabilityScope.emit(error: error.localizedDescription) - throw error - } + do { + try await withSession(service: service, name: self.buildParameters.pifManifest.pathString) { session, _ in + self.outputStream.send("Building for \(self.buildParameters.configuration == .debug ? "debugging" : "production")...\n") + + // Load the workspace, and set the system information to the default + do { + try await session.loadWorkspace(containerPath: self.buildParameters.pifManifest.pathString) + try await session.setSystemInfo(.default()) + } catch { + self.observabilityScope.emit(error: error.localizedDescription) + throw error + } // Find the targets to build. let configuredTargets: [SWBConfiguredTarget] diff --git a/Sources/_InternalTestSupport/misc.swift b/Sources/_InternalTestSupport/misc.swift index 9febddfa75a..b435a1808b0 100644 --- a/Sources/_InternalTestSupport/misc.swift +++ b/Sources/_InternalTestSupport/misc.swift @@ -117,6 +117,10 @@ public func testWithTemporaryDirectory( } } +public enum TestError: Error { + case platformNotSupported +} + @discardableResult public func fixture( name: String, createGitRepo: Bool = true, @@ -252,7 +256,7 @@ public func getBuildSystemArgs(for buildSystem: BuildSystemProvider.Kind?) -> [S @discardableResult public func executeSwiftBuild( - _ packagePath: AbsolutePath, + _ packagePath: AbsolutePath?, configuration: Configuration = .Debug, extraArgs: [String] = [], Xcc: [String] = [], @@ -274,8 +278,8 @@ public func executeSwiftBuild( @discardableResult public func executeSwiftRun( - _ packagePath: AbsolutePath, - _ executable: String, + _ packagePath: AbsolutePath?, + _ executable: String?, configuration: Configuration = .Debug, extraArgs: [String] = [], Xcc: [String] = [], @@ -292,13 +296,15 @@ public func executeSwiftRun( Xswiftc: Xswiftc, buildSystem: buildSystem ) - args.append(executable) + if let executable { + args.append(executable) + } return try await SwiftPM.Run.execute(args, packagePath: packagePath, env: env) } @discardableResult public func executeSwiftPackage( - _ packagePath: AbsolutePath, + _ packagePath: AbsolutePath?, configuration: Configuration = .Debug, extraArgs: [String] = [], Xcc: [String] = [], @@ -320,7 +326,7 @@ public func executeSwiftPackage( @discardableResult public func executeSwiftPackageRegistry( - _ packagePath: AbsolutePath, + _ packagePath: AbsolutePath?, configuration: Configuration = .Debug, extraArgs: [String] = [], Xcc: [String] = [], @@ -342,13 +348,14 @@ public func executeSwiftPackageRegistry( @discardableResult public func executeSwiftTest( - _ packagePath: AbsolutePath, + _ packagePath: AbsolutePath?, configuration: Configuration = .Debug, extraArgs: [String] = [], Xcc: [String] = [], Xld: [String] = [], Xswiftc: [String] = [], env: Environment? = nil, + throwIfCommandFails: Bool = false, buildSystem: BuildSystemProvider.Kind = .native ) async throws -> (stdout: String, stderr: String) { let args = swiftArgs( @@ -359,7 +366,7 @@ public func executeSwiftTest( Xswiftc: Xswiftc, buildSystem: buildSystem ) - return try await SwiftPM.Test.execute(args, packagePath: packagePath, env: env) + return try await SwiftPM.Test.execute(args, packagePath: packagePath, env: env, throwIfCommandFails: throwIfCommandFails) } private func swiftArgs( diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index f11fb8734cf..7b7a6c28541 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -47,7 +47,7 @@ extension Build.BuildPlan { class BuildPlanTestCase: BuildSystemProviderTestCase { override func setUpWithError() throws { - try XCTSkipIf(type(of: self) == BuildPlanTestCase.self, "Pay no attention to the class behind the curtain.") + try XCTSkipIf(type(of: self) == BuildPlanTestCase.self, "Skipping this test since it will be run in subclasses that will provide different build systems to test.") } let inputsDir = AbsolutePath(#file).parentDirectory.appending(components: "Inputs") diff --git a/Tests/CommandsTests/APIDiffTests.swift b/Tests/CommandsTests/APIDiffTests.swift index 8b01ed364b3..b8473e4c253 100644 --- a/Tests/CommandsTests/APIDiffTests.swift +++ b/Tests/CommandsTests/APIDiffTests.swift @@ -13,6 +13,7 @@ import Basics import Build import Commands +import SPMBuildCore @_spi(SwiftPMInternal) import DriverSupport @@ -24,7 +25,11 @@ import _InternalTestSupport import Workspace import XCTest -final class APIDiffTests: CommandsTestCase { +class APIDiffTestCase: CommandsBuildProviderTestCase { + override func setUpWithError() throws { + try XCTSkipIf(type(of: self) == APIDiffTestCase.self, "Skipping this test since it will be run in subclasses that will provide different build systems to test.") + } + @discardableResult private func execute( _ args: [String], @@ -34,7 +39,12 @@ final class APIDiffTests: CommandsTestCase { var environment = env ?? [:] // don't ignore local packages when caching environment["SWIFTPM_TESTS_PACKAGECACHE"] = "1" - return try await SwiftPM.Package.execute(args, packagePath: packagePath, env: environment) + return try await executeSwiftPackage( + packagePath, + extraArgs: args, + env: environment, + buildSystem: buildSystemProvider + ) } func skipIfApiDigesterUnsupportedOrUnset() throws { @@ -444,3 +454,26 @@ final class APIDiffTests: CommandsTestCase { } } } + +class APIDiffNativeTests: APIDiffTestCase { + + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .native + } + + override func skipIfApiDigesterUnsupportedOrUnset() throws { + try super.skipIfApiDigesterUnsupportedOrUnset() + } + +} + +class APIDiffSwiftBuildTests: APIDiffTestCase { + + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .swiftbuild + } + + override func skipIfApiDigesterUnsupportedOrUnset() throws { + try super.skipIfApiDigesterUnsupportedOrUnset() + } +} diff --git a/Tests/CommandsTests/BuildCommandTests.swift b/Tests/CommandsTests/BuildCommandTests.swift index 3f84d1a86e0..56eec94e650 100644 --- a/Tests/CommandsTests/BuildCommandTests.swift +++ b/Tests/CommandsTests/BuildCommandTests.swift @@ -19,6 +19,7 @@ import PackageLoading import PackageModel import SPMBuildCore import _InternalTestSupport +import TSCTestSupport import Workspace import XCTest @@ -30,14 +31,24 @@ struct BuildResult { let moduleContents: [String] } -final class BuildCommandTests: CommandsTestCase { +class BuildCommandTestCases: CommandsBuildProviderTestCase { + + override func setUpWithError() throws { + try XCTSkipIf(type(of: self) == BuildCommandTestCases.self, "Skipping this test since it will be run in subclasses that will provide different build systems to test.") + } + @discardableResult private func execute( _ args: [String] = [], environment: Environment? = nil, packagePath: AbsolutePath? = nil ) async throws -> (stdout: String, stderr: String) { - try await SwiftPM.Build.execute(args, packagePath: packagePath, env: environment) + return try await executeSwiftBuild( + packagePath, + extraArgs: args, + env: environment, + buildSystem: buildSystemProvider + ) } func build(_ args: [String], packagePath: AbsolutePath? = nil, isRelease: Bool = false, cleanAfterward: Bool = true) async throws -> BuildResult { @@ -62,7 +73,11 @@ final class BuildCommandTests: CommandsTestCase { let moduleContents = (try? localFileSystem.getDirectoryContents(binPath.appending(component: "Modules"))) ?? [] if cleanAfterward { - try! await SwiftPM.Package.execute(["clean"], packagePath: packagePath) + try! await executeSwiftPackage( + packagePath, + extraArgs: ["clean"], + buildSystem: buildSystemProvider + ) } return BuildResult( binPath: binPath, @@ -73,7 +88,11 @@ final class BuildCommandTests: CommandsTestCase { ) } catch { if cleanAfterward { - try! await SwiftPM.Package.execute(["clean"], packagePath: packagePath) + try! await executeSwiftPackage( + packagePath, + extraArgs: ["clean"], + buildSystem: buildSystemProvider + ) } throw error } @@ -89,12 +108,6 @@ final class BuildCommandTests: CommandsTestCase { XCTAssertMatch(stdout, .contains("SEE ALSO: swift run, swift package, swift test")) } - func testCommandDoesNotEmitDuplicateSymbols() async throws { - let (stdout, stderr) = try await execute(["--help"]) - XCTAssertNoMatch(stdout, duplicateSymbolRegex) - XCTAssertNoMatch(stderr, duplicateSymbolRegex) - } - func testVersion() async throws { let stdout = try await execute(["--version"]).stdout XCTAssertMatch(stdout, .regex(#"Swift Package Manager -( \w+ )?\d+.\d+.\d+(-\w+)?"#)) @@ -171,7 +184,7 @@ final class BuildCommandTests: CommandsTestCase { } } - func testBinPathAndSymlink() async throws { + func testBinSymlink() async throws { try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in let fullPath = try resolveSymlinks(fixturePath) let targetPath = try fullPath.appending( @@ -188,12 +201,15 @@ final class BuildCommandTests: CommandsTestCase { "\(targetPath.appending("release").pathString)\n" ) - // Print correct path when building with XCBuild. - #if os(macOS) - let xcodeDebugOutput = try await execute(["--build-system", "xcode", "--show-bin-path"], packagePath: fullPath) + guard buildSystemProvider == .xcode || buildSystemProvider == .swiftbuild else { + return + } + + // Print correct path when building with XCBuild or Swift Build + let xcodeDebugOutput = try await execute(["--show-bin-path"], packagePath: fullPath) .stdout let xcodeReleaseOutput = try await execute( - ["--build-system", "xcode", "-c", "release", "--show-bin-path"], + ["-c", "release", "--show-bin-path"], packagePath: fullPath ).stdout XCTAssertEqual( @@ -204,8 +220,16 @@ final class BuildCommandTests: CommandsTestCase { xcodeReleaseOutput, "\(xcbuildTargetPath.appending(components: "Products", "Release").pathString)\n" ) - #endif + } + } + func testSymlink() async throws { + try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in + let fullPath = try resolveSymlinks(fixturePath) + let targetPath = try fullPath.appending( + components: ".build", + UserToolchain.default.targetTriple.platformBuildPathComponent + ) // Test symlink. try await self.execute(packagePath: fullPath) XCTAssertEqual( @@ -232,7 +256,11 @@ final class BuildCommandTests: CommandsTestCase { do { let (_, stderr) = try await execute(["--product", "lib1"], packagePath: fullPath) - try await SwiftPM.Package.execute(["clean"], packagePath: fullPath) + try await executeSwiftPackage( + fullPath, + extraArgs:["clean"], + buildSystem: buildSystemProvider + ) XCTAssertMatch( stderr, .contains( @@ -418,15 +446,15 @@ final class BuildCommandTests: CommandsTestCase { } } - private func testBuildSystemDefaultSettings(buildSystem: String) async throws { + func testBuildSystemDefaultSettings() async throws { try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in // try await building using XCBuild with default parameters. This should succeed. We build verbosely so we get // full command lines. - let output = try await execute(["--build-system", buildSystem, "-c", "debug", "-v"], packagePath: fixturePath) + let output = try await execute(["-c", "debug", "-v"], packagePath: fixturePath) // In the case of the native build system check for the cross-compile target, only for macOS #if os(macOS) - if buildSystem == "native" { + if buildSystemProvider == .native { XCTAssertMatch( output.stdout, try .contains("-target \(UserToolchain.default.targetTriple.tripleString(forPlatformVersion: ""))") @@ -437,53 +465,26 @@ final class BuildCommandTests: CommandsTestCase { // Look for build completion message from the particular build system XCTAssertMatch( output.stdout, - try .contains("Build complete!") + .contains("Build complete!") ) } } - func testNativeBuildSystemDefaultSettings() async throws { - try await self.testBuildSystemDefaultSettings(buildSystem: "native") - } - - #if os(macOS) - func testXcodeBuildSystemDefaultSettings() async throws { - // TODO figure out in what circumstance the xcode build system test can run. - throw XCTSkip("Xcode build system test is not working in test") - - try await self.testBuildSystemDefaultSettings(buildSystem: "xcode") - } - #endif - - func testSwiftBuildSystemDefaultSettings() async throws { - #if os(Linux) - if FileManager.default.contents(atPath: "/etc/system-release").map { String(decoding: $0, as: UTF8.self) == "Amazon Linux release 2 (Karoo)\n" } ?? false { - throw XCTSkip("Skipping SwiftBuild testing on Amazon Linux because of platform issues.") - } - #endif - - if ProcessInfo.processInfo.environment["SWIFTPM_NO_SWBUILD_DEPENDENCY"] != nil { - throw XCTSkip("SWIFTPM_NO_SWBUILD_DEPENDENCY is set so skipping because SwiftPM doesn't have the swift-build capability built inside.") - } - - try await testBuildSystemDefaultSettings(buildSystem: "swiftbuild") - } - func testXcodeBuildSystemWithAdditionalBuildFlags() async throws { try XCTSkipIf( true, "Disabled for now because it is hitting 'IR generation failure: Cannot read legacy layout file' in CI (rdar://88828632)" ) - #if !os(macOS) - try XCTSkipIf(true, "test requires `xcbuild` and is therefore only supported on macOS") - #endif + guard buildSystemProvider == .xcode || buildSystemProvider == .swiftbuild else { + throw XCTSkip("This test only works with the xcode or swift build build system") + } + try await fixture(name: "ValidLayouts/SingleModule/ExecutableMixed") { fixturePath in // try await building using XCBuild with additional flags. This should succeed. We build verbosely so we get // full command lines. let defaultOutput = try await execute( [ - "--build-system", "xcode", "-c", "debug", "-v", "-Xlinker", "-rpath", "-Xlinker", "/fakerpath", "-Xcc", "-I/cfakepath", @@ -501,10 +502,11 @@ final class BuildCommandTests: CommandsTestCase { } } - func testXcodeBuildSystemOverrides() async throws { - #if !os(macOS) - try XCTSkipIf(true, "test requires `xcbuild` and is therefore only supported on macOS") - #endif + func testBuildSystemOverrides() async throws { + guard buildSystemProvider == .xcode else { + throw XCTSkip("Build system overrides are only available with the xcode build system.") + } + try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in // try await building using XCBuild without specifying overrides. This should succeed, and should use the default // compiler path. @@ -621,6 +623,7 @@ final class BuildCommandTests: CommandsTestCase { // lines. var buildResult = try await build(["-v"], packagePath: fixturePath) + // TODO verification of the ad-hoc code signing can be done by `swift run` of the executable in these cases once swiftbuild build system is working with that XCTAssertMatch(buildResult.stdout, .contains("codesign --force --sign - --entitlements")) buildResult = try await self.build(["-c", "debug", "-v"], packagePath: fixturePath) @@ -707,13 +710,31 @@ final class BuildCommandTests: CommandsTestCase { // Test that no codecov directory is created if not specified when building. try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { path in _ = try await self.build(["--build-tests"], packagePath: path, cleanAfterward: false) - await XCTAssertAsyncThrowsError(try await SwiftPM.Test.execute(["--skip-build", "--enable-code-coverage"], packagePath: path)) + await XCTAssertAsyncThrowsError( + try await executeSwiftTest( + path, + extraArgs: [ + "--skip-build", + "--enable-code-coverage", + ], + throwIfCommandFails: true, + buildSystem: buildSystemProvider + ) + ) } // Test that enabling code coverage during building produces the expected folder. try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { path in let buildResult = try await self.build(["--build-tests", "--enable-code-coverage"], packagePath: path, cleanAfterward: false) - try await SwiftPM.Test.execute(["--skip-build", "--enable-code-coverage"], packagePath: path) + try await executeSwiftTest( + path, + extraArgs: [ + "--skip-build", + "--enable-code-coverage", + ], + throwIfCommandFails: true, + buildSystem: buildSystemProvider + ) let codeCovPath = buildResult.binPath.appending("codecov") let codeCovFiles = try localFileSystem.getDirectoryContents(codeCovPath) XCTAssertGreaterThan(codeCovFiles.count, 0) @@ -751,3 +772,157 @@ final class BuildCommandTests: CommandsTestCase { } } + + +class BuildCommandNativeTests: BuildCommandTestCases { + + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .native + } + + override func testUsage() async throws { + try await super.testUsage() + } +} + +#if os(macOS) +// Xcode build system tests can only function on macOS +class BuildCommandXcodeTests: BuildCommandTestCases { + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .xcode + } + + override func testUsage() async throws { + try await super.testUsage() + } + + override func testAutomaticParseableInterfacesWithLibraryEvolution() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testNonReachableProductsAndTargetsFunctional() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testCodeCoverage() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testBuildStartMessage() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testBinSymlink() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testSymlink() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testSwiftGetVersion() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testParseableInterfaces() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testProductAndTarget() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testImportOfMissedDepWarning() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } + + override func testGetTaskAllowEntitlement() async throws { + try XCTSkip("Test not implemented for xcode build system.") + } +} +#endif + +class BuildCommandSwiftBuildTests: BuildCommandTestCases { + + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .swiftbuild + } + + override func testNonReachableProductsAndTargetsFunctional() async throws { + throw XCTSkip("SWBINTTODO: Test failed. This needs to be investigated") + } + + override func testParseableInterfaces() async throws { + throw XCTSkip("SWBINTTODO: Test failed with swiftbuild engine because the --enable-parseable-module-interfaces flag doesn't yet produce .swiftinterface files. This needs to be investigated") + } + + override func testGetTaskAllowEntitlement() async throws { + throw XCTSkip("SWBINTTODO: Test failed because swiftbuild doesn't output precis codesign commands. Once swift run works with swiftbuild the test can be investigated.") + } + + override func testCodeCoverage() async throws { + throw XCTSkip("SWBINTTODO: Test failed because of missing plugin support in the PIF builder. This can be reinvestigated after the support is there.") + } + + override func testAtMainSupport() async throws { + #if !os(macOS) + throw XCTSkip("SWBINTTODO: File not found or missing libclang errors on non-macOS platforms. This needs to be investigated") + #endif + + try await super.testAtMainSupport() + } + + override func testAutomaticParseableInterfacesWithLibraryEvolution() async throws { + throw XCTSkip("SWBINTTODO: The test fails because when the unsafe flag for a target is set to '-enable-library-evolution' it is not producing the correct .swiftinterface files. This needs to be investigated") + } + + override func testImportOfMissedDepWarning() async throws { + throw XCTSkip("SWBINTTODO: Test fails because the warning message regarding missing imports is expected to be more verbose and actionable at the SwiftPM level with mention of the involved targets. This needs to be investigated. See case targetDiagnostic(TargetDiagnosticInfo) as a message type that may help.") + } + + override func testProductAndTarget() async throws { + throw XCTSkip("SWBINTTODO: Test fails because there isn't a clear warning message about the lib1 being an automatic product and that the default product is being built instead. This needs to be investigated") + } + + override func testSwiftGetVersion() async throws { + throw XCTSkip("SWBINTTODO: Test fails because the dummy-swiftc used in the test isn't accepted by swift-build. This needs to be investigated") + } + + override func testBinSymlink() async throws { + throw XCTSkip("SWBINTTODO: Test fails because of a difference in the build layout. This needs to be updated to the expected path") + } + + override func testSymlink() async throws { + throw XCTSkip("SWBINTTODO: Test fails because of a difference in the build layout. This needs to be updated to the expected path") + } + +#if !canImport(Darwin) + override func testIgnoresLinuxMain() async throws { + throw XCTSkip("SWBINTTODO: Swift build doesn't currently ignore Linux main when linking on Linux. This needs further investigation.") + } +#endif + +#if !os(macOS) + override func testBuildStartMessage() async throws { + throw XCTSkip("SWBINTTODO: Swift build produces an error building the fixture for this test.") + } + + override func testSwiftDriverRawOutputGetsNewlines() async throws { + throw XCTSkip("SWBINTTODO: Swift build produces an error building the fixture for this test.") + } +#endif + + override func testBuildSystemDefaultSettings() async throws { + #if os(Linux) + if FileManager.default.contents(atPath: "/etc/system-release").map { String(decoding: $0, as: UTF8.self) == "Amazon Linux release 2 (Karoo)\n" } ?? false { + throw XCTSkip("Skipping SwiftBuild testing on Amazon Linux because of platform issues.") + } + #endif + + if ProcessInfo.processInfo.environment["SWIFTPM_NO_SWBUILD_DEPENDENCY"] != nil { + throw XCTSkip("SWIFTPM_NO_SWBUILD_DEPENDENCY is set so skipping because SwiftPM doesn't have the swift-build capability built inside.") + } + + try await super.testBuildSystemDefaultSettings() + } +} diff --git a/Tests/CommandsTests/CommandsTestCase.swift b/Tests/CommandsTests/CommandsTestCase.swift index 1348b1c68e0..93549b997ed 100644 --- a/Tests/CommandsTests/CommandsTestCase.swift +++ b/Tests/CommandsTests/CommandsTestCase.swift @@ -13,6 +13,7 @@ import Basics import XCTest import _InternalTestSupport + class CommandsTestCase: XCTestCase { /// Original working directory before the test ran (if known). @@ -33,3 +34,21 @@ class CommandsTestCase: XCTestCase { // FIXME: We should also hoist the `execute()` helper function that the various test suites implement, but right now they all seem to have slightly different implementations, so that's a later project. } + +class CommandsBuildProviderTestCase: BuildSystemProviderTestCase { + /// Original working directory before the test ran (if known). + private var originalWorkingDirectory: AbsolutePath? = .none + let duplicateSymbolRegex = StringPattern.regex(".*One of the duplicates must be removed or renamed.") + + override func setUp() { + originalWorkingDirectory = localFileSystem.currentWorkingDirectory + } + + override func tearDown() { + if let originalWorkingDirectory { + try? localFileSystem.changeCurrentWorkingDirectory(to: originalWorkingDirectory) + } + } + + // FIXME: We should also hoist the `execute()` helper function that the various test suites implement, but right now they all seem to have slightly different implementations, so that's a later project. +} diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index e2ee97b6b3d..d681eb04fec 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -21,6 +21,7 @@ import PackageGraph import PackageLoading import PackageModel import SourceControl +import SPMBuildCore import _InternalTestSupport import Workspace import XCTest @@ -30,7 +31,11 @@ import class TSCBasic.BufferedOutputByteStream import enum TSCBasic.JSON import class Basics.AsyncProcess -final class PackageCommandTests: CommandsTestCase { +class PackageCommandTestCase: CommandsBuildProviderTestCase { + override func setUpWithError() throws { + try XCTSkipIf(type(of: self) == PackageCommandTestCase.self, "Skipping this test since it will be run in subclasses that will provide different build systems to test.") + } + @discardableResult private func execute( _ args: [String] = [], @@ -40,7 +45,13 @@ final class PackageCommandTests: CommandsTestCase { var environment = env ?? [:] // don't ignore local packages when caching environment["SWIFTPM_TESTS_PACKAGECACHE"] = "1" - return try await SwiftPM.Package.execute(args, packagePath: packagePath, env: environment) + // return try await self.execute(args, packagePath: packagePath, env: environment) + return try await executeSwiftPackage( + packagePath, + extraArgs: args, + env: environment, + buildSystem: buildSystemProvider + ) } func testNoParameters() async throws { @@ -61,18 +72,14 @@ final class PackageCommandTests: CommandsTestCase { } func testSeeAlso() async throws { - let stdout = try await execute(["--help"]).stdout + // This test fails when `--build-system ` is provided, so directly invoke SwiftPM.Package.execute + let stdout = try await SwiftPM.Package.execute(["--help"]).stdout XCTAssertMatch(stdout, .contains("SEE ALSO: swift build, swift run, swift test")) } - func testCommandDoesNotEmitDuplicateSymbols() async throws { - let (stdout, stderr) = try await execute(["--help"]) - XCTAssertNoMatch(stdout, duplicateSymbolRegex) - XCTAssertNoMatch(stderr, duplicateSymbolRegex) - } - func testVersion() async throws { - let stdout = try await execute(["--version"]).stdout + // This test fails when `--build-system ` is provided, so directly invoke SwiftPM.Package.execute + let stdout = try await SwiftPM.Package.execute(["--version"]).stdout XCTAssertMatch(stdout, .regex(#"Swift Package Manager -( \w+ )?\d+.\d+.\d+(-\w+)?"#)) } @@ -346,7 +353,7 @@ final class PackageCommandTests: CommandsTestCase { func testDescribe() async throws { try await fixture(name: "Miscellaneous/ExeTest") { fixturePath in // Generate the JSON description. - let (jsonOutput, _) = try await SwiftPM.Package.execute(["describe", "--type=json"], packagePath: fixturePath) + let (jsonOutput, _) = try await self.execute(["describe", "--type=json"], packagePath: fixturePath) let json = try JSON(bytes: ByteString(encodingAsUTF8: jsonOutput)) // Check that tests don't appear in the product memberships. @@ -359,7 +366,7 @@ final class PackageCommandTests: CommandsTestCase { try await fixture(name: "CFamilyTargets/SwiftCMixed") { fixturePath in // Generate the JSON description. - let (jsonOutput, _) = try await SwiftPM.Package.execute(["describe", "--type=json"], packagePath: fixturePath) + let (jsonOutput, _) = try await self.execute(["describe", "--type=json"], packagePath: fixturePath) let json = try JSON(bytes: ByteString(encodingAsUTF8: jsonOutput)) // Check that the JSON description contains what we expect it to. @@ -386,7 +393,7 @@ final class PackageCommandTests: CommandsTestCase { XCTAssertEqual(jsonTarget2["product_memberships"]?.array?[0].stringValue, "CExec") // Generate the text description. - let (textOutput, _) = try await SwiftPM.Package.execute(["describe", "--type=text"], packagePath: fixturePath) + let (textOutput, _) = try await self.execute(["describe", "--type=text"], packagePath: fixturePath) let textChunks = textOutput.components(separatedBy: "\n").reduce(into: [""]) { chunks, line in // Split the text into chunks based on presence or absence of leading whitespace. if line.hasPrefix(" ") == chunks[chunks.count-1].hasPrefix(" ") { @@ -440,7 +447,7 @@ final class PackageCommandTests: CommandsTestCase { try await fixture(name: "DependencyResolution/External/Simple/Bar") { fixturePath in // Generate the JSON description. - let (jsonOutput, _) = try await SwiftPM.Package.execute(["describe", "--type=json"], packagePath: fixturePath) + let (jsonOutput, _) = try await self.execute(["describe", "--type=json"], packagePath: fixturePath) let json = try JSON(bytes: ByteString(encodingAsUTF8: jsonOutput)) // Check that product dependencies and memberships are as expected. @@ -456,7 +463,7 @@ final class PackageCommandTests: CommandsTestCase { func testDescribePackageUsingPlugins() async throws { try await fixture(name: "Miscellaneous/Plugins/MySourceGenPlugin") { fixturePath in // Generate the JSON description. - let (stdout, _) = try await SwiftPM.Package.execute(["describe", "--type=json"], packagePath: fixturePath) + let (stdout, _) = try await self.execute(["describe", "--type=json"], packagePath: fixturePath) let json = try JSON(bytes: ByteString(encodingAsUTF8: stdout)) // Check the contents of the JSON. @@ -512,7 +519,7 @@ final class PackageCommandTests: CommandsTestCase { let arguments = withPrettyPrinting ? ["dump-symbol-graph", "--pretty-print"] : ["dump-symbol-graph"] - let result = try await SwiftPM.Package.execute(arguments, packagePath: path, env: ["SWIFT_SYMBOLGRAPH_EXTRACT": symbolGraphExtractorPath.pathString]) + let result = try await self.execute(arguments, packagePath: path, env: ["SWIFT_SYMBOLGRAPH_EXTRACT": symbolGraphExtractorPath.pathString]) let enumerator = try XCTUnwrap(FileManager.default.enumerator(at: URL(fileURLWithPath: path.pathString), includingPropertiesForKeys: nil), file: file, line: line) var symbolGraphURL: URL? @@ -588,11 +595,11 @@ final class PackageCommandTests: CommandsTestCase { func testShowExecutables() async throws { try await fixture(name: "Miscellaneous/ShowExecutables") { fixturePath in let packageRoot = fixturePath.appending("app") - let (textOutput, _) = try await SwiftPM.Package.execute(["show-executables", "--format=flatlist"], packagePath: packageRoot) + let (textOutput, _) = try await self.execute(["show-executables", "--format=flatlist"], packagePath: packageRoot) XCTAssert(textOutput.contains("dealer\n")) XCTAssert(textOutput.contains("deck (deck-of-playing-cards)\n")) - let (jsonOutput, _) = try await SwiftPM.Package.execute(["show-executables", "--format=json"], packagePath: packageRoot) + let (jsonOutput, _) = try await self.execute(["show-executables", "--format=json"], packagePath: packageRoot) let json = try JSON(bytes: ByteString(encodingAsUTF8: jsonOutput)) guard case let .array(contents) = json else { XCTFail("unexpected result"); return } @@ -623,10 +630,10 @@ final class PackageCommandTests: CommandsTestCase { func testShowDependencies() async throws { try await fixture(name: "DependencyResolution/External/Complex") { fixturePath in let packageRoot = fixturePath.appending("app") - let (textOutput, _) = try await SwiftPM.Package.execute(["show-dependencies", "--format=text"], packagePath: packageRoot) + let (textOutput, _) = try await self.execute(["show-dependencies", "--format=text"], packagePath: packageRoot) XCTAssert(textOutput.contains("FisherYates@1.2.3")) - let (jsonOutput, _) = try await SwiftPM.Package.execute(["show-dependencies", "--format=json"], packagePath: packageRoot) + let (jsonOutput, _) = try await self.execute(["show-dependencies", "--format=json"], packagePath: packageRoot) let json = try JSON(bytes: ByteString(encodingAsUTF8: jsonOutput)) guard case let .dictionary(contents) = json else { XCTFail("unexpected result"); return } guard case let .string(name)? = contents["name"] else { XCTFail("unexpected result"); return } @@ -1206,12 +1213,12 @@ final class PackageCommandTests: CommandsTestCase { try await fixture(name: "Miscellaneous/PackageEdit") { fixturePath in let fooPath = fixturePath.appending("foo") func build() async throws -> (stdout: String, stderr: String) { - return try await SwiftPM.Build.execute(packagePath: fooPath) + return try await executeSwiftBuild(fooPath) } // Put bar and baz in edit mode. - _ = try await SwiftPM.Package.execute(["edit", "bar", "--branch", "bugfix"], packagePath: fooPath) - _ = try await SwiftPM.Package.execute(["edit", "baz", "--branch", "bugfix"], packagePath: fooPath) + _ = try await self.execute(["edit", "bar", "--branch", "bugfix"], packagePath: fooPath) + _ = try await self.execute(["edit", "baz", "--branch", "bugfix"], packagePath: fooPath) // Path to the executable. let exec = [fooPath.appending(components: ".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "debug", "foo").pathString] @@ -1238,7 +1245,7 @@ final class PackageCommandTests: CommandsTestCase { // It shouldn't be possible to unedit right now because of uncommitted changes. do { - _ = try await SwiftPM.Package.execute(["unedit", "bar"], packagePath: fooPath) + _ = try await self.execute(["unedit", "bar"], packagePath: fooPath) XCTFail("Unexpected unedit success") } catch {} @@ -1247,7 +1254,7 @@ final class PackageCommandTests: CommandsTestCase { // It shouldn't be possible to unedit right now because of unpushed changes. do { - _ = try await SwiftPM.Package.execute(["unedit", "bar"], packagePath: fooPath) + _ = try await self.execute(["unedit", "bar"], packagePath: fooPath) XCTFail("Unexpected unedit success") } catch {} @@ -1255,11 +1262,11 @@ final class PackageCommandTests: CommandsTestCase { try editsRepo.push(remote: "origin", branch: "bugfix") // We should be able to unedit now. - _ = try await SwiftPM.Package.execute(["unedit", "bar"], packagePath: fooPath) + _ = try await self.execute(["unedit", "bar"], packagePath: fooPath) // Test editing with a path i.e. ToT development. let bazTot = fixturePath.appending("tot") - try await SwiftPM.Package.execute(["edit", "baz", "--path", bazTot.pathString], packagePath: fooPath) + try await self.execute(["edit", "baz", "--path", bazTot.pathString], packagePath: fooPath) XCTAssertTrue(localFileSystem.exists(bazTot)) XCTAssertTrue(localFileSystem.isSymlink(bazEditsPath)) @@ -1270,12 +1277,12 @@ final class PackageCommandTests: CommandsTestCase { try localFileSystem.writeFileContents(bazTotPackageFile, string: content) // Unediting baz will remove the symlink but not the checked out package. - try await SwiftPM.Package.execute(["unedit", "baz"], packagePath: fooPath) + try await self.execute(["unedit", "baz"], packagePath: fooPath) XCTAssertTrue(localFileSystem.exists(bazTot)) XCTAssertFalse(localFileSystem.isSymlink(bazEditsPath)) // Check that on re-editing with path, we don't make a new clone. - try await SwiftPM.Package.execute(["edit", "baz", "--path", bazTot.pathString], packagePath: fooPath) + try await self.execute(["edit", "baz", "--path", bazTot.pathString], packagePath: fooPath) XCTAssertTrue(localFileSystem.isSymlink(bazEditsPath)) XCTAssertEqual(try localFileSystem.readFileContents(bazTotPackageFile), content) } @@ -1331,7 +1338,7 @@ final class PackageCommandTests: CommandsTestCase { @discardableResult func execute(_ args: String..., printError: Bool = true) async throws -> String { - return try await SwiftPM.Package.execute([] + args, packagePath: fooPath).stdout + return try await self.execute([] + args, packagePath: fooPath).stdout } try await execute("update") @@ -1392,7 +1399,7 @@ final class PackageCommandTests: CommandsTestCase { ).pathString] // Build and check. - _ = try await SwiftPM.Build.execute(packagePath: fooPath) + _ = try await executeSwiftBuild(fooPath) try await XCTAssertAsyncEqual(try await AsyncProcess.checkNonZeroExit(arguments: exec).spm_chomp(), "\(5)") // Get path to `bar` checkout. @@ -1435,7 +1442,7 @@ final class PackageCommandTests: CommandsTestCase { @discardableResult func execute(_ args: String...) async throws -> String { - return try await SwiftPM.Package.execute([] + args, packagePath: fooPath).stdout + return try await self.execute([] + args, packagePath: fooPath).stdout } // Try to pin bar. @@ -1766,7 +1773,7 @@ final class PackageCommandTests: CommandsTestCase { try await execute(["config", "set-mirror", "--original", "https://scm.com/org/foo", "--mirror", "https://scm.com/org/bar"], packagePath: packageRoot) XCTAssertTrue(fs.isFile(configFile)) - let (stdout, _) = try await SwiftPM.Package.execute(["dump-package"], packagePath: packageRoot) + let (stdout, _) = try await self.execute(["dump-package"], packagePath: packageRoot) XCTAssertMatch(stdout, .contains("https://scm.com/org/bar")) XCTAssertNoMatch(stdout, .contains("https://scm.com/org/foo")) } @@ -1809,7 +1816,7 @@ final class PackageCommandTests: CommandsTestCase { try await execute(["config", "set-mirror", "--original", "https://scm.com/org/foo", "--mirror", "org.bar"], packagePath: packageRoot) XCTAssertTrue(fs.isFile(configFile)) - let (stdout, _) = try await SwiftPM.Package.execute(["dump-package"], packagePath: packageRoot) + let (stdout, _) = try await self.execute(["dump-package"], packagePath: packageRoot) XCTAssertMatch(stdout, .contains("org.bar")) XCTAssertNoMatch(stdout, .contains("https://scm.com/org/foo")) } @@ -1852,7 +1859,7 @@ final class PackageCommandTests: CommandsTestCase { try await execute(["config", "set-mirror", "--original", "org.foo", "--mirror", "https://scm.com/org/bar"], packagePath: packageRoot) XCTAssertTrue(fs.isFile(configFile)) - let (stdout, _) = try await SwiftPM.Package.execute(["dump-package"], packagePath: packageRoot) + let (stdout, _) = try await self.execute(["dump-package"], packagePath: packageRoot) XCTAssertMatch(stdout, .contains("https://scm.com/org/bar")) XCTAssertNoMatch(stdout, .contains("org.foo")) } @@ -1882,7 +1889,7 @@ final class PackageCommandTests: CommandsTestCase { // Invoke `swift-package`, passing in the overriding `PATH` environment variable. let packageRoot = fixturePath.appending("Library") let patchedPATH = fakeBinDir.pathString + ":" + ProcessInfo.processInfo.environment["PATH"]! - let (stdout, _) = try await SwiftPM.Package.execute(["dump-package"], packagePath: packageRoot, env: ["PATH": patchedPATH]) + let (stdout, _) = try await self.execute(["dump-package"], packagePath: packageRoot, env: ["PATH": patchedPATH]) // Check that the wrong tools weren't invoked. We can't just check the exit code because of fallbacks. XCTAssertNoMatch(stdout, .contains("wrong xcrun invoked")) @@ -1990,7 +1997,10 @@ final class PackageCommandTests: CommandsTestCase { // Invoke it, and check the results. let args = staticStdlib ? ["--static-swift-stdlib"] : [] - let (stdout, stderr) = try await SwiftPM.Build.execute(args, packagePath: packageDir) + let (stdout, stderr) = try await executeSwiftBuild( + packageDir, + extraArgs: args + ) XCTAssert(stdout.contains("Build complete!")) // We expect a warning about `library.bar` but not about `library.foo`. @@ -2056,7 +2066,7 @@ final class PackageCommandTests: CommandsTestCase { ) // Invoke it, and check the results. - await XCTAssertAsyncThrowsError(try await SwiftPM.Build.execute(["-v"], packagePath: packageDir)) { error in + await XCTAssertAsyncThrowsError(try await executeSwiftBuild(packageDir, extraArgs: ["-v"])) { error in guard case SwiftPMError.executionFailure(_, _, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2073,34 +2083,34 @@ final class PackageCommandTests: CommandsTestCase { // Running without arguments or options do { - let (stdout, _) = try await SwiftPM.Package.execute(["archive-source"], packagePath: packageRoot) + let (stdout, _) = try await self.execute(["archive-source"], packagePath: packageRoot) XCTAssert(stdout.contains("Created Bar.zip"), #"actual: "\#(stdout)""#) } // Running without arguments or options again, overwriting existing archive do { - let (stdout, _) = try await SwiftPM.Package.execute(["archive-source"], packagePath: packageRoot) + let (stdout, _) = try await self.execute(["archive-source"], packagePath: packageRoot) XCTAssert(stdout.contains("Created Bar.zip"), #"actual: "\#(stdout)""#) } // Running with output as absolute path within package root do { let destination = packageRoot.appending("Bar-1.2.3.zip") - let (stdout, _) = try await SwiftPM.Package.execute(["archive-source", "--output", destination.pathString], packagePath: packageRoot) + let (stdout, _) = try await self.execute(["archive-source", "--output", destination.pathString], packagePath: packageRoot) XCTAssert(stdout.contains("Created Bar-1.2.3.zip"), #"actual: "\#(stdout)""#) } // Running with output is outside the package root try await withTemporaryDirectory { tempDirectory in let destination = tempDirectory.appending("Bar-1.2.3.zip") - let (stdout, _) = try await SwiftPM.Package.execute(["archive-source", "--output", destination.pathString], packagePath: packageRoot) + let (stdout, _) = try await self.execute(["archive-source", "--output", destination.pathString], packagePath: packageRoot) XCTAssert(stdout.hasPrefix("Created /"), #"actual: "\#(stdout)""#) XCTAssert(stdout.contains("Bar-1.2.3.zip"), #"actual: "\#(stdout)""#) } // Running without arguments or options in non-package directory do { - await XCTAssertAsyncThrowsError(try await SwiftPM.Package.execute(["archive-source"], packagePath: fixturePath)) { error in + await XCTAssertAsyncThrowsError(try await self.execute(["archive-source"], packagePath: fixturePath)) { error in guard case SwiftPMError.executionFailure(_, _, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2111,7 +2121,7 @@ final class PackageCommandTests: CommandsTestCase { // Running with output as absolute path to existing directory do { let destination = AbsolutePath.root - await XCTAssertAsyncThrowsError(try await SwiftPM.Package.execute(["archive-source", "--output", destination.pathString], packagePath: packageRoot)) { error in + await XCTAssertAsyncThrowsError(try await self.execute(["archive-source", "--output", destination.pathString], packagePath: packageRoot)) { error in guard case SwiftPMError.executionFailure(_, _, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2332,25 +2342,25 @@ final class PackageCommandTests: CommandsTestCase { // Check that we can invoke the plugin with the "plugin" subcommand. do { - let (stdout, _) = try await SwiftPM.Package.execute(["plugin", "mycmd"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["plugin", "mycmd"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("This is MyCommandPlugin.")) } // Check that we can also invoke it without the "plugin" subcommand. do { - let (stdout, _) = try await SwiftPM.Package.execute(["mycmd"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["mycmd"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("This is MyCommandPlugin.")) } // Testing listing the available command plugins. do { - let (stdout, _) = try await SwiftPM.Package.execute(["plugin", "--list"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["plugin", "--list"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("‘mycmd’ (plugin ‘MyPlugin’ in package ‘MyPackage’)")) } // Check that we get the expected error if trying to invoke a plugin with the wrong name. do { - await XCTAssertAsyncThrowsError(try await SwiftPM.Package.execute(["my-nonexistent-cmd"], packagePath: packageDir)) { error in + await XCTAssertAsyncThrowsError(try await self.execute(["my-nonexistent-cmd"], packagePath: packageDir)) { error in guard case SwiftPMError.executionFailure(_, _, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2360,7 +2370,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that the .docc file was properly vended to the plugin. do { - let (stdout, _) = try await SwiftPM.Package.execute(["mycmd", "--target", "MyLibrary"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["mycmd", "--target", "MyLibrary"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Sources/MyLibrary/library.swift: source")) XCTAssertMatch(stdout, .contains("Sources/MyLibrary/test.docc: unknown")) } @@ -2368,13 +2378,13 @@ final class PackageCommandTests: CommandsTestCase { // Check that the initial working directory is what we expected. do { let workingDirectory = FileManager.default.currentDirectoryPath - let (stdout, _) = try await SwiftPM.Package.execute(["mycmd"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["mycmd"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Initial working directory: \(workingDirectory)")) } // Check that information about the dependencies was properly sent to the plugin. do { - let (stdout, _) = try await SwiftPM.Package.execute(["mycmd", "--target", "MyLibrary"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["mycmd", "--target", "MyLibrary"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("dependency HelperPackage: local")) } } @@ -2385,7 +2395,7 @@ final class PackageCommandTests: CommandsTestCase { try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") try await fixture(name: "Miscellaneous/Plugins/AmbiguousCommands") { fixturePath in - let (stdout, _) = try await SwiftPM.Package.execute(["plugin", "--package", "A", "A"], packagePath: fixturePath) + let (stdout, _) = try await self.execute(["plugin", "--package", "A", "A"], packagePath: fixturePath) XCTAssertMatch(stdout, .contains("Hello A!")) } } @@ -2407,13 +2417,13 @@ final class PackageCommandTests: CommandsTestCase { try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in func runPlugin(flags: [String], diagnostics: [String], completion: (String, String) -> Void) async throws { - let (stdout, stderr) = try await SwiftPM.Package.execute(flags + ["print-diagnostics"] + diagnostics, packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) + let (stdout, stderr) = try await self.execute(flags + ["print-diagnostics"] + diagnostics, packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) completion(stdout, stderr) } // Diagnostics.error causes SwiftPM to return a non-zero exit code, but we still need to check stdout and stderr func runPluginWithError(flags: [String], diagnostics: [String], completion: (String, String) -> Void) async throws { - await XCTAssertAsyncThrowsError(try await SwiftPM.Package.execute(flags + ["print-diagnostics"] + diagnostics, packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"])) { error in + await XCTAssertAsyncThrowsError(try await self.execute(flags + ["print-diagnostics"] + diagnostics, packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"])) { error in guard case SwiftPMError.executionFailure(_, let stdout, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2555,35 +2565,35 @@ final class PackageCommandTests: CommandsTestCase { // By default, a plugin-requested build produces a debug binary try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let _ = try await SwiftPM.Package.execute(["-c", "release", "build-target"], packagePath: fixturePath) + let _ = try await self.execute(["-c", "release", "build-target"], packagePath: fixturePath) AssertIsExecutableFile(fixturePath.appending(components: debugTarget)) AssertNotExists(fixturePath.appending(components: releaseTarget)) } // If the plugin specifies a debug binary, that is what will be built, regardless of overall configuration try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let _ = try await SwiftPM.Package.execute(["-c", "release", "build-target", "build-debug"], packagePath: fixturePath) + let _ = try await self.execute(["-c", "release", "build-target", "build-debug"], packagePath: fixturePath) AssertIsExecutableFile(fixturePath.appending(components: debugTarget)) AssertNotExists(fixturePath.appending(components: releaseTarget)) } // If the plugin requests a release binary, that is what will be built, regardless of overall configuration try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let _ = try await SwiftPM.Package.execute(["-c", "debug", "build-target", "build-release"], packagePath: fixturePath) + let _ = try await self.execute(["-c", "debug", "build-target", "build-release"], packagePath: fixturePath) AssertNotExists(fixturePath.appending(components: debugTarget)) AssertIsExecutableFile(fixturePath.appending(components: releaseTarget)) } // If the plugin inherits the overall build configuration, that is what will be built try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let _ = try await SwiftPM.Package.execute(["-c", "debug", "build-target", "build-inherit"], packagePath: fixturePath) + let _ = try await self.execute(["-c", "debug", "build-target", "build-inherit"], packagePath: fixturePath) AssertIsExecutableFile(fixturePath.appending(components: debugTarget)) AssertNotExists(fixturePath.appending(components: releaseTarget)) } // If the plugin inherits the overall build configuration, that is what will be built try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let _ = try await SwiftPM.Package.execute(["-c", "release", "build-target", "build-inherit"], packagePath: fixturePath) + let _ = try await self.execute(["-c", "release", "build-target", "build-inherit"], packagePath: fixturePath) AssertNotExists(fixturePath.appending(components: debugTarget)) AssertIsExecutableFile(fixturePath.appending(components: releaseTarget)) } @@ -2594,27 +2604,27 @@ final class PackageCommandTests: CommandsTestCase { // Overall configuration: debug, plugin build request: debug -> without testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "debug", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) + await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) } // Overall configuration: debug, plugin build request: release -> without testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "debug", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath)) + await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath)) } // Overall configuration: release, plugin build request: debug -> with testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "release", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) + await XCTAssertAsyncNoThrow(try await self.execute(["-c", "release", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) } // Overall configuration: release, plugin build request: release -> with testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "release", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath)) + await XCTAssertAsyncNoThrow(try await self.execute(["-c", "release", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath)) } // Overall configuration: release, plugin build request: release including tests -> with testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "release", "check-testability", "all-with-tests", "release", "true"], packagePath: fixturePath)) + await XCTAssertAsyncNoThrow(try await self.execute(["-c", "release", "check-testability", "all-with-tests", "release", "true"], packagePath: fixturePath)) } } @@ -2638,7 +2648,7 @@ final class PackageCommandTests: CommandsTestCase { // Check than nothing is echoed when echoLogs is false try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Package.execute(["print-diagnostics", "build"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) + let (stdout, stderr) = try await self.execute(["print-diagnostics", "build"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) XCTAssertMatch(stdout, isEmpty) // Filter some unrelated output that could show up on stderr. let filteredStderr = stderr.components(separatedBy: "\n") @@ -2648,7 +2658,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that logs are returned to the plugin when echoLogs is false try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Package.execute(["print-diagnostics", "build", "printlogs"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) + let (stdout, stderr) = try await self.execute(["print-diagnostics", "build", "printlogs"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) XCTAssertMatch(stdout, containsLogtext) // Filter some unrelated output that could show up on stderr. let filteredStderr = stderr.components(separatedBy: "\n") @@ -2658,14 +2668,14 @@ final class PackageCommandTests: CommandsTestCase { // Check that logs echoed to the console (on stderr) when echoLogs is true try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Package.execute(["print-diagnostics", "build", "echologs"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) + let (stdout, stderr) = try await self.execute(["print-diagnostics", "build", "echologs"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) XCTAssertMatch(stdout, isEmpty) XCTAssertMatch(stderr, containsLogecho) } // Check that logs are returned to the plugin and echoed to the console (on stderr) when echoLogs is true try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Package.execute(["print-diagnostics", "build", "printlogs", "echologs"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) + let (stdout, stderr) = try await self.execute(["print-diagnostics", "build", "printlogs", "echologs"], packagePath: fixturePath, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) XCTAssertMatch(stdout, containsLogtext) XCTAssertMatch(stderr, containsLogecho) } @@ -2707,7 +2717,7 @@ final class PackageCommandTests: CommandsTestCase { #if os(macOS) do { - await XCTAssertAsyncThrowsError(try await SwiftPM.Package.execute(["plugin", "Network"], packagePath: packageDir)) { error in + await XCTAssertAsyncThrowsError(try await self.execute(["plugin", "Network"], packagePath: packageDir)) { error in guard case SwiftPMError.executionFailure(_, let stdout, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2721,7 +2731,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that we don't get an error (and also are allowed to write to the package directory) if we pass `--allow-writing-to-package-directory`. do { - let (stdout, _) = try await SwiftPM.Package.execute(["plugin"] + remedy + ["Network"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["plugin"] + remedy + ["Network"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("hello world")) } } @@ -2838,7 +2848,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that we get an error if the plugin needs permission but if we don't give it to them. Note that sandboxing is only currently supported on macOS. #if os(macOS) do { - await XCTAssertAsyncThrowsError(try await SwiftPM.Package.execute(["plugin", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"])) { error in + await XCTAssertAsyncThrowsError(try await self.execute(["plugin", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"])) { error in guard case SwiftPMError.executionFailure(_, let stdout, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2852,7 +2862,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that we don't get an error (and also are allowed to write to the package directory) if we pass `--allow-writing-to-package-directory`. do { - let (stdout, stderr) = try await SwiftPM.Package.execute(["plugin", "--allow-writing-to-package-directory", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) + let (stdout, stderr) = try await self.execute(["plugin", "--allow-writing-to-package-directory", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) XCTAssertMatch(stdout, .contains("successfully created it")) XCTAssertNoMatch(stderr, .contains("error: Couldn’t create file at path")) } @@ -2860,7 +2870,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that we get an error if the plugin doesn't declare permission but tries to write anyway. Note that sandboxing is only currently supported on macOS. #if os(macOS) do { - await XCTAssertAsyncThrowsError(try await SwiftPM.Package.execute(["plugin", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "0"])) { error in + await XCTAssertAsyncThrowsError(try await self.execute(["plugin", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "0"])) { error in guard case SwiftPMError.executionFailure(_, let stdout, let stderr) = error else { return XCTFail("invalid error \(error)") } @@ -2872,21 +2882,21 @@ final class PackageCommandTests: CommandsTestCase { // Check default command with arguments do { - let (stdout, stderr) = try await SwiftPM.Package.execute(["--allow-writing-to-package-directory", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) + let (stdout, stderr) = try await self.execute(["--allow-writing-to-package-directory", "PackageScribbler"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) XCTAssertMatch(stdout, .contains("successfully created it")) XCTAssertNoMatch(stderr, .contains("error: Couldn’t create file at path")) } // Check plugin arguments after plugin name do { - let (stdout, stderr) = try await SwiftPM.Package.execute(["plugin", "PackageScribbler", "--allow-writing-to-package-directory"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) + let (stdout, stderr) = try await self.execute(["plugin", "PackageScribbler", "--allow-writing-to-package-directory"], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) XCTAssertMatch(stdout, .contains("successfully created it")) XCTAssertNoMatch(stderr, .contains("error: Couldn’t create file at path")) } // Check default command with arguments after plugin name do { - let (stdout, stderr) = try await SwiftPM.Package.execute(["PackageScribbler", "--allow-writing-to-package-directory", ], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) + let (stdout, stderr) = try await self.execute(["PackageScribbler", "--allow-writing-to-package-directory", ], packagePath: packageDir, env: ["DECLARE_PACKAGE_WRITING_PERMISSION": "1"]) XCTAssertMatch(stdout, .contains("successfully created it")) XCTAssertNoMatch(stderr, .contains("error: Couldn’t create file at path")) } @@ -2958,14 +2968,14 @@ final class PackageCommandTests: CommandsTestCase { // Check arguments do { - let (stdout, stderr) = try await SwiftPM.Package.execute(["plugin", "MyPlugin", "--foo", "--help", "--version", "--verbose"], packagePath: packageDir, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) + let (stdout, stderr) = try await self.execute(["plugin", "MyPlugin", "--foo", "--help", "--version", "--verbose"], packagePath: packageDir, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) XCTAssertMatch(stdout, .contains("success")) XCTAssertFalse(stderr.contains("error:")) } // Check default command arguments do { - let (stdout, stderr) = try await SwiftPM.Package.execute(["MyPlugin", "--foo", "--help", "--version", "--verbose"], packagePath: packageDir, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) + let (stdout, stderr) = try await self.execute(["MyPlugin", "--foo", "--help", "--version", "--verbose"], packagePath: packageDir, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"]) XCTAssertMatch(stdout, .contains("success")) XCTAssertFalse(stderr.contains("error:")) } @@ -3058,7 +3068,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that if we don't pass any target, we successfully get symbol graph information for all targets in the package, and at different paths. do { - let (stdout, _) = try await SwiftPM.Package.execute(["generate-documentation"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["generate-documentation"], packagePath: packageDir) XCTAssertMatch(stdout, .and(.contains("MyLibrary:"), .contains("mypackage/MyLibrary"))) XCTAssertMatch(stdout, .and(.contains("MyCommand:"), .contains("mypackage/MyCommand"))) @@ -3066,7 +3076,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that if we pass a target, we successfully get symbol graph information for just the target we asked for. do { - let (stdout, _) = try await SwiftPM.Package.execute(["generate-documentation", "--target", "MyLibrary"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["generate-documentation", "--target", "MyLibrary"], packagePath: packageDir) XCTAssertMatch(stdout, .and(.contains("MyLibrary:"), .contains("mypackage/MyLibrary"))) XCTAssertNoMatch(stdout, .and(.contains("MyCommand:"), .contains("mypackage/MyCommand"))) } @@ -3187,7 +3197,7 @@ final class PackageCommandTests: CommandsTestCase { // Invoke the plugin with parameters choosing a verbose build of MyExecutable for debugging. do { - let (stdout, _) = try await SwiftPM.Package.execute(["my-build-tester", "--product", "MyExecutable", "--print-commands"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["my-build-tester", "--product", "MyExecutable", "--print-commands"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Building for debugging...")) XCTAssertNoMatch(stdout, .contains("Building for production...")) XCTAssertMatch(stdout, .contains("-module-name MyExecutable")) @@ -3200,7 +3210,7 @@ final class PackageCommandTests: CommandsTestCase { // Invoke the plugin with parameters choosing a concise build of MyExecutable for release. do { - let (stdout, _) = try await SwiftPM.Package.execute(["my-build-tester", "--product", "MyExecutable", "--release"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["my-build-tester", "--product", "MyExecutable", "--release"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Building for production...")) XCTAssertNoMatch(stdout, .contains("Building for debug...")) XCTAssertNoMatch(stdout, .contains("-module-name MyExecutable")) @@ -3212,7 +3222,7 @@ final class PackageCommandTests: CommandsTestCase { // Invoke the plugin with parameters choosing a verbose build of MyStaticLibrary for release. do { - let (stdout, _) = try await SwiftPM.Package.execute(["my-build-tester", "--product", "MyStaticLibrary", "--print-commands", "--release"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["my-build-tester", "--product", "MyStaticLibrary", "--print-commands", "--release"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Building for production...")) XCTAssertNoMatch(stdout, .contains("Building for debug...")) XCTAssertNoMatch(stdout, .contains("-module-name MyLibrary")) @@ -3224,7 +3234,7 @@ final class PackageCommandTests: CommandsTestCase { // Invoke the plugin with parameters choosing a verbose build of MyDynamicLibrary for release. do { - let (stdout, _) = try await SwiftPM.Package.execute(["my-build-tester", "--product", "MyDynamicLibrary", "--print-commands", "--release"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["my-build-tester", "--product", "MyDynamicLibrary", "--print-commands", "--release"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Building for production...")) XCTAssertNoMatch(stdout, .contains("Building for debug...")) XCTAssertNoMatch(stdout, .contains("-module-name MyLibrary")) @@ -3353,7 +3363,7 @@ final class PackageCommandTests: CommandsTestCase { ) // Check basic usage with filtering and code coverage. The plugin itself asserts a bunch of values. - try await SwiftPM.Package.execute(["my-test-tester"], packagePath: packageDir) + try await self.execute(["my-test-tester"], packagePath: packageDir) // We'll add checks for various error conditions here in a future commit. } @@ -3529,28 +3539,28 @@ final class PackageCommandTests: CommandsTestCase { // Check that a target doesn't include itself in its recursive dependencies. do { - let (stdout, _) = try await SwiftPM.Package.execute(["print-target-dependencies", "--target", "SecondTarget"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["print-target-dependencies", "--target", "SecondTarget"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Recursive dependencies of 'SecondTarget': [\"FirstTarget\"]")) XCTAssertMatch(stdout, .contains("Module kind of 'SecondTarget': generic")) } // Check that targets are not included twice in recursive dependencies. do { - let (stdout, _) = try await SwiftPM.Package.execute(["print-target-dependencies", "--target", "ThirdTarget"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["print-target-dependencies", "--target", "ThirdTarget"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Recursive dependencies of 'ThirdTarget': [\"FirstTarget\"]")) XCTAssertMatch(stdout, .contains("Module kind of 'ThirdTarget': generic")) } // Check that product dependencies work in recursive dependencies. do { - let (stdout, _) = try await SwiftPM.Package.execute(["print-target-dependencies", "--target", "FourthTarget"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["print-target-dependencies", "--target", "FourthTarget"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Recursive dependencies of 'FourthTarget': [\"FirstTarget\", \"SecondTarget\", \"ThirdTarget\", \"HelperLibrary\"]")) XCTAssertMatch(stdout, .contains("Module kind of 'FourthTarget': generic")) } // Check some of the other utility APIs. do { - let (stdout, _) = try await SwiftPM.Package.execute(["print-target-dependencies", "--target", "FifthTarget"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["print-target-dependencies", "--target", "FifthTarget"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("execProducts: [\"FifthTarget\"]")) XCTAssertMatch(stdout, .contains("swiftTargets: [\"FifthTarget\", \"FirstTarget\", \"FourthTarget\", \"SecondTarget\", \"TestTarget\", \"ThirdTarget\"]")) XCTAssertMatch(stdout, .contains("swiftSources: [\"library.swift\", \"library.swift\", \"library.swift\", \"library.swift\", \"main.swift\", \"tests.swift\"]")) @@ -3559,7 +3569,7 @@ final class PackageCommandTests: CommandsTestCase { // Check a test target. do { - let (stdout, _) = try await SwiftPM.Package.execute(["print-target-dependencies", "--target", "TestTarget"], packagePath: packageDir) + let (stdout, _) = try await self.execute(["print-target-dependencies", "--target", "TestTarget"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Recursive dependencies of 'TestTarget': [\"FirstTarget\", \"SecondTarget\"]")) XCTAssertMatch(stdout, .contains("Module kind of 'TestTarget': test")) } @@ -3654,7 +3664,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that building without options compiles both plugins and that the build proceeds. do { - let (stdout, _) = try await SwiftPM.Build.execute(packagePath: packageDir) + let (stdout, _) = try await executeSwiftBuild(packageDir) XCTAssertMatch(stdout, .contains("Compiling plugin MyBuildToolPlugin")) XCTAssertMatch(stdout, .contains("Compiling plugin MyCommandPlugin")) XCTAssertMatch(stdout, .contains("Building for debugging...")) @@ -3662,7 +3672,10 @@ final class PackageCommandTests: CommandsTestCase { // Check that building just one of them just compiles that plugin and doesn't build anything else. do { - let (stdout, _) = try await SwiftPM.Build.execute(["--target", "MyCommandPlugin"], packagePath: packageDir) + let (stdout, _) = try await executeSwiftBuild( + packageDir, + extraArgs: ["--target", "MyCommandPlugin"] + ) XCTAssertNoMatch(stdout, .contains("Compiling plugin MyBuildToolPlugin")) XCTAssertMatch(stdout, .contains("Compiling plugin MyCommandPlugin")) XCTAssertNoMatch(stdout, .contains("Building for debugging...")) @@ -3685,7 +3698,7 @@ final class PackageCommandTests: CommandsTestCase { // Check that building stops after compiling the plugin and doesn't proceed. // Run this test a number of times to try to catch any race conditions. for _ in 1...5 { - await XCTAssertAsyncThrowsError(try await SwiftPM.Build.execute(packagePath: packageDir)) { error in + await XCTAssertAsyncThrowsError(try await executeSwiftBuild(packageDir)) { error in guard case SwiftPMError.executionFailure(_, let stdout, _) = error else { return XCTFail("invalid error \(error)") } @@ -3766,3 +3779,39 @@ final class PackageCommandTests: CommandsTestCase { } } } + + +class PackageCommandNativeTests: PackageCommandTestCase { + + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .native + } + + override func testNoParameters() async throws { + try await super.testNoParameters() + } +} + +class PackageCommandSwiftBuildTests: PackageCommandTestCase { + + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .swiftbuild + } + + override func testNoParameters() async throws { + try await super.testNoParameters() + } + + override func testCommandPluginBuildingCallbacks() async throws { + throw XCTSkip("SWBINTTODO: Test fails as plugins are not currenty supported") + } + override func testCommandPluginBuildTestability() async throws { + throw XCTSkip("SWBINTTODO: Test fails as plugins are not currenty supported") + } + +#if !os(macOS) + override func testCommandPluginTestingCallbacks() async throws { + throw XCTSkip("SWBINTTODO: Test fails on inability to find libclang on Linux. Also, plugins are not currently supported") + } +#endif +} diff --git a/Tests/CommandsTests/RunCommandTests.swift b/Tests/CommandsTests/RunCommandTests.swift index 34391d561b7..7516cc41308 100644 --- a/Tests/CommandsTests/RunCommandTests.swift +++ b/Tests/CommandsTests/RunCommandTests.swift @@ -12,17 +12,29 @@ import Basics import Commands +import SPMBuildCore import _InternalTestSupport +import TSCTestSupport import XCTest import class Basics.AsyncProcess -final class RunCommandTests: CommandsTestCase { +class RunCommandTestCase: CommandsBuildProviderTestCase { + override func setUpWithError() throws { + try XCTSkipIf(type(of: self) == RunCommandTestCase.self, "Skipping this test since it will be run in subclasses that will provide different build systems to test.") + } + private func execute( _ args: [String] = [], + _ executable: String? = nil, packagePath: AbsolutePath? = nil ) async throws -> (stdout: String, stderr: String) { - return try await SwiftPM.Run.execute(args, packagePath: packagePath) + return try await executeSwiftRun( + packagePath, + nil, + extraArgs: args, + buildSystem: buildSystemProvider + ) } func testUsage() async throws { @@ -50,8 +62,10 @@ final class RunCommandTests: CommandsTestCase { #if !os(Windows) func testToolsetDebugger() async throws { try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Run.execute( - ["--toolset", "\(fixturePath)/toolset.json"], packagePath: fixturePath) + let (stdout, stderr) = try await execute( + ["--toolset", "\(fixturePath)/toolset.json"], + packagePath: fixturePath + ) // We only expect tool's output on the stdout stream. XCTAssertMatch(stdout, .contains("\(fixturePath)/.build")) @@ -66,7 +80,7 @@ final class RunCommandTests: CommandsTestCase { func testUnknownProductAndArgumentPassing() async throws { try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Run.execute( + let (stdout, stderr) = try await execute( ["secho", "1", "--hello", "world"], packagePath: fixturePath) // We only expect tool's output on the stdout stream. @@ -219,3 +233,40 @@ final class RunCommandTests: CommandsTestCase { } } + +class RunCommandNativeTests: RunCommandTestCase { + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .native + } + + override func testUsage() async throws { + try await super.testUsage() + } +} + + +class RunCommandSwiftBuildTests: RunCommandTestCase { + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .swiftbuild + } + + override func testUsage() async throws { + try await super.testUsage() + } + + override func testMultipleExecutableAndExplicitExecutable() async throws { + throw XCTSkip("SWBINTTODO: https://github.com/swiftlang/swift-package-manager/issues/8279: Swift run using Swift Build does not output executable content to the terminal") + } + + override func testUnknownProductAndArgumentPassing() async throws { + throw XCTSkip("SWBINTTODO: https://github.com/swiftlang/swift-package-manager/issues/8279: Swift run using Swift Build does not output executable content to the terminal") + } + + override func testToolsetDebugger() async throws { + throw XCTSkip("SWBINTTODO: Test fixture fails to build") + } + + override func testUnreachableExecutable() async throws { + throw XCTSkip("SWBINTTODO: Test fails because of build layout differences.") + } +} diff --git a/Tests/CommandsTests/SwiftSDKCommandTests.swift b/Tests/CommandsTests/SwiftSDKCommandTests.swift index ad8cfab7790..a1ad53f4db2 100644 --- a/Tests/CommandsTests/SwiftSDKCommandTests.swift +++ b/Tests/CommandsTests/SwiftSDKCommandTests.swift @@ -32,7 +32,7 @@ final class SwiftSDKCommandTests: CommandsTestCase { } } - func testCommandDoesNotEmitDuplicateSymbols() async throws { + func testCommandDoesNotEmitDuplicateSymbols() async throws { for command in [SwiftPM.sdk, SwiftPM.experimentalSDK] { let (stdout, stderr) = try await command.execute(["--help"]) XCTAssertNoMatch(stdout, duplicateSymbolRegex) @@ -40,7 +40,6 @@ final class SwiftSDKCommandTests: CommandsTestCase { } } - func testVersionS() async throws { for command in [SwiftPM.sdk, SwiftPM.experimentalSDK] { let stdout = try await command.execute(["--version"]).stdout diff --git a/Tests/CommandsTests/TestCommandTests.swift b/Tests/CommandsTests/TestCommandTests.swift index 8e7831cd4c5..4e27e48fc68 100644 --- a/Tests/CommandsTests/TestCommandTests.swift +++ b/Tests/CommandsTests/TestCommandTests.swift @@ -12,18 +12,28 @@ import Basics import Commands +import SPMBuildCore import PackageModel import _InternalTestSupport import TSCTestSupport import XCTest -final class TestCommandTests: CommandsTestCase { +class TestCommandTestCase: CommandsBuildProviderTestCase { + override func setUpWithError() throws { + try XCTSkipIf(type(of: self) == TestCommandTestCase.self, "Skipping this test since it will be run in subclasses that will provide different build systems to test.") + } + private func execute( _ args: [String], packagePath: AbsolutePath? = nil, throwIfCommandFails: Bool = true ) async throws -> (stdout: String, stderr: String) { - try await SwiftPM.Test.execute(args, packagePath: packagePath, throwIfCommandFails: throwIfCommandFails) + try await executeSwiftTest( + packagePath, + extraArgs: args, + throwIfCommandFails: throwIfCommandFails, + buildSystem: buildSystemProvider + ) } func testUsage() async throws { @@ -48,12 +58,6 @@ final class TestCommandTests: CommandsTestCase { XCTAssert(stdout.contains("SEE ALSO: swift build, swift run, swift package"), "got stdout:\n" + stdout) } - func testCommandDoesNotEmitDuplicateSymbols() async throws { - let (stdout, stderr) = try await execute(["--help"]) - XCTAssertNoMatch(stdout, duplicateSymbolRegex) - XCTAssertNoMatch(stderr, duplicateSymbolRegex) - } - func testVersion() async throws { let stdout = try await execute(["--version"]).stdout XCTAssertMatch(stdout, .regex(#"Swift Package Manager -( \w+ )?\d+.\d+.\d+(-\w+)?"#)) @@ -63,7 +67,7 @@ final class TestCommandTests: CommandsTestCase { #if !os(Windows) func testToolsetRunner() async throws { try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Test.execute( + let (stdout, stderr) = try await execute( ["--toolset", "\(fixturePath)/toolset.json"], packagePath: fixturePath) // We only expect tool's output on the stdout stream. @@ -138,21 +142,21 @@ final class TestCommandTests: CommandsTestCase { func testSwiftTestParallel() async throws { try await fixture(name: "Miscellaneous/ParallelTestsPkg") { fixturePath in // First try normal serial testing. - await XCTAssertThrowsCommandExecutionError(try await SwiftPM.Test.execute(packagePath: fixturePath)) { error in + await XCTAssertThrowsCommandExecutionError(try await execute([], packagePath: fixturePath)) { error in // in "swift test" test output goes to stdout XCTAssertMatch(error.stdout, .contains("Executed 2 tests")) XCTAssertNoMatch(error.stdout, .contains("[3/3]")) } // Try --no-parallel. - await XCTAssertThrowsCommandExecutionError(try await SwiftPM.Test.execute(["--no-parallel"], packagePath: fixturePath)) { error in + await XCTAssertThrowsCommandExecutionError(try await execute(["--no-parallel"], packagePath: fixturePath)) { error in // in "swift test" test output goes to stdout XCTAssertMatch(error.stdout, .contains("Executed 2 tests")) XCTAssertNoMatch(error.stdout, .contains("[3/3]")) } // Run tests in parallel. - await XCTAssertThrowsCommandExecutionError(try await SwiftPM.Test.execute(["--parallel"], packagePath: fixturePath)) { error in + await XCTAssertThrowsCommandExecutionError(try await execute(["--parallel"], packagePath: fixturePath)) { error in // in "swift test" test output goes to stdout XCTAssertMatch(error.stdout, .contains("testExample1")) XCTAssertMatch(error.stdout, .contains("testExample2")) @@ -165,7 +169,7 @@ final class TestCommandTests: CommandsTestCase { let xUnitOutput = fixturePath.appending("result.xml") // Run tests in parallel with verbose output. await XCTAssertThrowsCommandExecutionError( - try await SwiftPM.Test.execute(["--parallel", "--verbose", "--xunit-output", xUnitOutput.pathString], packagePath: fixturePath) + try await execute(["--parallel", "--verbose", "--xunit-output", xUnitOutput.pathString], packagePath: fixturePath) ) { error in // in "swift test" test output goes to stdout XCTAssertMatch(error.stdout, .contains("testExample1")) @@ -189,7 +193,7 @@ final class TestCommandTests: CommandsTestCase { try await fixture(name: "Miscellaneous/EmptyTestsPkg") { fixturePath in let xUnitOutput = fixturePath.appending("result.xml") // Run tests in parallel with verbose output. - _ = try await SwiftPM.Test.execute(["--parallel", "--verbose", "--xunit-output", xUnitOutput.pathString], packagePath: fixturePath).stdout + _ = try await execute(["--parallel", "--verbose", "--xunit-output", xUnitOutput.pathString], packagePath: fixturePath).stdout // Check the xUnit output. XCTAssertFileExists(xUnitOutput) @@ -362,7 +366,7 @@ final class TestCommandTests: CommandsTestCase { func testSwiftTestFilter() async throws { try await fixture(name: "Miscellaneous/SkipTests") { fixturePath in - let (stdout, _) = try await SwiftPM.Test.execute(["--filter", ".*1"], packagePath: fixturePath) + let (stdout, _) = try await execute(["--filter", ".*1"], packagePath: fixturePath) // in "swift test" test output goes to stdout XCTAssertMatch(stdout, .contains("testExample1")) XCTAssertNoMatch(stdout, .contains("testExample2")) @@ -371,7 +375,7 @@ final class TestCommandTests: CommandsTestCase { } try await fixture(name: "Miscellaneous/SkipTests") { fixturePath in - let (stdout, _) = try await SwiftPM.Test.execute(["--filter", "SomeTests", "--skip", ".*1", "--filter", "testExample3"], packagePath: fixturePath) + let (stdout, _) = try await execute(["--filter", "SomeTests", "--skip", ".*1", "--filter", "testExample3"], packagePath: fixturePath) // in "swift test" test output goes to stdout XCTAssertNoMatch(stdout, .contains("testExample1")) XCTAssertMatch(stdout, .contains("testExample2")) @@ -382,7 +386,7 @@ final class TestCommandTests: CommandsTestCase { func testSwiftTestSkip() async throws { try await fixture(name: "Miscellaneous/SkipTests") { fixturePath in - let (stdout, _) = try await SwiftPM.Test.execute(["--skip", "SomeTests"], packagePath: fixturePath) + let (stdout, _) = try await execute(["--skip", "SomeTests"], packagePath: fixturePath) // in "swift test" test output goes to stdout XCTAssertNoMatch(stdout, .contains("testExample1")) XCTAssertNoMatch(stdout, .contains("testExample2")) @@ -391,7 +395,7 @@ final class TestCommandTests: CommandsTestCase { } try await fixture(name: "Miscellaneous/SkipTests") { fixturePath in - let (stdout, _) = try await SwiftPM.Test.execute(["--filter", "ExampleTests", "--skip", ".*2", "--filter", "MoreTests", "--skip", "testExample3"], packagePath: fixturePath) + let (stdout, _) = try await execute(["--filter", "ExampleTests", "--skip", ".*2", "--filter", "MoreTests", "--skip", "testExample3"], packagePath: fixturePath) // in "swift test" test output goes to stdout XCTAssertMatch(stdout, .contains("testExample1")) XCTAssertNoMatch(stdout, .contains("testExample2")) @@ -400,7 +404,7 @@ final class TestCommandTests: CommandsTestCase { } try await fixture(name: "Miscellaneous/SkipTests") { fixturePath in - let (stdout, _) = try await SwiftPM.Test.execute(["--skip", "Tests"], packagePath: fixturePath) + let (stdout, _) = try await execute(["--skip", "Tests"], packagePath: fixturePath) // in "swift test" test output goes to stdout XCTAssertNoMatch(stdout, .contains("testExample1")) XCTAssertNoMatch(stdout, .contains("testExample2")) @@ -414,26 +418,26 @@ final class TestCommandTests: CommandsTestCase { #if canImport(Darwin) // should emit when LinuxMain is present try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - let (_, stderr) = try await SwiftPM.Test.execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) + let (_, stderr) = try await execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) XCTAssertMatch(stderr, .contains("warning: '--enable-test-discovery' option is deprecated")) } // should emit when LinuxMain is not present try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in try localFileSystem.writeFileContents(fixturePath.appending(components: "Tests", SwiftModule.defaultTestEntryPointName), bytes: "fatalError(\"boom\")") - let (_, stderr) = try await SwiftPM.Test.execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) + let (_, stderr) = try await execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) XCTAssertMatch(stderr, .contains("warning: '--enable-test-discovery' option is deprecated")) } #else // should emit when LinuxMain is present try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - let (_, stderr) = try await SwiftPM.Test.execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) + let (_, stderr) = try await execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) XCTAssertMatch(stderr, .contains("warning: '--enable-test-discovery' option is deprecated")) } // should not emit when LinuxMain is present try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in try localFileSystem.writeFileContents(fixturePath.appending(components: "Tests", SwiftModule.defaultTestEntryPointName), bytes: "fatalError(\"boom\")") - let (_, stderr) = try await SwiftPM.Test.execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) + let (_, stderr) = try await execute(["--enable-test-discovery"] + compilerDiagnosticFlags, packagePath: fixturePath) XCTAssertNoMatch(stderr, .contains("warning: '--enable-test-discovery' option is deprecated")) } #endif @@ -441,7 +445,7 @@ final class TestCommandTests: CommandsTestCase { func testList() async throws { try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - let (stdout, stderr) = try await SwiftPM.Test.execute(["list"], packagePath: fixturePath) + let (stdout, stderr) = try await execute(["list"], packagePath: fixturePath) // build was run XCTAssertMatch(stderr, .contains("Build complete!")) // getting the lists @@ -458,7 +462,7 @@ final class TestCommandTests: CommandsTestCase { } // list do { - let (stdout, stderr) = try await SwiftPM.Test.execute(["list"], packagePath: fixturePath) + let (stdout, stderr) = try await execute(["list"], packagePath: fixturePath) // build was run XCTAssertMatch(stderr, .contains("Build complete!")) // getting the lists @@ -476,7 +480,7 @@ final class TestCommandTests: CommandsTestCase { } // list while skipping build do { - let (stdout, stderr) = try await SwiftPM.Test.execute(["list", "--skip-build"], packagePath: fixturePath) + let (stdout, stderr) = try await execute(["list", "--skip-build"], packagePath: fixturePath) // build was not run XCTAssertNoMatch(stderr, .contains("Build complete!")) // getting the lists @@ -490,7 +494,7 @@ final class TestCommandTests: CommandsTestCase { func testListWithSkipBuildAndNoBuildArtifacts() async throws { try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in await XCTAssertThrowsCommandExecutionError( - try await SwiftPM.Test.execute(["list", "--skip-build"], packagePath: fixturePath) + try await execute(["list", "--skip-build"], packagePath: fixturePath, throwIfCommandFails: true) ) { error in XCTAssertMatch(error.stderr, .contains("Test build artifacts were not found in the build folder")) } @@ -507,7 +511,7 @@ final class TestCommandTests: CommandsTestCase { try await fixture(name: "Miscellaneous/TestDiscovery/SwiftTesting") { fixturePath in do { - let (stdout, _) = try await SwiftPM.Test.execute(["--enable-swift-testing", "--disable-xctest"], packagePath: fixturePath) + let (stdout, _) = try await execute(["--enable-swift-testing", "--disable-xctest"], packagePath: fixturePath) XCTAssertMatch(stdout, .contains(#"Test "SOME TEST FUNCTION" started"#)) } } @@ -523,7 +527,7 @@ final class TestCommandTests: CommandsTestCase { try await fixture(name: "Miscellaneous/TestDiscovery/SwiftTesting") { fixturePath in do { - let (stdout, _) = try await SwiftPM.Test.execute(["--enable-experimental-swift-testing", "--disable-xctest"], packagePath: fixturePath) + let (stdout, _) = try await execute(["--enable-experimental-swift-testing", "--disable-xctest"], packagePath: fixturePath) XCTAssertMatch(stdout, .contains(#"Test "SOME TEST FUNCTION" started"#)) } } @@ -533,7 +537,7 @@ final class TestCommandTests: CommandsTestCase { func testGeneratedMainIsConcurrencySafe_XCTest() async throws { let strictConcurrencyFlags = ["-Xswiftc", "-strict-concurrency=complete"] try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - let (_, stderr) = try await SwiftPM.Test.execute(strictConcurrencyFlags, packagePath: fixturePath) + let (_, stderr) = try await execute(strictConcurrencyFlags, packagePath: fixturePath) XCTAssertNoMatch(stderr, .contains("is not concurrency-safe")) } } @@ -543,7 +547,7 @@ final class TestCommandTests: CommandsTestCase { func testGeneratedMainIsExistentialAnyClean() async throws { let existentialAnyFlags = ["-Xswiftc", "-enable-upcoming-feature", "-Xswiftc", "ExistentialAny"] try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - let (_, stderr) = try await SwiftPM.Test.execute(existentialAnyFlags, packagePath: fixturePath) + let (_, stderr) = try await execute(existentialAnyFlags, packagePath: fixturePath) XCTAssertNoMatch(stderr, .contains("error: use of protocol")) } } @@ -561,7 +565,7 @@ final class TestCommandTests: CommandsTestCase { func testXCTestOnlyDoesNotLogAboutNoMatchingTests() async throws { try await fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - let (_, stderr) = try await SwiftPM.Test.execute(["--disable-swift-testing"], packagePath: fixturePath) + let (_, stderr) = try await execute(["--disable-swift-testing"], packagePath: fixturePath) XCTAssertNoMatch(stderr, .contains("No matching test cases were run")) } } @@ -599,3 +603,126 @@ final class TestCommandTests: CommandsTestCase { } } + +class TestCommandNativeTests: TestCommandTestCase { + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .native + } + + override func testUsage() async throws { + try await super.testUsage() + } +} + + +class TestCommandSwiftBuildTests: TestCommandTestCase { + override open var buildSystemProvider: BuildSystemProvider.Kind { + return .swiftbuild + } + + override func testUsage() async throws { + try await super.testUsage() + } + + override func testFatalErrorDisplayedCorrectNumberOfTimesWhenSingleXCTestHasFatalErrorInBuildCompilation() async throws { + guard ProcessInfo.processInfo.environment["SWIFTPM_NO_SWBUILD_DEPENDENCY"] == nil else { + throw XCTSkip("Skipping test because SwiftBuild is not linked in.") + } + + try await super.testFatalErrorDisplayedCorrectNumberOfTimesWhenSingleXCTestHasFatalErrorInBuildCompilation() + } + + override func testListWithSkipBuildAndNoBuildArtifacts() async throws { + guard ProcessInfo.processInfo.environment["SWIFTPM_NO_SWBUILD_DEPENDENCY"] == nil else { + throw XCTSkip("Skipping test because SwiftBuild is not linked in.") + } + + try await super.testListWithSkipBuildAndNoBuildArtifacts() + } + + override func testList() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails due to 'error: build failed'") + } + + override func testEnableTestDiscoveryDeprecation() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails due to 'error: build failed'") + } + + override func testEnableDisableTestability() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails due to 'error: build failed'") + } + + override func testToolsetRunner() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails, as some assertions are not met") + } + + override func testWithReleaseConfiguration() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails with 'error: toolchain is invalid: could not find CLI tool `swiftpm-testing-helper` at any of these directories: [..., ...]'") + } + + override func testXCTestOnlyDoesNotLogAboutNoMatchingTests() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails assertion as the there is a different error message 'error: no tests found; create a target in the 'Tests' directory'") + } + + override func testSwiftTestXMLOutputVerifyMultipleTestFailureMessageWithFlagEnabledSwiftTesting() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails assertion as the there is a different error message 'error: no tests found; create a target in the 'Tests' directory'") + } + + override func testSwiftTestXMLOutputVerifySingleTestFailureMessageWithFlagDisabledSwiftTesting() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails, further investigation is needed") + } + + override func testSwiftTestXMLOutputVerifySingleTestFailureMessageWithFlagEnabledSwiftTesting() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails, further investigation is needed") + } + + override func testSwiftTestXMLOutputVerifyMultipleTestFailureMessageWithFlagDisabledSwiftTesting() async throws { + throw XCTSkip("SWBINTTODO: Test currently fails, further investigation is needed") + } + +#if !canImport(Darwin) + override func testGeneratedMainIsExistentialAnyClean() async throws { + throw XCTSkip("SWBINTTODO: This is a PIF builder missing GUID problem. Further investigation is needed.") + } +#endif + +#if !canImport(Darwin) + override func testGeneratedMainIsConcurrencySafe_XCTest() async throws { + throw XCTSkip("SWBINTTODO: This is a PIF builder missing GUID problem. Further investigation is needed.") + } +#endif + +#if !os(macOS) + override func testSwiftTestXMLOutputVerifySingleTestFailureMessageWithFlagDisabledXCTest() async throws { + throw XCTSkip("SWBINTTODO: Result XML could not be found. This looks to be a build layout issue. Further investigation is needed.") + } + + override func testSwiftTestXMLOutputVerifyMultipleTestFailureMessageWithFlagEnabledXCTest() async throws { + throw XCTSkip("SWBINTTODO: Result XML could not be found. This looks to be a build layout issue. Further investigation is needed.") + } + + override func testSwiftTestXMLOutputVerifySingleTestFailureMessageWithFlagEnabledXCTest() async throws { + throw XCTSkip("SWBINTTODO: Result XML could not be found. This looks to be a build layout issue. Further investigation is needed.") + } + + override func testSwiftTestXMLOutputVerifyMultipleTestFailureMessageWithFlagDisabledXCTest() async throws { + throw XCTSkip("SWBINTTODO: Result XML could not be found. This looks to be a build layout issue. Further investigation is needed.") + } + + override func testSwiftTestSkip() async throws { + throw XCTSkip("SWBINTTODO: This fails due to a linker error on Linux. Further investigation is needed.") + } + + override func testSwiftTestXMLOutputWhenEmpty() async throws { + throw XCTSkip("SWBINTTODO: This fails due to a linker error on Linux 'undefined reference to main'. Further investigation is needed.") + } + + override func testSwiftTestFilter() async throws { + throw XCTSkip("SWBINTTODO: This fails due to an unknown linker error on Linux. Further investigation is needed.") + } + + override func testSwiftTestParallel() async throws { + throw XCTSkip("SWBINTTODO: This fails due to the test expecting specific test output that appears to be empty on Linux. Further investigation is needed.") + } +#endif +} diff --git a/Tests/PackageRegistryTests/RegistryClientTests.swift b/Tests/PackageRegistryTests/RegistryClientTests.swift index e9c824e812c..dc59f4daf12 100644 --- a/Tests/PackageRegistryTests/RegistryClientTests.swift +++ b/Tests/PackageRegistryTests/RegistryClientTests.swift @@ -1360,7 +1360,7 @@ final class RegistryClientTests: XCTestCase { version: version, customToolsVersion: nil, observabilityScope: ObservabilitySystem.NOOP, - callbackQueue: .sharedConcurrent, + callbackQueue: .sharedConcurrent ) { continuation.resume(with: $0) } } let parsedToolsVersion = try ToolsVersionParser.parse(utf8String: manifestSync) @@ -3419,7 +3419,7 @@ final class RegistryClientTests: XCTestCase { signatureFormat: .none, fileSystem: localFileSystem, observabilityScope: ObservabilitySystem.NOOP, - callbackQueue: .sharedConcurrent, + callbackQueue: .sharedConcurrent ) { result in continuation.resume(with: result) } } diff --git a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift index fd4ee893e92..8569345b014 100644 --- a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift +++ b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift @@ -326,7 +326,7 @@ final class SourceKitLSPAPITests: XCTestCase { func testClangOutputPaths() async throws { let fs = InMemoryFileSystem(emptyFiles: "/Pkg/Sources/lib/include/lib.h", - "/Pkg/Sources/lib/lib.cpp", + "/Pkg/Sources/lib/lib.cpp" ) let observability = ObservabilitySystem.makeForTesting()