test(core): add seatbelt sem lock tests (#1823)

## Summary
- add a unit test to ensure the macOS seatbelt policy allows POSIX
semaphores
- add a macOS-only test that runs a Python multiprocessing Lock under
Seatbelt

## Testing
- `cargo test -p codex_core seatbelt_base_policy_allows_ipc_posix_sem
--no-fail-fast` (failed: failed to download from
`https://static.crates.io/crates/tokio-stream/0.1.17/download`)
- `cargo test -p codex_core seatbelt_base_policy_allows_ipc_posix_sem
--no-fail-fast --offline` (failed: attempting to make an HTTP request,
but --offline was specified)
- `cargo test --all-features --no-fail-fast --offline` (failed:
attempting to make an HTTP request, but --offline was specified)
- `just fmt` (failed: command not found: just)
- `just fix` (failed: command not found: just)

Ran tests locally to confirm it passes on master and failed before my
previous change

------
https://chatgpt.com/codex/tasks/task_i_6890f221e0a4833381cfb53e11499bcc
This commit is contained in:
David Z Hao
2025-08-14 14:23:06 -07:00
committed by GitHub
parent 7038827bf4
commit 992e81d9b5

View File

@@ -301,6 +301,59 @@ mod tests {
assert_eq!(expected_args, args);
}
#[test]
fn seatbelt_base_policy_allows_ipc_posix_sem() {
assert!(
MACOS_SEATBELT_BASE_POLICY.contains("(allow ipc-posix-sem)"),
"base policy should allow ipc-posix-sem"
);
}
#[cfg(target_os = "macos")]
#[tokio::test]
async fn python_multiprocessing_lock_works_under_seatbelt() {
use super::spawn_command_under_seatbelt;
use crate::spawn::StdioPolicy;
use std::collections::HashMap;
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
include_default_writable_roots: true,
};
let python_code = r#"import multiprocessing
from multiprocessing import Lock, Process
def f(lock):
with lock:
print("Lock acquired in child process")
if __name__ == '__main__':
lock = Lock()
p = Process(target=f, args=(lock,))
p.start()
p.join()
"#;
let mut child = spawn_command_under_seatbelt(
vec![
"python3".to_string(),
"-c".to_string(),
python_code.to_string(),
],
&policy,
std::env::current_dir().expect("should be able to get current dir"),
StdioPolicy::RedirectForShellTool,
HashMap::new(),
)
.await
.expect("should be able to spawn python under seatbelt");
let status = child.wait().await.expect("should wait for child process");
assert!(status.success(), "python exited with {status:?}");
}
struct PopulatedTmp {
root_with_git: PathBuf,
root_without_git: PathBuf,