Skip to content

Commit 63ca4fb

Browse files
committed
Updates tests for execution on non Apple hosts.
- Update StringChecker to handle Windows line endings. - Use .exe suffix for executables on Windows - Use where.exe on Windows for tool location detection. - Enable unconditionally skipped tests, marking with known issue where appropriate. - Fix unconditionally skipped tests, skipping was added many years ago and never removed. - Add matrix style testing for the build system (native/swiftbuild) on "swift init/build/test" tests.
1 parent 6c179de commit 63ca4fb

File tree

5 files changed

+78
-56
lines changed

5 files changed

+78
-56
lines changed

Diff for: IntegrationTests/Sources/IntegrationTestSupport/Helpers.swift

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public let toolchainPath: AbsolutePath = {
3737
let swiftcPath = try! AbsolutePath(
3838
validating: sh("xcrun", "--find", "swift").stdout.spm_chomp()
3939
)
40+
#elseif os(Windows)
41+
let swiftcPath = try! AbsolutePath(validating: sh("where.exe", "swift.exe").stdout.spm_chomp())
4042
#else
4143
let swiftcPath = try! AbsolutePath(validating: sh("which", "swift").stdout.spm_chomp())
4244
#endif

Diff for: IntegrationTests/Sources/IntegrationTestSupport/Process.swift

+12
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,16 @@ extension ProcessInfo {
2828
#else
2929
public static let hostOperatingSystem = OperatingSystem.unknown
3030
#endif
31+
32+
#if os(Windows)
33+
public static let EOL = "\r\n"
34+
#else
35+
public static let EOL = "\n"
36+
#endif
37+
38+
#if os(Windows)
39+
public static let exeSuffix = ".exe"
40+
#else
41+
public static let exeSuffix = ""
42+
#endif
3143
}

Diff for: IntegrationTests/Sources/IntegrationTestSupport/StringChecker.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class StringChecker {
1818

1919
public init(string: String) {
2020
self.string = string
21-
self.lines = string.split(separator: "\n")
21+
self.lines = string.split(separator: ProcessInfo.EOL)
2222
self.currentLineIndex = 0
2323
}
2424

Diff for: IntegrationTests/Tests/IntegrationTests/BasicTests.swift

+37-31
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import Foundation
1112
import IntegrationTestSupport
1213
import Testing
1314
import TSCBasic
@@ -22,13 +23,15 @@ private struct BasicTests {
2223
@Test(
2324
.skipSwiftCISelfHosted(
2425
"These packages don't use the latest runtime library, which doesn't work with self-hosted builds."
25-
)
26+
),
27+
.skipHostOS(.windows, "random.swift:34:8: error: unsupported platform")
2628
)
2729
func testExamplePackageDealer() throws {
2830
try withTemporaryDirectory { tempDir in
2931
let packagePath = tempDir.appending(component: "dealer")
30-
try sh("git", "clone", "https://github.com/apple/example-package-dealer", packagePath)
32+
try sh("git\(ProcessInfo.exeSuffix)", "clone", "https://github.com/apple/example-package-dealer", packagePath)
3133
let build1Output = try sh(swiftBuild, "--package-path", packagePath).stdout
34+
3235
// Check the build log.
3336
#expect(build1Output.contains("Build complete"))
3437

@@ -40,7 +43,7 @@ private struct BasicTests {
4043

4144
// Verify that the 'git status' is clean after a build.
4245
try localFileSystem.changeCurrentWorkingDirectory(to: packagePath)
43-
let gitOutput = try sh("git", "status").stdout
46+
let gitOutput = try sh("git\(ProcessInfo.exeSuffix)", "status").stdout
4447
#expect(gitOutput.contains("nothing to commit, working tree clean"))
4548

4649
// Verify that another 'swift build' does nothing.
@@ -83,7 +86,7 @@ private struct BasicTests {
8386
// Verify that the tool exists and works.
8487
let toolOutput = try sh(packagePath.appending(components: ".build", "debug", "tool"))
8588
.stdout
86-
#expect(toolOutput == "HI\n")
89+
#expect(toolOutput == "HI\(ProcessInfo.EOL)")
8790
}
8891
}
8992

@@ -103,7 +106,7 @@ private struct BasicTests {
103106

104107
// Check the file runs.
105108
let helloOutput = try sh(helloBinaryPath).stdout
106-
#expect(helloOutput == "hello\n")
109+
#expect(helloOutput == "hello\(ProcessInfo.EOL)")
107110
}
108111
}
109112

@@ -133,24 +136,26 @@ private struct BasicTests {
133136
}
134137
}
135138

136-
@Test(.skip("FIXME: swift-test invocations are timing out in Xcode and self-hosted CI"))
139+
@Test
137140
func testSwiftPackageInitExecTests() throws {
138141
try withTemporaryDirectory { tempDir in
139142
// Create a new package with an executable target.
140143
let packagePath = tempDir.appending(component: "Project")
141144
try localFileSystem.createDirectory(packagePath)
142-
try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "executable")
143-
let testOutput = try sh(swiftTest, "--package-path", packagePath).stdout
144-
145-
// Check the test log.
146-
let checker = StringChecker(string: testOutput)
147-
#expect(checker.check(.regex("Compiling .*ProjectTests.*")))
148-
#expect(checker.check("Test Suite 'All tests' passed"))
149-
#expect(checker.checkNext("Executed 1 test"))
150-
151-
// Check there were no compile errors or warnings.
152-
#expect(testOutput.contains("error") == false)
153-
#expect(testOutput.contains("warning") == false)
145+
withKnownIssue("error: no tests found; create a target in the 'Tests' directory") {
146+
try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "executable")
147+
let testOutput = try sh(swiftTest, "--package-path", packagePath).stdout
148+
149+
// Check the test log.
150+
let checker = StringChecker(string: testOutput)
151+
#expect(checker.check(.regex("Compiling .*ProjectTests.*")))
152+
#expect(checker.check("Test Suite 'All tests' passed"))
153+
#expect(checker.checkNext("Executed 1 test"))
154+
155+
// Check there were no compile errors or warnings.
156+
#expect(testOutput.contains("error") == false)
157+
#expect(testOutput.contains("warning") == false)
158+
}
154159
}
155160
}
156161

@@ -173,7 +178,7 @@ private struct BasicTests {
173178
}
174179
}
175180

176-
@Test(.skip("FIXME: swift-test invocations are timing out in Xcode and self-hosted CI"))
181+
@Test
177182
func testSwiftPackageLibsTests() throws {
178183
try withTemporaryDirectory { tempDir in
179184
// Create a new package with an executable target.
@@ -184,9 +189,9 @@ private struct BasicTests {
184189

185190
// Check the test log.
186191
let checker = StringChecker(string: testOutput)
187-
#expect(checker.check(.regex("Compiling .*ProjectTests.*")))
188-
#expect(checker.check("Test Suite 'All tests' passed"))
189-
#expect(checker.checkNext("Executed 1 test"))
192+
#expect(checker.check(.contains("Test Suite 'All tests' started")))
193+
#expect(checker.check(.contains("Test example() passed after")))
194+
#expect(checker.checkNext(.contains("Test run with 1 test passed after")))
190195

191196
// Check there were no compile errors or warnings.
192197
#expect(testOutput.contains("error") == false)
@@ -226,17 +231,19 @@ private struct BasicTests {
226231

227232
// Check the build.
228233
let buildOutput = try sh(swiftBuild, "--package-path", packagePath, "-v").stdout
229-
#expect(try
230-
#/swiftc.* -module-name special_tool .* '@.*/more spaces/special tool/.build/[^/]+/debug/special_tool.build/sources'/#
231-
.firstMatch(in: buildOutput) != nil
232-
)
234+
let expression = ProcessInfo
235+
.hostOperatingSystem != .windows ?
236+
#/swiftc.* -module-name special_tool .* '@.*/more spaces/special tool/.build/[^/]+/debug/special_tool.build/sources'/# :
237+
#/swiftc.* -module-name special_tool .* "@.*\\more spaces\\special tool\\.build\\[^\\]+\\debug\\special_tool.build\\sources"/#
238+
#expect(try expression.firstMatch(in: buildOutput) != nil)
233239
#expect(buildOutput.contains("Build complete"))
234240

235241
// Verify that the tool exists and works.
236242
let toolOutput = try sh(
237243
packagePath.appending(components: ".build", "debug", "special tool")
238244
).stdout
239-
#expect(toolOutput == "HI\n")
245+
246+
#expect(toolOutput == "HI\(ProcessInfo.EOL)")
240247
}
241248
}
242249

@@ -273,11 +280,10 @@ private struct BasicTests {
273280
#expect(checker.check(.regex("Linking .*secho")))
274281
#expect(checker.check(.contains("Build of product 'secho' complete")))
275282

276-
#expect(runOutput == "1 \"two\"\n")
283+
#expect(runOutput == "1 \"two\"\(ProcessInfo.EOL)")
277284
}
278285
}
279286

280-
@Test(.skip("FIXME: swift-test invocations are timing out in Xcode and self-hosted CI"))
281287
func testSwiftTest() throws {
282288
try withTemporaryDirectory { tempDir in
283289
let packagePath = tempDir.appending(component: "swiftTest")
@@ -314,7 +320,7 @@ private struct BasicTests {
314320
}
315321
}
316322

317-
@Test(.skip("FIXME: swift-test invocations are timing out in Xcode and self-hosted CI"))
323+
@Test
318324
func testSwiftTestWithResources() throws {
319325
try withTemporaryDirectory { tempDir in
320326
let packagePath = tempDir.appending(component: "swiftTestResources")
@@ -395,7 +401,7 @@ private struct BasicTests {
395401

396402
let testOutput = try sh(
397403
swiftTest, "--package-path", packagePath, "--filter", "MyTests.*"
398-
).stderr
404+
).stdout
399405

400406
// Check the test log.
401407
let checker = StringChecker(string: testOutput)

Diff for: IntegrationTests/Tests/IntegrationTests/SwiftPMTests.swift

+26-24
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ import Testing
1414
import TSCBasic
1515
import TSCTestSupport
1616

17+
// TODO: This should be replaced with BuildSystem.BuildSystemProvider if 'IntegrationTests' are moved up under the swift-package-manager tests.
18+
public enum BuildSystemProvider: String, Codable, CaseIterable {
19+
case native
20+
case swiftbuild
21+
}
22+
1723
@Suite
1824
private struct SwiftPMTests {
1925
@Test(.requireHostOS(.macOS))
@@ -68,45 +74,41 @@ private struct SwiftPMTests {
6874
}
6975
}
7076

71-
@Test(.requireThreadSafeWorkingDirectory)
72-
func packageInitExecutable() throws {
77+
@Test(.requireThreadSafeWorkingDirectory, arguments: BuildSystemProvider.allCases)
78+
func packageInitExecutable(_ buildSystemProvider: BuildSystemProvider) throws {
7379
// Executable
7480
do {
7581
try withTemporaryDirectory { tmpDir in
7682
let packagePath = tmpDir.appending(component: "foo")
7783
try localFileSystem.createDirectory(packagePath)
7884
try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "executable")
79-
try sh(swiftBuild, "--package-path", packagePath, "--build-system", "swiftbuild")
80-
// SWBINTTODO: Path issues related to swift test of the output from a swiftbuild buildsystem
81-
// let (stdout, stderr) = try sh(
82-
// swiftRun, "--package-path", packagePath, "--build-system", "swiftbuild"
83-
// )
84-
// #expect(!stderr.contains("error:"))
85-
// #expect(stdout.contains("Hello, world!"))
85+
try sh(swiftBuild, "--package-path", packagePath, "--build-system", buildSystemProvider.rawValue, "--vv")
86+
let (stdout, stderr) = try sh(
87+
swiftRun, "--package-path", packagePath, "--build-system", buildSystemProvider.rawValue, "--vv"
88+
)
89+
#expect(!stderr.contains("error:"))
90+
#expect(stdout.contains("Hello, world!"))
8691
}
8792
}
8893
}
8994

90-
@Test(
91-
.skipHostOS(
92-
.windows,
93-
"Windows fails to link this library package due to a 'lld-link: error: subsystem must be defined' error. See https://github.com/swiftlang/swift-build/issues/310"
94-
),
95-
.requireThreadSafeWorkingDirectory
96-
)
97-
func packageInitLibrary() throws {
95+
@Test(.requireThreadSafeWorkingDirectory, arguments: BuildSystemProvider.allCases)
96+
func packageInitLibrary(_ buildSystemProvider: BuildSystemProvider) throws {
9897
do {
9998
try withTemporaryDirectory { tmpDir in
10099
let packagePath = tmpDir.appending(component: "foo")
101100
try localFileSystem.createDirectory(packagePath)
102101
try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "library")
103-
try sh(swiftBuild, "--package-path", packagePath, "--build-system", "swiftbuild")
104-
// SWBINTTODO: Path issues related to swift test of the output from a swiftbuild buildsystem
105-
// let (stdout, stderr) = try sh(
106-
// swiftTest, "--package-path", packagePath, "--build-system", "swiftbuild"
107-
// )
108-
// #expect(!stderr.contains("error:"))
109-
// #expect(stdout.contains("Test Suite 'All tests' passed"))
102+
try withKnownIssue("unknown Argument unused during compilation: '-rdynamic'") {
103+
try sh(swiftBuild, "--package-path", packagePath, "--build-system", buildSystemProvider.rawValue)
104+
let (stdout, stderr) = try sh(
105+
swiftTest, "--package-path", packagePath, "--build-system", buildSystemProvider.rawValue
106+
)
107+
#expect(!stderr.contains("error:"))
108+
#expect(stdout.contains("Test Suite 'All tests' passed"))
109+
} when: {
110+
buildSystemProvider == .swiftbuild && (ProcessInfo.hostOperatingSystem == .linux || ProcessInfo.hostOperatingSystem == .windows)
111+
}
110112
}
111113
}
112114
}

0 commit comments

Comments
 (0)