Skip to content

Commit 3e955b7

Browse files
authored
Only clear exit test ID env var upon successful lookup (#1226)
This changes the logic in `ExitTest.findInEnvironmentForEntryPoint()` to only clear the environment variable containing the ID of the exit test to run if an exit test is successfully located. ### Motivation: This ensures that if a tool integrates with the testing library and has both its own built-in copy of the library but also may call into the ABI entry point, both usage scenarios can successfully look up the exit test. Without this fix, if an earlier attempt to look up an exit test fails, the environment variable would be cleared which prevents a subsequent lookup attempt from succeeding. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent cfa0c09 commit 3e955b7

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

Sources/Testing/ExitTests/ExitTest.swift

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ extension ExitTest {
233233
#endif
234234
}
235235

236+
/// The name of the environment variable used to identify the exit test to
237+
/// call in a spawned exit test process.
238+
private static let _idEnvironmentVariableName = "SWT_EXIT_TEST_ID"
239+
236240
/// Call the exit test in the current process.
237241
///
238242
/// This function invokes the closure originally passed to
@@ -713,6 +717,17 @@ extension ExitTest {
713717
#endif
714718
}
715719

720+
/// The ID of the exit test to run, if any, specified in the environment.
721+
static var environmentIDForEntryPoint: ID? {
722+
guard var idString = Environment.variable(named: Self._idEnvironmentVariableName) else {
723+
return nil
724+
}
725+
726+
return try? idString.withUTF8 { idBuffer in
727+
try JSON.decode(ExitTest.ID.self, from: UnsafeRawBufferPointer(idBuffer))
728+
}
729+
}
730+
716731
/// Find the exit test function specified in the environment of the current
717732
/// process, if any.
718733
///
@@ -723,21 +738,15 @@ extension ExitTest {
723738
/// `__swiftPMEntryPoint()` function. The effect of using it under other
724739
/// configurations is undefined.
725740
static func findInEnvironmentForEntryPoint() -> Self? {
726-
// Find the ID of the exit test to run, if any, in the environment block.
727-
var id: ExitTest.ID?
728-
if var idString = Environment.variable(named: "SWT_EXIT_TEST_ID") {
729-
// Clear the environment variable. It's an implementation detail and exit
730-
// test code shouldn't be dependent on it. Use ExitTest.current if needed!
731-
Environment.setVariable(nil, named: "SWT_EXIT_TEST_ID")
732-
733-
id = try? idString.withUTF8 { idBuffer in
734-
try JSON.decode(ExitTest.ID.self, from: UnsafeRawBufferPointer(idBuffer))
735-
}
736-
}
737-
guard let id, var result = find(identifiedBy: id) else {
741+
guard let id = environmentIDForEntryPoint, var result = find(identifiedBy: id) else {
738742
return nil
739743
}
740744

745+
// Since an exit test was found, clear the environment variable. It's an
746+
// implementation detail and exit test code shouldn't be dependent on it.
747+
// Use ExitTest.current if needed!
748+
Environment.setVariable(nil, named: Self._idEnvironmentVariableName)
749+
741750
// If an exit test was found, inject back channel handling into its body.
742751
// External tools authors should set up their own back channel mechanisms
743752
// and ensure they're installed before calling ExitTest.callAsFunction().
@@ -867,7 +876,7 @@ extension ExitTest {
867876
// Insert a specific variable that tells the child process which exit test
868877
// to run.
869878
try JSON.withEncoding(of: exitTest.id) { json in
870-
childEnvironment["SWT_EXIT_TEST_ID"] = String(decoding: json, as: UTF8.self)
879+
childEnvironment[Self._idEnvironmentVariableName] = String(decoding: json, as: UTF8.self)
871880
}
872881

873882
typealias ResultUpdater = @Sendable (inout ExitTest.Result) -> Void

0 commit comments

Comments
 (0)