Track main at 3f238ff (per-role reasoning_effort, #12), 21 commits past d6627d7 ("1.0.0 (#6)"). cargoHash is unchanged: Cargo.lock is identical across that range, so the vendored tree is byte-for-byte the same. The new tests/test_session_boot.rs spawns the real binary with env_clear(), which drops SSL_CERT_FILE. rustls-native-certs is then left with a fixed list of /etc paths to probe, none of which exist in the Nix sandbox, so the child dies in reqwest::Client::new() and four exit-code assertions observe the panic's 101. The patch forwards the runner's SSL_CERT_FILE to the child and leaves every assertion intact. The underlying defect is upstream's rather than Nix's: src/llm/client.rs builds its client with unwrap_or_default() on a Result<Client, reqwest::Error>, and reqwest's Client::default() is Client::new(), which repeats the same build and .expect()s it. The fallback can therefore never recover; it turns a reportable "no CA certificates" error into a panic. Reproduced on a stock busybox image with no /etc/ssl at all, so it hits any minimal container, not just sandboxed builds. Tested: 1251 tests pass across 31 targets, 0 failures.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
Give the env-cleared child process a trust store.
|
||||
|
||||
run_marmel() wipes the child environment so the binary under test cannot
|
||||
inherit the runner's MARMEL_* variables or its terminal. reqwest's TLS stack
|
||||
is rustls-native-certs, which reads SSL_CERT_FILE / SSL_CERT_DIR and then the
|
||||
well-known /etc paths, so where no system trust store exists at all the child
|
||||
dies inside reqwest::Client::new() ("No CA certificates were loaded from the
|
||||
system") before it ever reads the bundle. Four cases in this file assert the
|
||||
CLI's exit codes and stderr, and they then observe the panic's 101 instead.
|
||||
|
||||
Forward the test runner's SSL_CERT_FILE when it has one. On a normal Linux
|
||||
host the child picks the trust store up from /etc as before, so the assertions
|
||||
themselves are unchanged.
|
||||
|
||||
This is a workaround, not the real fix. The panic should not happen at all:
|
||||
src/llm/client.rs builds the client with unwrap_or_default() on a
|
||||
Result<Client, reqwest::Error>, and reqwest's Client::default() is
|
||||
Client::new(), which repeats the same build and .expect()s it, so the fallback
|
||||
can never recover. Upstream was told; drop this patch once the error is
|
||||
propagated instead of discarded.
|
||||
|
||||
--- a/tests/test_session_boot.rs
|
||||
+++ b/tests/test_session_boot.rs
|
||||
@@ -221,8 +221,17 @@
|
||||
let err_file = std::fs::File::create(&err_path).expect("stderr file");
|
||||
|
||||
let mut cmd = Command::new(env!("CARGO_BIN_EXE_marmel"));
|
||||
- cmd.current_dir(dir)
|
||||
- .env_clear()
|
||||
+ cmd.current_dir(dir).env_clear();
|
||||
+ // rustls-native-certs reads SSL_CERT_FILE / SSL_CERT_DIR, both of which the
|
||||
+ // env_clear() above drops, so when no system trust store can be probed
|
||||
+ // either the child dies inside reqwest::Client::new() ("No CA certificates
|
||||
+ // were loaded from the system") before it ever reaches the bundle, and the
|
||||
+ // exit-code assertions below then see the panic's 101. Forward the runner's
|
||||
+ // value when it has one; the assertions themselves are untouched.
|
||||
+ if let Some(trust_store) = std::env::var("SSL_CERT_FILE").ok().filter(|p| !p.is_empty()) {
|
||||
+ cmd.env("SSL_CERT_FILE", trust_store);
|
||||
+ }
|
||||
+ cmd
|
||||
// A minimal, deterministic environment: the binary must not inherit the
|
||||
// test runner's `MARMEL_*` variables or its terminal.
|
||||
.env("PATH", "/usr/bin:/bin")
|
||||
Reference in New Issue
Block a user