commit 565b1c6b147dbff6712df07e4688665b1bc1bf2d
parent 9608edf9735169a70a68fbad0a6f48b46a2579b1
Author: triesap <tyson@radroots.org>
Date: Thu, 2 Apr 2026 00:56:32 +0000
tests: prove real external-command timeout path
- add a unix-only helper-backed timeout proof for MycProcessCommandExecutor
- assert the production helper path returns TimedOut within a bounded window
- keep the coverage isolated to custody tests without widening runtime behavior
- revalidate myc with nix check and nix test on an isolated target dir during workspace contention
Diffstat:
1 file changed, 33 insertions(+), 0 deletions(-)
diff --git a/src/custody.rs b/src/custody.rs
@@ -1370,8 +1370,12 @@ impl MycIdentityStatusOutput {
#[cfg(test)]
mod tests {
+ use std::fs;
+ #[cfg(unix)]
+ use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
+ use std::time::Instant;
use radroots_identity::RadrootsIdentity;
use radroots_nostr_accounts::prelude::{
@@ -1398,6 +1402,15 @@ mod tests {
}
}
+ #[cfg(unix)]
+ fn write_timeout_helper(path: &Path) {
+ let script = "#!/bin/sh\nwhile :; do\n :\ndone\n";
+ fs::write(path, script).expect("write helper");
+ let mut permissions = fs::metadata(path).expect("helper metadata").permissions();
+ permissions.set_mode(0o755);
+ fs::set_permissions(path, permissions).expect("helper permissions");
+ }
+
#[derive(Debug)]
struct FakeExternalCommandExecutor {
identity: RadrootsIdentity,
@@ -1917,4 +1930,24 @@ mod tests {
} if role == "signer" && path == &PathBuf::from("/tmp/signer-helper")
));
}
+
+ #[cfg(unix)]
+ #[test]
+ fn process_executor_times_out_and_kills_real_helper() {
+ let temp = tempfile::tempdir().expect("tempdir");
+ let helper_path = temp.path().join("timeout-helper.sh");
+ write_timeout_helper(&helper_path);
+
+ let executor = MycProcessCommandExecutor;
+ let started_at = Instant::now();
+ let err = executor
+ .execute(&helper_path, b"{\"operation\":\"describe\"}", Duration::from_millis(100))
+ .expect_err("timeout");
+
+ assert!(matches!(err, MycExternalCommandExecuteError::TimedOut));
+ assert!(
+ started_at.elapsed() < Duration::from_secs(2),
+ "timeout path should stay bounded"
+ );
+ }
}