Skip to content

Commit 80074f0

Browse files
committed
Unskip tests blocked by requireThreadSafeWorkingDirectory
Now that llbuild has fork/exec support, the tests can be enabled on Amazon Linux 2, OpenBSD, etc.
1 parent 502cfa3 commit 80074f0

File tree

67 files changed

+237
-168
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+237
-168
lines changed

Sources/SWBApplePlatform/AssetCatalogCompiler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public final class ActoolCompilerSpec : GenericCompilerSpec, SpecIdentifierType,
5555
}
5656

5757
private func assetTagCombinations(catalogInputs inputs: [FileToBuild], _ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async throws -> Set<Set<String>> {
58-
return try await executeExternalTool(cbc, delegate, commandLine: [resolveExecutablePath(cbc, cbc.scope.actoolExecutablePath()).str, "--print-asset-tag-combinations", "--output-format", "xml1"] + inputs.map { $0.absolutePath.str }, workingDirectory: cbc.producer.defaultWorkingDirectory.str, environment: environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute asset tag combinations") { output in
58+
return try await executeExternalTool(cbc, delegate, commandLine: [resolveExecutablePath(cbc, cbc.scope.actoolExecutablePath()).str, "--print-asset-tag-combinations", "--output-format", "xml1"] + inputs.map { $0.absolutePath.str }, workingDirectory: cbc.producer.defaultWorkingDirectory, environment: environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute asset tag combinations") { output in
5959
struct AssetCatalogToolOutput: Decodable {
6060
struct Diagnostic: Decodable {
6161
let description: String

Sources/SWBApplePlatform/CoreDataCompiler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public final class CoreDataModelCompilerSpec : GenericCompilerSpec, SpecIdentifi
6767
// Mark the entire directory structure as being watched by the build system.
6868
delegate.access(path: input.absolutePath)
6969

70-
generatedFiles = try await generatedFilePaths(cbc, delegate, commandLine: [commandLine[0]] + ["--dry-run"] + commandLine[1...], workingDirectory: cbc.producer.defaultWorkingDirectory.str, environment: self.environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute data model \(input.absolutePath.basename) code generation output paths") { output in
70+
generatedFiles = try await generatedFilePaths(cbc, delegate, commandLine: [commandLine[0]] + ["--dry-run"] + commandLine[1...], workingDirectory: cbc.producer.defaultWorkingDirectory, environment: self.environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute data model \(input.absolutePath.basename) code generation output paths") { output in
7171
return output.unsafeStringValue.split(separator: "\n").map(Path.init).map { $0.prependingPrivatePrefixIfNeeded(otherPath: outputDir) }
7272
}
7373
guard !generatedFiles.isEmpty else {

Sources/SWBApplePlatform/CoreMLCompiler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public final class CoreMLCompilerSpec : GenericCompilerSpec, SpecIdentifierType,
241241
// Mark the file as being watched by the build system to invalidate the build description.
242242
delegate.access(path: input.absolutePath)
243243

244-
generatedFiles = try await generatedFilePaths(cbc, delegate, commandLine: commandLine[0...3] + ["--dry-run", "yes"] + commandLine[4...], workingDirectory: cbc.producer.defaultWorkingDirectory.str, environment: self.environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute CoreML model \(input.absolutePath.basename) code generation output paths") { output in
244+
generatedFiles = try await generatedFilePaths(cbc, delegate, commandLine: commandLine[0...3] + ["--dry-run", "yes"] + commandLine[4...], workingDirectory: cbc.producer.defaultWorkingDirectory, environment: self.environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute CoreML model \(input.absolutePath.basename) code generation output paths") { output in
245245
return output.unsafeStringValue.split(separator: "\n").map(Path.init)
246246
}
247247
guard !generatedFiles.isEmpty else {

Sources/SWBApplePlatform/IntentsCompiler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public final class IntentsCompilerSpec : GenericCompilerSpec, SpecIdentifierType
194194
// Mark the file as being watched by the build system to invalidate the build description.
195195
delegate.access(path: input.absolutePath)
196196

197-
generatedFiles = try await generatedFilePaths(cbc, delegate, commandLine: commandLine[0...1] + ["-dryRun"] + commandLine[2...], workingDirectory: cbc.producer.defaultWorkingDirectory.str, environment: self.environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute Intent Definition \(input.absolutePath.basename) code generation output paths") { output in
197+
generatedFiles = try await generatedFilePaths(cbc, delegate, commandLine: commandLine[0...1] + ["-dryRun"] + commandLine[2...], workingDirectory: cbc.producer.defaultWorkingDirectory, environment: self.environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute Intent Definition \(input.absolutePath.basename) code generation output paths") { output in
198198
return output.unsafeStringValue.split(separator: "\n").map(Path.init).map { $0.prependingPrivatePrefixIfNeeded(otherPath: outputDir) }
199199
}
200200
guard !generatedFiles.isEmpty else {

Sources/SWBApplePlatform/XCStringsCompiler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public final class XCStringsCompilerSpec: GenericCompilerSpec, SpecIdentifierTyp
6262
// xcstringstool compile --dry-run
6363
dryRunCommandLine.insert("--dry-run", at: 2)
6464

65-
outputs = try await generatedFilePaths(cbc, delegate, commandLine: dryRunCommandLine, workingDirectory: cbc.producer.defaultWorkingDirectory.str, environment: environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute XCStrings \(cbc.input.absolutePath.basename) output paths") { output in
65+
outputs = try await generatedFilePaths(cbc, delegate, commandLine: dryRunCommandLine, workingDirectory: cbc.producer.defaultWorkingDirectory, environment: environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute XCStrings \(cbc.input.absolutePath.basename) output paths") { output in
6666
return output.unsafeStringValue.split(separator: "\n").map(Path.init)
6767
}
6868
} catch {

Sources/SWBBuildService/BuildDependencyInfo.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ extension BuildDependencyInfo {
469469

470470
/// Special `CoreClientDelegate`-conforming struct because our use of `GlobalProductPlan` here should never be running external tools.
471471
fileprivate struct UnsupportedCoreClientDelegate: CoreClientDelegate {
472-
func executeExternalTool(commandLine: [String], workingDirectory: String?, environment: [String : String]) async throws -> ExternalToolResult {
472+
func executeExternalTool(commandLine: [String], workingDirectory: Path?, environment: [String : String]) async throws -> ExternalToolResult {
473473
throw StubError.error("Running external tools is not supported when computing build dependency target info.")
474474
}
475475
}

Sources/SWBBuildService/ClientExchangeDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class ClientExchangeDelegate: ClientDelegate {
3333
self.session = session
3434
}
3535

36-
func executeExternalTool(commandLine: [String], workingDirectory: String?, environment: [String : String]) async throws -> ExternalToolResult {
36+
func executeExternalTool(commandLine: [String], workingDirectory: Path?, environment: [String : String]) async throws -> ExternalToolResult {
3737
// Create a synchronous client exchange which the session uses to handle the response from the client, to make the communication synchronous from the point of view of our caller.
3838
let exchange = SynchronousClientExchange<ExternalToolExecutionResponse>(session)
3939

Sources/SWBBuildSystem/BuildOperation.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,14 +1122,14 @@ private struct OperatorSystemAdaptorDynamicContext: DynamicTaskExecutionDelegate
11221122
}
11231123

11241124
@discardableResult
1125-
func spawn(commandLine: [String], environment: [String: String], workingDirectory: String, processDelegate: any ProcessDelegate) async throws -> Bool {
1125+
func spawn(commandLine: [String], environment: [String: String], workingDirectory: Path, processDelegate: any ProcessDelegate) async throws -> Bool {
11261126
guard let jobContext else {
11271127
throw StubError.error("API misuse. Spawning processes is only allowed from `performTaskAction`.")
11281128
}
11291129

11301130
// This calls into llb_buildsystem_command_interface_spawn, which can block, so ensure it's shunted to a new thread so as not to block the Swift Concurrency thread pool. This shouldn't risk thread explosion because this function is only allowed to be called from performTaskAction, which in turn should be bounded to ncores based on the number of active llbuild lane threads.
11311131
return await _Concurrency.Task.detachNewThread(name: "llb_buildsystem_command_interface_spawn") { [commandInterface, jobContext, processDelegate] in
1132-
commandInterface.spawn(jobContext, commandLine: commandLine, environment: environment, workingDirectory: workingDirectory, processDelegate: processDelegate)
1132+
commandInterface.spawn(jobContext, commandLine: commandLine, environment: environment, workingDirectory: workingDirectory.str, processDelegate: processDelegate)
11331133
}
11341134
}
11351135

Sources/SWBCore/ProcessExecutionCache.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,20 @@ public import SWBUtil
1414

1515
public final class ProcessExecutionCache: Sendable {
1616
private let cache = AsyncCache<[String], Processes.ExecutionResult>()
17+
private let workingDirectory: Path?
1718

18-
public init() { }
19+
public init(workingDirectory: Path? = .root) {
20+
// FIXME: Work around lack of thread-safe working directory support in Foundation (Amazon Linux 2, OpenBSD). Executing processes in the current working directory is less deterministic, but all of the clients which use this class are generally not expected to be sensitive to the working directory anyways. This workaround can be removed once we drop support for Amazon Linux 2 and/or adopt swift-subprocess and/or Foundation.Process's working directory support is made thread safe.
21+
if try! Process.hasUnsafeWorkingDirectorySupport {
22+
self.workingDirectory = nil
23+
return
24+
}
25+
self.workingDirectory = workingDirectory
26+
}
1927

2028
public func run(_ delegate: any CoreClientTargetDiagnosticProducingDelegate, _ commandLine: [String], executionDescription: String?) async throws -> Processes.ExecutionResult {
2129
try await cache.value(forKey: commandLine) {
22-
try await delegate.executeExternalTool(commandLine: commandLine, workingDirectory: "/", environment: [:], executionDescription: executionDescription)
30+
try await delegate.executeExternalTool(commandLine: commandLine, workingDirectory: workingDirectory, environment: [:], executionDescription: executionDescription)
2331
}
2432
}
2533
}

Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,15 +1393,15 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
13931393
return Base.instance.shouldStart(task, buildCommand: buildCommand)
13941394
}
13951395

1396-
public func executeExternalTool<T>(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, commandLine: [String], workingDirectory: String?, environment: [String: String], executionDescription: String?, _ parse: @escaping (ByteString) throws -> T) async throws -> T {
1396+
public func executeExternalTool<T>(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, commandLine: [String], workingDirectory: Path?, environment: [String: String], executionDescription: String?, _ parse: @escaping (ByteString) throws -> T) async throws -> T {
13971397
let executionResult = try await delegate.executeExternalTool(commandLine: commandLine, workingDirectory: workingDirectory, environment: environment, executionDescription: executionDescription)
13981398
guard executionResult.exitStatus.isSuccess else {
13991399
throw RunProcessNonZeroExitError(args: commandLine, workingDirectory: workingDirectory, environment: .init(environment), status: executionResult.exitStatus, stdout: ByteString(executionResult.stdout), stderr: ByteString(executionResult.stderr))
14001400
}
14011401
return try parse(ByteString(executionResult.stdout))
14021402
}
14031403

1404-
public func generatedFilePaths(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, commandLine: [String], workingDirectory: String?, environment: [String: String], executionDescription: String?, _ parse: @escaping (ByteString) throws -> [Path]) async throws -> [Path] {
1404+
public func generatedFilePaths(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, commandLine: [String], workingDirectory: Path?, environment: [String: String], executionDescription: String?, _ parse: @escaping (ByteString) throws -> [Path]) async throws -> [Path] {
14051405
return try await executeExternalTool(cbc, delegate, commandLine: commandLine, workingDirectory: workingDirectory, environment: environment, executionDescription: executionDescription, parse)
14061406
}
14071407
}

0 commit comments

Comments
 (0)