@@ -17,6 +17,38 @@ import XCTest
17
17
18
18
@testable import SwiftSDKGenerator
19
19
20
+ extension FileManager {
21
+ func withTemporaryDirectory< T> ( logger: Logger , cleanup: Bool = true , body: ( URL ) async throws -> T ) async throws -> T {
22
+ // Create a temporary directory using a UUID. Throws if the directory already exists.
23
+ // The docs suggest using FileManager.url(for: .itemReplacementDirectory, ...) to create a temporary directory,
24
+ // but on Linux the directory name contains spaces, which means we need to be careful to quote it everywhere:
25
+ //
26
+ // `(A Document Being Saved By \(name))`
27
+ //
28
+ // https://github.com/swiftlang/swift-corelibs-foundation/blob/21b3196b33a64d53a0989881fc9a486227b4a316/Sources/Foundation/FileManager.swift#L152
29
+ var logger = logger
30
+
31
+ let temporaryDirectory = self . temporaryDirectory. appendingPathComponent ( UUID ( ) . uuidString)
32
+ logger [ metadataKey: " temporaryDirectory " ] = " \( temporaryDirectory. path) "
33
+
34
+ try createDirectory ( at: temporaryDirectory, withIntermediateDirectories: false )
35
+ defer {
36
+ // Best effort cleanup.
37
+ do {
38
+ if cleanup {
39
+ try removeItem ( at: temporaryDirectory)
40
+ logger. info ( " Removed temporary directory " )
41
+ } else {
42
+ logger. info ( " Keeping temporary directory " )
43
+ }
44
+ } catch { }
45
+ }
46
+
47
+ logger. info ( " Created temporary directory " )
48
+ return try await body ( temporaryDirectory)
49
+ }
50
+ }
51
+
20
52
final class EndToEndTests : XCTestCase {
21
53
private let testcases = [
22
54
#"""
@@ -37,10 +69,14 @@ final class EndToEndTests: XCTestCase {
37
69
38
70
private let logger = Logger ( label: " swift-sdk-generator " )
39
71
72
+ // Building an SDK requires running the sdk-generator with `swift run swift-sdk-generator`.
73
+ // This takes a lock on `.build`, but if the tests are being run by `swift test` the outer Swift Package Manager
74
+ // instance will already hold this lock, causing the test to deadlock. We can work around this by giving
75
+ // the `swift run swift-sdk-generator` instance its own scratch directory.
40
76
#if !os(macOS)
41
- func buildSDK( inDirectory packageDirectory: FilePath , withArguments runArguments: String ) async throws -> String {
77
+ func buildSDK( inDirectory packageDirectory: FilePath , scratchPath : String , withArguments runArguments: String ) async throws -> String {
42
78
let generatorOutput = try await Shell . readStdout (
43
- " cd \( packageDirectory) && swift run swift-sdk-generator \( runArguments) "
79
+ " cd \( packageDirectory) && swift run --scratch-path \" \( scratchPath ) \" swift-sdk-generator \( runArguments) "
44
80
)
45
81
46
82
let installCommand = try XCTUnwrap ( generatorOutput. split ( separator: " \n " ) . first {
@@ -84,10 +120,9 @@ final class EndToEndTests: XCTestCase {
84
120
}
85
121
86
122
for runArguments in possibleArguments {
87
- let bundleName = try await buildSDK ( inDirectory: packageDirectory, withArguments: runArguments)
88
-
89
- let installOutput = try await Shell . readStdout ( String ( installCommand) )
90
- XCTAssertTrue ( installOutput. contains ( " successfully installed " ) )
123
+ let bundleName = try await FileManager . default. withTemporaryDirectory ( logger: logger) { tempDir in
124
+ try await buildSDK ( inDirectory: packageDirectory, scratchPath: tempDir. path, withArguments: runArguments)
125
+ }
91
126
92
127
for testcase in self . testcases {
93
128
let testPackageURL = FileManager . default. temporaryDirectory. appendingPathComponent ( " swift-sdk-generator-test " )
@@ -130,8 +165,10 @@ final class EndToEndTests: XCTestCase {
130
165
}
131
166
132
167
for runArguments in possibleArguments {
133
- let _ = try await buildSDK ( inDirectory: packageDirectory, withArguments: runArguments)
134
- let _ = try await buildSDK ( inDirectory: packageDirectory, withArguments: runArguments)
168
+ try await FileManager . default. withTemporaryDirectory ( logger: logger) { tempDir in
169
+ let _ = try await buildSDK ( inDirectory: packageDirectory, scratchPath: tempDir. path, withArguments: runArguments)
170
+ let _ = try await buildSDK ( inDirectory: packageDirectory, scratchPath: tempDir. path, withArguments: runArguments)
171
+ }
135
172
}
136
173
}
137
174
#endif
0 commit comments