Skip to content

Commit ed4df9b

Browse files
committed
Tests: Migrate BuildSystemDelegateTests to Swift Testing and augment
Migrate the `BuildSystemDelegateTests` test to Swift Testing and augment the test to run against both the Native and SwiftBUild build system, in addition to the `debug`` and `release` build configuration. Depends on: #9012 Relates to: #8997 issue: rdar://157669245
1 parent 25ff1f3 commit ed4df9b

File tree

7 files changed

+148
-89
lines changed

7 files changed

+148
-89
lines changed

Sources/_InternalTestSupport/BuildSystemProvider+Configuration.swift

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,18 @@
1212

1313
import struct SPMBuildCore.BuildSystemProvider
1414
import enum PackageModel.BuildConfiguration
15+
import class PackageModel.UserToolchain
1516

1617
extension BuildSystemProvider.Kind {
1718

19+
@available(*, deprecated, message: "use binPath(for:scrathPath:triple) instead")
1820
public func binPathSuffixes(for config: BuildConfiguration) -> [String] {
1921
let suffix: String
2022

2123
#if os(Linux)
2224
suffix = "-linux"
2325
#elseif os(Windows)
24-
suffix = "-windows"
26+
suffix = "-windows"
2527
#else
2628
suffix = ""
2729
#endif
@@ -34,4 +36,40 @@ extension BuildSystemProvider.Kind {
3436
return ["apple", "Products" , "\(config)".capitalized + suffix]
3537
}
3638
}
39+
40+
public func binPath(
41+
for config: BuildConfiguration,
42+
scratchPath: [String] = [".build"],
43+
triple: String? = nil,
44+
) throws -> [String] {
45+
let suffix: String
46+
47+
#if os(Linux)
48+
suffix = "-linux"
49+
#elseif os(Windows)
50+
suffix = "-windows"
51+
#else
52+
suffix = ""
53+
#endif
54+
55+
let tripleString: String
56+
if let triple {
57+
tripleString = triple
58+
} else {
59+
do {
60+
tripleString = try UserToolchain.default.targetTriple.platformBuildPathComponent
61+
} catch {
62+
tripleString = ""
63+
}
64+
}
65+
switch self {
66+
case .native:
67+
return scratchPath + [tripleString, "\(config)".lowercased()]
68+
case .swiftbuild:
69+
return scratchPath + [tripleString, "Products", "\(config)".capitalized + suffix]
70+
case .xcode:
71+
return scratchPath + ["apple", "Products", "\(config)".capitalized + suffix]
72+
}
73+
}
74+
3775
}

Sources/_InternalTestSupport/SwiftTesting+TraitConditional.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ extension Trait where Self == Testing.ConditionTrait {
7979
}
8080
}
8181

82+
/// Enabled if toolsupm suported SDK Dependent Tests
83+
public static var requiresSDKDependentTestsSupport: Self {
84+
enabled("skipping because test environment doesn't support this test") {
85+
(try? UserToolchain.default)!.supportsSDKDependentTests()
86+
}
87+
}
88+
8289
// Enabled if the toolchain has supported features
8390
public static var supportsSupportedFeatures: Self {
8491
enabled("skipping because test environment compiler doesn't support `-print-supported-features`") {

Tests/BuildTests/BuildSystemDelegateTests.swift

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,94 @@
22
//
33
// This source file is part of the Swift open source project
44
//
5-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2024-2025 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See http://swift.org/LICENSE.txt for license information
99
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12+
import Foundation
1213

1314
import PackageModel
1415
import _InternalTestSupport
15-
import XCTest
16+
import Testing
1617

1718
import var TSCBasic.localFileSystem
1819

19-
final class BuildSystemDelegateTests: XCTestCase {
20-
func testDoNotFilterLinkerDiagnostics() async throws {
21-
try XCTSkipIf(!UserToolchain.default.supportsSDKDependentTests(), "skipping because test environment doesn't support this test")
22-
try await fixtureXCTest(name: "Miscellaneous/DoNotFilterLinkerDiagnostics") { fixturePath in
23-
#if !os(macOS)
24-
// These linker diagnostics are only produced on macOS.
25-
try XCTSkipIf(true, "test is only supported on macOS")
26-
#endif
27-
let (fullLog, _) = try await executeSwiftBuild(fixturePath, buildSystem: .native)
28-
XCTAssertTrue(fullLog.contains("ld: warning: search path 'foobar' not found"), "log didn't contain expected linker diagnostics")
20+
@Suite(
21+
.tags(
22+
.TestSize.large,
23+
)
24+
)
25+
struct BuildSystemDelegateTests {
26+
@Test(
27+
.requiresSDKDependentTestsSupport,
28+
.requireHostOS(.macOS), // These linker diagnostics are only produced on macOS.
29+
arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms),
30+
)
31+
func doNotFilterLinkerDiagnostics(
32+
data: BuildData,
33+
) async throws {
34+
try await fixture(name: "Miscellaneous/DoNotFilterLinkerDiagnostics") { fixturePath in
35+
let (stdout, stderr) = try await executeSwiftBuild(
36+
fixturePath,
37+
configuration: data.config,
38+
buildSystem: data.buildSystem,
39+
)
40+
switch data.buildSystem {
41+
42+
case .native:
43+
#expect(
44+
stdout.contains("ld: warning: search path 'foobar' not found"),
45+
"log didn't contain expected linker diagnostics. stderr: '\(stderr)')",
46+
)
47+
case .swiftbuild:
48+
#expect(
49+
!stderr.contains("warning: search path 'foobar' not found"),
50+
"log didn't contain expected linker diagnostics. stdout: '\(stdout)')",
51+
)
52+
#expect(
53+
!stdout.contains("warning: search path 'foobar' not found"),
54+
"log didn't contain expected linker diagnostics. stderr: '\(stderr)')",
55+
)
56+
case .xcode:
57+
Issue.record("Test expectation has not be implemented")
58+
}
2959
}
3060
}
3161

32-
func testFilterNonFatalCodesignMessages() async throws {
33-
try XCTSkipOnWindows(because: "https://github.com/swiftlang/swift-package-manager/issues/8540: Package fails to build when the test is being executed")
34-
35-
try XCTSkipIf(!UserToolchain.default.supportsSDKDependentTests(), "skipping because test environment doesn't support this test")
36-
// Note: we can re-use the `TestableExe` fixture here since we just need an executable.
37-
#if os(Windows)
38-
let executableExt = ".exe"
39-
#else
40-
let executableExt = ""
41-
#endif
42-
try await fixtureXCTest(name: "Miscellaneous/TestableExe") { fixturePath in
43-
_ = try await executeSwiftBuild(fixturePath, buildSystem: .native)
44-
let execPath = fixturePath.appending(components: ".build", "debug", "TestableExe1\(executableExt)")
45-
XCTAssertTrue(localFileSystem.exists(execPath), "executable not found at '\(execPath)'")
46-
try localFileSystem.removeFileTree(execPath)
47-
let (fullLog, _) = try await executeSwiftBuild(fixturePath, buildSystem: .native)
48-
XCTAssertFalse(fullLog.contains("replacing existing signature"), "log contained non-fatal codesigning messages")
62+
@Test(
63+
.issue("https://github.com/swiftlang/swift-package-manager/issues/8540", relationship: .defect), // Package fails to build when the test is being executed"
64+
.requiresSDKDependentTestsSupport,
65+
arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms),
66+
)
67+
func filterNonFatalCodesignMessages(
68+
data: BuildData,
69+
) async throws {
70+
try await withKnownIssue {
71+
// Note: we can re-use the `TestableExe` fixture here since we just need an executable.
72+
try await fixture(name: "Miscellaneous/TestableExe") { fixturePath in
73+
_ = try await executeSwiftBuild(
74+
fixturePath,
75+
configuration: data.config,
76+
buildSystem: data.buildSystem,
77+
)
78+
let execPath = try fixturePath.appending(
79+
components: data.buildSystem.binPath(for: data.config) + [executableName("TestableExe1")]
80+
)
81+
expectFileExists(at: execPath)
82+
try localFileSystem.removeFileTree(execPath)
83+
let (stdout, stderr) = try await executeSwiftBuild(
84+
fixturePath,
85+
configuration: data.config,
86+
buildSystem: data.buildSystem,
87+
)
88+
#expect(!stdout.contains("replacing existing signature"), "log contained non-fatal codesigning messages stderr: '\(stderr)'")
89+
#expect(!stderr.contains("replacing existing signature"), "log contained non-fatal codesigning messages. stdout: '\(stdout)'")
90+
}
91+
} when: {
92+
ProcessInfo.hostOperatingSystem == .windows
4993
}
5094
}
5195
}

Tests/CommandsTests/BuildCommandTests.swift

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ struct SanitierTests {
5252
}
5353

5454
@Suite(
55-
.serialized, // to limit the number of swift executable running.
5655
.tags(
5756
Tag.TestSize.large,
5857
Tag.Feature.Command.Build,
@@ -165,18 +164,11 @@ struct BuildCommandTestCases {
165164
// Test is not implemented for Xcode build system
166165
try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in
167166
let fullPath = try resolveSymlinks(fixturePath)
168-
169-
let rootScrathPath = fullPath.appending(component: ".build")
170-
let targetPath: AbsolutePath
171-
if buildSystem == .xcode {
172-
targetPath = rootScrathPath
173-
} else {
174-
targetPath = try rootScrathPath.appending(component: UserToolchain.default.targetTriple.platformBuildPathComponent)
175-
}
167+
168+
let targetPath = try fullPath.appending(components: buildSystem.binPath(for: configuration))
176169
let path = try await self.execute(["--show-bin-path"], packagePath: fullPath, configuration: configuration, buildSystem: buildSystem).stdout.trimmingCharacters(in: .whitespacesAndNewlines)
177170
#expect(
178-
AbsolutePath(path).pathString == targetPath
179-
.appending(components: buildSystem.binPathSuffixes(for: configuration)).pathString
171+
AbsolutePath(path).pathString == targetPath.pathString
180172
)
181173
}
182174
}
@@ -288,29 +280,19 @@ struct BuildCommandTestCases {
288280
}
289281

290282
@Test(
291-
.SWBINTTODO("Test fails because of a difference in the build layout. This needs to be updated to the expected path"),
292283
arguments: SupportedBuildSystemOnPlatform, BuildConfiguration.allCases
293284
)
294285
func symlink(
295286
buildSystem: BuildSystemProvider.Kind,
296287
configuration: BuildConfiguration,
297288
) async throws {
298-
try await withKnownIssue {
299-
try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in
300-
let fullPath = try resolveSymlinks(fixturePath)
301-
let targetPath = try fullPath.appending(components:
302-
".build",
303-
UserToolchain.default.targetTriple.platformBuildPathComponent
304-
)
305-
// Test symlink.
306-
let buildDir = fullPath.appending(components: ".build")
307-
try await self.execute(packagePath: fullPath, configuration: configuration, buildSystem: buildSystem)
308-
let actualDebug = try resolveSymlinks(buildDir.appending(components: buildSystem.binPathSuffixes(for: configuration)))
309-
let expectedDebug = targetPath.appending(components: buildSystem.binPathSuffixes(for: configuration))
310-
#expect(actualDebug == expectedDebug)
311-
}
312-
} when: {
313-
buildSystem != .native
289+
try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in
290+
let fullPath = try resolveSymlinks(fixturePath)
291+
// Test symlink.
292+
try await self.execute(packagePath: fullPath, configuration: configuration, buildSystem: buildSystem)
293+
let actualDebug = try resolveSymlinks(fullPath.appending(components: buildSystem.binPath(for: configuration)))
294+
let expectedDebug = try fullPath.appending(components: buildSystem.binPath(for: configuration))
295+
#expect(actualDebug == expectedDebug)
314296
}
315297
}
316298

@@ -1125,10 +1107,9 @@ struct BuildCommandTestCases {
11251107
return try SupportedBuildSystemOnPlatform.map { buildSystem in
11261108
let triple = try UserToolchain.default.targetTriple.withoutVersion()
11271109
let base = try RelativePath(validating: ".build")
1128-
let debugFolderComponents = buildSystem.binPathSuffixes(for: .debug)
1110+
let path = try base.appending(components: buildSystem.binPath(for: .debug, scratchPath: []))
11291111
switch buildSystem {
11301112
case .xcode:
1131-
let path = base.appending(components: debugFolderComponents)
11321113
return (
11331114
buildSystem,
11341115
triple.platformName() == "macosx" ? path.appending("ExecutableNew") : path
@@ -1137,8 +1118,6 @@ struct BuildCommandTestCases {
11371118
.appending("\(triple).swiftsourceinfo")
11381119
)
11391120
case .swiftbuild:
1140-
let path = base.appending(triple.tripleString)
1141-
.appending(components: debugFolderComponents)
11421121
return (
11431122
buildSystem,
11441123
triple.platformName() == "macosx" ? path.appending("ExecutableNew") : path
@@ -1149,8 +1128,7 @@ struct BuildCommandTestCases {
11491128
case .native:
11501129
return (
11511130
buildSystem,
1152-
base.appending(components: debugFolderComponents)
1153-
.appending("ExecutableNew.build")
1131+
path.appending("ExecutableNew.build")
11541132
.appending("main.swift.o")
11551133
)
11561134
}

Tests/FunctionalTests/DependencyResolutionTests.swift

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@ struct DependencyResolutionTests {
5050
buildSystem: buildSystem,
5151
)
5252

53-
let executablePath = try fixturePath.appending(
54-
components: [".build", UserToolchain.default.targetTriple.platformBuildPathComponent]
55-
+ buildSystem.binPathSuffixes(for: configuration) + ["Foo"]
56-
)
53+
let binPath = try fixturePath.appending(components: buildSystem.binPath(for: configuration))
54+
let executablePath = binPath.appending(components: "Foo")
5755
let output = try await AsyncProcess.checkNonZeroExit(args: executablePath.pathString).withSwiftLineEnding
5856
#expect(output == "Foo\nBar\n")
5957
}
@@ -111,10 +109,8 @@ struct DependencyResolutionTests {
111109
buildSystem: buildSystem,
112110
)
113111

114-
let executablePath = try fixturePath.appending(
115-
components: [".build", UserToolchain.default.targetTriple.platformBuildPathComponent]
116-
+ buildSystem.binPathSuffixes(for: configuration) + ["Foo"]
117-
)
112+
let binPath = try fixturePath.appending(components: buildSystem.binPath(for: configuration))
113+
let executablePath = binPath.appending(components: "Foo")
118114
let output = try await AsyncProcess.checkNonZeroExit(args: executablePath.pathString)
119115
.withSwiftLineEnding
120116
#expect(output == "meiow Baz\n")
@@ -152,12 +148,8 @@ struct DependencyResolutionTests {
152148
configuration: configuration,
153149
buildSystem: buildSystem,
154150
)
155-
let executablePath = packageRoot.appending(
156-
components: [
157-
".build",
158-
try UserToolchain.default.targetTriple.platformBuildPathComponent,
159-
] + buildSystem.binPathSuffixes(for: configuration) + [executableName("Bar")]
160-
)
151+
let binPath = try packageRoot.appending(components: buildSystem.binPath(for: configuration))
152+
let executablePath = binPath.appending(components: executableName("Bar"))
161153
#expect(
162154
localFileSystem.exists(executablePath),
163155
"Path \(executablePath) does not exist",
@@ -185,16 +177,15 @@ struct DependencyResolutionTests {
185177
) async throws {
186178
try await withKnownIssue(isIntermittent: ProcessInfo.hostOperatingSystem == .windows){
187179
try await fixture(name: "DependencyResolution/External/Complex") { fixturePath in
180+
let packageRoot = fixturePath.appending("app")
188181
try await executeSwiftBuild(
189-
fixturePath.appending("app"),
182+
packageRoot,
190183
configuration: configuration,
191184
buildSystem: buildSystem,
192185
)
193-
let executablePath = try fixturePath.appending(
194-
components: [
195-
"app", ".build", UserToolchain.default.targetTriple.platformBuildPathComponent,
196-
] + buildSystem.binPathSuffixes(for: configuration) + ["Dealer"]
197-
)
186+
let binPath = try packageRoot.appending(components: buildSystem.binPath(for: configuration))
187+
let executablePath = binPath.appending(components: "Dealer")
188+
expectFileExists(at: executablePath)
198189
let output = try await AsyncProcess.checkNonZeroExit(args: executablePath.pathString)
199190
.withSwiftLineEnding
200191
#expect(output == "♣︎K\n♣︎Q\n♣︎J\n♣︎10\n♣︎9\n♣︎8\n♣︎7\n♣︎6\n♣︎5\n♣︎4\n")

Tests/FunctionalTests/ModuleAliasingFixtureTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct ModuleAliasingFixtureTests {
3939
try await withKnownIssue(isIntermittent: true) {
4040
try await fixture(name: "ModuleAliasing/DirectDeps1") { fixturePath in
4141
let pkgPath = fixturePath.appending(components: "AppPkg")
42-
let buildPath = pkgPath.appending(components: [".build", try UserToolchain.default.targetTriple.platformBuildPathComponent] + buildSystem.binPathSuffixes(for: configuration))
42+
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
4343
try await executeSwiftBuild(
4444
pkgPath,
4545
configuration: configuration,
@@ -82,7 +82,7 @@ struct ModuleAliasingFixtureTests {
8282
try await withKnownIssue {
8383
try await fixture(name: "ModuleAliasing/DirectDeps2") { fixturePath in
8484
let pkgPath = fixturePath.appending(components: "AppPkg")
85-
let buildPath = pkgPath.appending(components: [".build", try UserToolchain.default.targetTriple.platformBuildPathComponent] + buildSystem.binPathSuffixes(for: configuration))
85+
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
8686
try await executeSwiftBuild(
8787
pkgPath,
8888
configuration: configuration,
@@ -117,7 +117,7 @@ struct ModuleAliasingFixtureTests {
117117
try await withKnownIssue {
118118
try await fixture(name: "ModuleAliasing/NestedDeps1") { fixturePath in
119119
let pkgPath = fixturePath.appending(components: "AppPkg")
120-
let buildPath = pkgPath.appending(components: [".build", try UserToolchain.default.targetTriple.platformBuildPathComponent] + buildSystem.binPathSuffixes(for: configuration))
120+
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
121121
try await executeSwiftBuild(
122122
pkgPath,
123123
configuration: configuration,
@@ -156,7 +156,7 @@ struct ModuleAliasingFixtureTests {
156156
try await withKnownIssue {
157157
try await fixture(name: "ModuleAliasing/NestedDeps2") { fixturePath in
158158
let pkgPath = fixturePath.appending(components: "AppPkg")
159-
let buildPath = pkgPath.appending(components: [".build", try UserToolchain.default.targetTriple.platformBuildPathComponent] + buildSystem.binPathSuffixes(for: configuration))
159+
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
160160
try await executeSwiftBuild(
161161
pkgPath,
162162
configuration: configuration,

0 commit comments

Comments
 (0)