diff --git a/Sources/Testing/ExitTests/ExitTest.swift b/Sources/Testing/ExitTests/ExitTest.swift index 69346b74e..bd5cb95b9 100644 --- a/Sources/Testing/ExitTests/ExitTest.swift +++ b/Sources/Testing/ExitTests/ExitTest.swift @@ -457,6 +457,10 @@ extension ExitTest { return nil } + // Erase the environment variable so that it cannot accidentally be opened + // twice (nor, in theory, affect the code of the exit test.) + Environment.setVariable(nil, named: "SWT_EXPERIMENTAL_BACKCHANNEL") + var fd: CInt? #if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) fd = CInt(backChannelEnvironmentVariable) @@ -487,6 +491,10 @@ extension ExitTest { // Find the ID of the exit test to run, if any, in the environment block. var id: ExitTest.ID? if var idString = Environment.variable(named: "SWT_EXPERIMENTAL_EXIT_TEST_ID") { + // Clear the environment variable. It's an implementation detail and exit + // test code shouldn't be dependent on it. Use ExitTest.current if needed! + Environment.setVariable(nil, named: "SWT_EXPERIMENTAL_EXIT_TEST_ID") + id = try? idString.withUTF8 { idBuffer in try JSON.decode(ExitTest.ID.self, from: UnsafeRawBufferPointer(idBuffer)) } diff --git a/Sources/Testing/Support/Environment.swift b/Sources/Testing/Support/Environment.swift index f09efc1ed..2ab3710a4 100644 --- a/Sources/Testing/Support/Environment.swift +++ b/Sources/Testing/Support/Environment.swift @@ -235,3 +235,42 @@ enum Environment { } } } + +// MARK: - Setting variables + +extension Environment { + /// Set the environment variable with the specified name. + /// + /// - Parameters: + /// - value: The new value for the specified environment variable. Pass + /// `nil` to remove the variable from the current process' environment. + /// - name: The name of the environment variable. + /// + /// - Returns: Whether or not the environment variable was successfully set. + @discardableResult + static func setVariable(_ value: String?, named name: String) -> Bool { +#if SWT_NO_ENVIRONMENT_VARIABLES + simulatedEnvironment.withLock { environment in + environment[name] = value + } + return true +#elseif SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) || os(WASI) + if let value { + return 0 == setenv(name, value, 1) + } + return 0 == unsetenv(name) +#elseif os(Windows) + name.withCString(encodedAs: UTF16.self) { name in + if let value { + return value.withCString(encodedAs: UTF16.self) { value in + SetEnvironmentVariableW(name, value) + } + } + return SetEnvironmentVariableW(name, nil) + } +#else +#warning("Platform-specific implementation missing: environment variables unavailable") + return false +#endif + } +} diff --git a/Tests/TestingTests/Support/EnvironmentTests.swift b/Tests/TestingTests/Support/EnvironmentTests.swift index 512ebfe7b..43d8ea3f3 100644 --- a/Tests/TestingTests/Support/EnvironmentTests.swift +++ b/Tests/TestingTests/Support/EnvironmentTests.swift @@ -71,42 +71,3 @@ struct EnvironmentTests { #expect(Environment.flag(named: name) == false) } } - -// MARK: - Fixtures - -extension Environment { - /// Set the environment variable with the specified name. - /// - /// - Parameters: - /// - value: The new value for the specified environment variable. Pass - /// `nil` to remove the variable from the current process' environment. - /// - name: The name of the environment variable. - /// - /// - Returns: Whether or not the environment variable was successfully set. - @discardableResult - static func setVariable(_ value: String?, named name: String) -> Bool { -#if SWT_NO_ENVIRONMENT_VARIABLES - simulatedEnvironment.withLock { environment in - environment[name] = value - } - return true -#elseif SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) || os(WASI) - if let value { - return 0 == setenv(name, value, 1) - } - return 0 == unsetenv(name) -#elseif os(Windows) - name.withCString(encodedAs: UTF16.self) { name in - if let value { - return value.withCString(encodedAs: UTF16.self) { value in - SetEnvironmentVariableW(name, value) - } - } - return SetEnvironmentVariableW(name, nil) - } -#else -#warning("Platform-specific implementation missing: environment variables unavailable") - return false -#endif - } -}