Validate native Windows exit status and isolated runtime dependencies

This commit is contained in:
Max Lv
2026-09-11 00:37:39 +08:00
parent 46d3acd9d6
commit 28b6147b79
5 changed files with 31 additions and 11 deletions
+2 -1
View File
@@ -57,7 +57,8 @@ jobs:
cmake -S . -B build -G Ninja
cmake --build build --parallel 4
ctest --test-dir build -L 'unit|vendor' --output-on-failure --no-tests=error
python tests/interop.py --self --bin build/bin
objdump -p build/bin/ss-server.exe | sed -n '/DLL Name/p'
python tests/interop.py --self --bin build/bin --isolate-windows-runtime
- name: Installed consumers
run: |
cmake --install build --prefix "$PWD/install"
@@ -1,5 +1,5 @@
{
"commit": "feature/self-contained-portable-c (working tree)",
"commit": "46d3acd9d6b72e088b688c2f84aae5c0466885d8",
"platform": "Darwin arm64",
"binaries": {
"ss-local": {
@@ -1,5 +1,5 @@
{
"commit": "feature/self-contained-portable-c (working tree)",
"commit": "46d3acd9d6b72e088b688c2f84aae5c0466885d8",
"platform": "Darwin arm64",
"binaries": {
"ss-local": {
+12 -3
View File
@@ -137,7 +137,7 @@ def wait_ready(process, port):
@contextlib.contextmanager
def peers(commands, ports):
def peers(commands, ports, environment=None):
processes = []
with tempfile.TemporaryDirectory(prefix="ss-interop-") as temp, contextlib.ExitStack() as stack:
logs = []
@@ -146,7 +146,7 @@ def peers(commands, ports):
path = Path(temp) / f"peer-{index}.log"
log = stack.enter_context(path.open("wb"))
logs.append(path)
process = subprocess.Popen(command, stdout=log, stderr=subprocess.STDOUT)
process = subprocess.Popen(command, stdout=log, stderr=subprocess.STDOUT, env=environment)
processes.append(process)
wait_ready(process, port)
yield
@@ -172,9 +172,18 @@ def main():
parser.add_argument("--method", help="run one cipher")
parser.add_argument("--bin", default=os.environ.get("SS_BIN_DIR", "build/bin"), help="program directory")
parser.add_argument("--plugin", help="SIP003 fixture executable (requires --self)")
parser.add_argument("--isolate-windows-runtime", action="store_true",
help="remove MSYS2/toolchain DLL directories from child PATH")
args = parser.parse_args()
if args.plugin and not args.self:
parser.error("--plugin requires --self")
environment = None
if args.isolate_windows_runtime:
if os.name != "nt":
parser.error("--isolate-windows-runtime requires Windows")
environment = os.environ.copy()
system_root = environment["SystemRoot"]
environment["PATH"] = os.pathsep.join((system_root, os.path.join(system_root, "System32")))
binary_dir = Path(args.bin).resolve()
suffix = ".exe" if os.name == "nt" else ""
local, server = [str(binary_dir / (name + suffix)) for name in ("ss-local", "ss-server")]
@@ -219,7 +228,7 @@ def main():
elif direction.startswith("Rust client"):
commands[1] = [rust_local, "-b", f"127.0.0.1:{local_port}", "-s", f"127.0.0.1:{server_port}", "-k", psk, "-m", method, "-U"]
try:
with peers(commands, [server_port, local_port]):
with peers(commands, [server_port, local_port], environment):
for marker in markers:
deadline = time.monotonic() + 10
while not marker.exists() and time.monotonic() < deadline:
+15 -5
View File
@@ -9,8 +9,6 @@
#include "test_helpers.h"
#ifndef _WIN32
#include <sys/wait.h>
#else
#include <process.h>
#endif
int verbose = 0;
@@ -151,9 +149,21 @@ test_read_jconf_rejects_out_of_range_int_options(void)
fclose(f);
#ifdef _WIN32
const char *args[] = {test_executable, "--read-config", path, NULL};
intptr_t status = _spawnv(_P_WAIT, test_executable, args);
assert(status > 0);
char command[3 * 4096];
assert(snprintf(command, sizeof(command), "\"%s\" --read-config \"%s\"",
test_executable, path) < (int)sizeof(command));
STARTUPINFOA startup = {0};
PROCESS_INFORMATION child = {0};
startup.cb = sizeof(startup);
assert(CreateProcessA(test_executable, command, NULL, NULL, FALSE, 0,
NULL, NULL, &startup, &child));
CloseHandle(child.hThread);
assert(WaitForSingleObject(child.hProcess, 10000) == WAIT_OBJECT_0);
DWORD status;
assert(GetExitCodeProcess(child.hProcess, &status));
CloseHandle(child.hProcess);
/* FATAL exits with -1, which is a valid nonzero DWORD exit status. */
assert(status != 0);
#else
pid_t pid = fork();
assert(pid >= 0);