Skip to content

Tests: Augment SwiftBuild build provider test coverage #8555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 5 additions & 18 deletions IntegrationTests/Tests/IntegrationTests/SwiftPMTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,6 @@ private struct SwiftPMTests {
}

@Test(
.requireThreadSafeWorkingDirectory,
arguments: [BuildSystemProvider.native]
)
func packageInitExecutable(_ buildSystemProvider: BuildSystemProvider) throws {
try _packageInitExecutable(buildSystemProvider)
}

@Test(
.skipHostOS(.windows),
.requireThreadSafeWorkingDirectory,
.bug(
"https://github.com/swiftlang/swift-package-manager/issues/8416",
Expand All @@ -93,13 +84,9 @@ private struct SwiftPMTests {
"https://github.com/swiftlang/swift-package-manager/issues/8514",
"[Windows] Integration test SwiftPMTests.packageInitExecutable with --build-system swiftbuild is skipped"
),
arguments: [BuildSystemProvider.swiftbuild]
arguments: BuildSystemProvider.allCases
)
func packageInitExecutablSkipWindows(_ buildSystemProvider: BuildSystemProvider) throws {
try _packageInitExecutable(buildSystemProvider)
}

private func _packageInitExecutable(_ buildSystemProvider: BuildSystemProvider) throws {
private func packageInitExecutable(_ buildSystemProvider: BuildSystemProvider) throws {
try withTemporaryDirectory { tmpDir in
let packagePath = tmpDir.appending(component: "foo")
try localFileSystem.createDirectory(packagePath)
Expand All @@ -119,16 +106,16 @@ private struct SwiftPMTests {
#expect(!runOutput.stderr.contains("error:"))
#expect(runOutput.stdout.contains("Hello, world!"))
} when: {
buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem == .linux
buildSystemProvider == .swiftbuild && (ProcessInfo.hostOperatingSystem == .linux || ProcessInfo.hostOperatingSystem == .windows)
}
}
}

@Test(
.requireThreadSafeWorkingDirectory,
.bug(id: 0, "SWBINTTODO: Linux: /lib/x86_64-linux-gnu/Scrt1.o:function _start: error:"),
.bug(id: 0, "SwiftBuildTodo: Linux: /lib/x86_64-linux-gnu/Scrt1.o:function _start: error:"),
.bug("https://github.com/swiftlang/swift-package-manager/issues/8380", "lld-link: error: subsystem must be defined"),
.bug(id: 0, "SWBINTTODO: MacOS: Could not find or use auto-linked library 'Testing': library 'Testing' not found"),
.bug(id: 0, "SwiftBuildTodo: MacOS: Could not find or use auto-linked library 'Testing': library 'Testing' not found"),
arguments: BuildSystemProvider.allCases
)
func packageInitLibrary(_ buildSystemProvider: BuildSystemProvider) throws {
Expand Down
22 changes: 20 additions & 2 deletions Sources/SwiftBuildSupport/SwiftBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,22 @@ func withService(
func withSession(
service: SWBBuildService,
name: String,
toolchainPath: String,
packageManagerResourcesDirectory: Basics.AbsolutePath?,
body: @escaping (
_ session: SWBBuildServiceSession,
_ diagnostics: [SwiftBuild.SwiftBuildMessage.DiagnosticInfo]
) async throws -> Void
) async throws {
switch await service.createSession(name: name, resourceSearchPaths: packageManagerResourcesDirectory.map { [$0.pathString] } ?? [], cachePath: nil, inferiorProductsPath: nil, environment: nil) {
switch await service.createSession(
name: name,
swiftToolchainPath: toolchainPath,
resourceSearchPaths: packageManagerResourcesDirectory.map {
[$0.pathString]
} ?? [],
cachePath: nil, inferiorProductsPath: nil,
environment: nil
) {
case (.success(let session), let diagnostics):
do {
try await body(session, diagnostics)
Expand Down Expand Up @@ -260,7 +269,16 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
)

do {
try await withSession(service: service, name: self.buildParameters.pifManifest.pathString, packageManagerResourcesDirectory: self.packageManagerResourcesDirectory) { session, _ in
let toolchainPath = self.buildParameters.toolchain.swiftCompilerPath
.parentDirectory // remove swift
.parentDirectory // remove bin
.parentDirectory // remove usr
try await withSession(
service: service,
name: self.buildParameters.pifManifest.pathString,
toolchainPath: toolchainPath.pathString,
packageManagerResourcesDirectory: self.packageManagerResourcesDirectory
) { 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
Expand Down
14 changes: 13 additions & 1 deletion Sources/_InternalTestSupport/Commands.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import SPMBuildCore
import struct SPMBuildCore.BuildSystemProvider
import enum PackageModel.BuildConfiguration
import XCTest

open class BuildSystemProviderTestCase: XCTestCase {
open var buildSystemProvider: BuildSystemProvider.Kind {
fatalError("\(self) does not implement \(#function)")
}
}

open class BuildConfigurationTestCase: BuildSystemProviderTestCase {
open var binPathSuffixes: [String] {
fatalError("\(self) does not implement \(#function)")
}

open var buildConfig: BuildConfiguration {
fatalError("\(self) does not implement \(#function)")
}

}
9 changes: 7 additions & 2 deletions Sources/_InternalTestSupport/XCTAssertHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Basics
import class Foundation.Bundle
#endif
import SPMBuildCore
import enum PackageModel.BuildConfiguration
import TSCTestSupport
import XCTest

Expand Down Expand Up @@ -108,6 +109,10 @@ public func XCTSkipIfCompilerLessThan6_2() throws {
#endif
}

public func XCTSkipSwiftBuildTodo(because reason: String) throws {
throw XCTSkip("SwiftBuildTodo: \(reason)")
}

/// An `async`-friendly replacement for `XCTAssertThrowsError`.
public func XCTAssertAsyncThrowsError<T>(
_ expression: @autoclosure () async throws -> T,
Expand Down Expand Up @@ -139,7 +144,7 @@ package func XCTAssertAsyncNoThrow<T>(

public func XCTAssertBuilds(
_ path: AbsolutePath,
configurations: Set<Configuration> = [.Debug, .Release],
configurations: Set<BuildConfiguration> = [.debug, .release],
extraArgs: [String] = [],
Xcc: [String] = [],
Xld: [String] = [],
Expand Down Expand Up @@ -169,7 +174,7 @@ public func XCTAssertBuilds(

public func XCTAssertSwiftTest(
_ path: AbsolutePath,
configuration: Configuration = .Debug,
configuration: BuildConfiguration = .debug,
extraArgs: [String] = [],
Xcc: [String] = [],
Xld: [String] = [],
Expand Down
20 changes: 7 additions & 13 deletions Sources/_InternalTestSupport/misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ public func getBuildSystemArgs(for buildSystem: BuildSystemProvider.Kind?) -> [S
@discardableResult
public func executeSwiftBuild(
_ packagePath: AbsolutePath?,
configuration: Configuration = .Debug,
configuration: BuildConfiguration = .debug,
extraArgs: [String] = [],
Xcc: [String] = [],
Xld: [String] = [],
Expand All @@ -304,7 +304,7 @@ public func executeSwiftBuild(
public func executeSwiftRun(
_ packagePath: AbsolutePath?,
_ executable: String?,
configuration: Configuration = .Debug,
configuration: BuildConfiguration = .debug,
extraArgs: [String] = [],
Xcc: [String] = [],
Xld: [String] = [],
Expand All @@ -329,7 +329,7 @@ public func executeSwiftRun(
@discardableResult
public func executeSwiftPackage(
_ packagePath: AbsolutePath?,
configuration: Configuration = .Debug,
configuration: BuildConfiguration = .debug,
extraArgs: [String] = [],
Xcc: [String] = [],
Xld: [String] = [],
Expand All @@ -351,7 +351,7 @@ public func executeSwiftPackage(
@discardableResult
public func executeSwiftPackageRegistry(
_ packagePath: AbsolutePath?,
configuration: Configuration = .Debug,
configuration: BuildConfiguration = .debug,
extraArgs: [String] = [],
Xcc: [String] = [],
Xld: [String] = [],
Expand All @@ -373,7 +373,7 @@ public func executeSwiftPackageRegistry(
@discardableResult
public func executeSwiftTest(
_ packagePath: AbsolutePath?,
configuration: Configuration = .Debug,
configuration: BuildConfiguration = .debug,
extraArgs: [String] = [],
Xcc: [String] = [],
Xld: [String] = [],
Expand All @@ -394,20 +394,14 @@ public func executeSwiftTest(
}

private func swiftArgs(
configuration: Configuration,
configuration: BuildConfiguration,
extraArgs: [String],
Xcc: [String],
Xld: [String],
Xswiftc: [String],
buildSystem: BuildSystemProvider.Kind?
) -> [String] {
var args = ["--configuration"]
switch configuration {
case .Debug:
args.append("debug")
case .Release:
args.append("release")
}
var args = ["--configuration", "\(configuration)"]

args += Xcc.flatMap { ["-Xcc", $0] }
args += Xld.flatMap { ["-Xlinker", $0] }
Expand Down
24 changes: 12 additions & 12 deletions Tests/CommandsTests/BuildCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ class BuildCommandSwiftBuildTests: BuildCommandTestCases {
}

override func testNonReachableProductsAndTargetsFunctional() async throws {
throw XCTSkip("SWBINTTODO: Test failed. This needs to be investigated")
try XCTSkipSwiftBuildTodo(because: "Test failed. This needs to be investigated")
}

override func testParseableInterfaces() async throws {
Expand All @@ -871,7 +871,7 @@ class BuildCommandSwiftBuildTests: BuildCommandTestCases {
}

override func testAutomaticParseableInterfacesWithLibraryEvolution() async throws {
throw XCTSkip("SWBINTTODO: Test failed because of missing 'A.swiftmodule/*.swiftinterface' files")
try XCTSkipSwiftBuildTodo(because: "Test failed because of missing 'A.swiftmodule/*.swiftinterface' files")
// TODO: We still need to override this test just like we did for `testParseableInterfaces` above.
}

Expand All @@ -890,50 +890,50 @@ class BuildCommandSwiftBuildTests: BuildCommandTestCases {
}

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.")
try XCTSkipSwiftBuildTodo(because: "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.")
try XCTSkipSwiftBuildTodo(because: "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")
try XCTSkipSwiftBuildTodo(because: "File not found or missing libclang errors on non-macOS platforms. This needs to be investigated")
#else
try await super.testAtMainSupport()
#endif
}

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.")
try XCTSkipSwiftBuildTodo(because: "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")
try XCTSkipSwiftBuildTodo(because: "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")
try XCTSkipSwiftBuildTodo(because: "Test fails because the dummy-swiftc used in the test isn't accepted by swift-build. This needs to be investigated")
}

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")
try XCTSkipSwiftBuildTodo(because: "Test fails because of a difference in the build layout. This needs to be updated to the expected path")
}

#if os(Linux)
override func testIgnoresLinuxMain() async throws {
throw XCTSkip("SWBINTTODO: Swift build doesn't currently ignore Linux main when linking on Linux. This needs further investigation.")
try XCTSkipSwiftBuildTodo(because: "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.")
try XCTSkipSwiftBuildTodo(because: "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.")
try XCTSkipSwiftBuildTodo(because: "Swift build produces an error building the fixture for this test.")
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion Tests/CommandsTests/MultiRootSupportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import _InternalTestSupport
import Workspace
import XCTest

final class MultiRootSupportTests: CommandsTestCase {
final class MultiRootSupportTests: XCTestCase {
func testWorkspaceLoader() throws {
let fs = InMemoryFileSystem(emptyFiles: [
"/tmp/test/dep/Package.swift",
Expand Down
15 changes: 6 additions & 9 deletions Tests/CommandsTests/PackageCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,7 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase {

func testPackageClean() async throws {
try await fixture(name: "DependencyResolution/External/Simple") { fixturePath in
let packageRoot = fixturePath.appending("Bar")
let packageRoot: AbsolutePath = fixturePath.appending("Bar")

// Build it.
await XCTAssertBuilds(packageRoot)
Expand All @@ -1508,6 +1508,8 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase {
// Clean, and check for removal of the build directory but not Packages.
_ = try await execute(["clean"], packagePath: packageRoot)
XCTAssertNoSuchPath(binFile)
XCTAssertFalse(try localFileSystem.getDirectoryContents(buildPath.appending("repositories")).isEmpty)

// Clean again to ensure we get no error.
_ = try await execute(["clean"], packagePath: packageRoot)
}
Expand All @@ -1523,15 +1525,10 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase {
let binFile = buildPath.appending(components: try UserToolchain.default.targetTriple.platformBuildPathComponent, "debug", executableName("Bar"))
XCTAssertFileExists(binFile)
XCTAssert(localFileSystem.isDirectory(buildPath))
// Clean, and check for removal of the build directory but not Packages.

_ = try await execute(["clean"], packagePath: packageRoot)
XCTAssertNoSuchPath(binFile)
XCTAssertFalse(try localFileSystem.getDirectoryContents(buildPath.appending("repositories")).isEmpty)

// Fully clean.
_ = try await execute(["reset"], packagePath: packageRoot)
XCTAssertFalse(localFileSystem.isDirectory(buildPath))
XCTAssertFalse(localFileSystem.exists(buildPath))

// Test that we can successfully run reset again.
_ = try await execute(["reset"], packagePath: packageRoot)
Expand Down Expand Up @@ -4063,10 +4060,10 @@ class PackageCommandSwiftBuildTests: PackageCommandTestCase {
}

override func testCommandPluginBuildingCallbacks() async throws {
throw XCTSkip("SWBINTTODO: Test fails because plugin is not producing expected output to stdout.")
try XCTSkipSwiftBuildTodo(because: "Test fails because plugin is not producing expected output to stdout")
}
override func testCommandPluginBuildTestability() async throws {
throw XCTSkip("SWBINTTODO: Test fails as plugins are not currenty supported")
try XCTSkipSwiftBuildTodo(because: "Test fails as plugins are not currenty supported")
}

override func testMigrateCommand() async throws {
Expand Down
8 changes: 4 additions & 4 deletions Tests/CommandsTests/RunCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,18 +259,18 @@ class RunCommandSwiftBuildTests: RunCommandTestCase {
}

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")
try XCTSkipSwiftBuildTodo(because: "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")
try XCTSkipSwiftBuildTodo(because: "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")
try XCTSkipSwiftBuildTodo(because: "Test fixture fails to build")
}

override func testUnreachableExecutable() async throws {
throw XCTSkip("SWBINTTODO: Test fails because of build layout differences.")
try XCTSkipSwiftBuildTodo(because: "Test fails because of build layout differences.")
}
}
Loading