diff --git a/hyperactor_mesh/src/actor_mesh.rs b/hyperactor_mesh/src/actor_mesh.rs index ab83c0f00..22e2253a5 100644 --- a/hyperactor_mesh/src/actor_mesh.rs +++ b/hyperactor_mesh/src/actor_mesh.rs @@ -1345,9 +1345,9 @@ mod tests { use crate::alloc::process::ProcessAllocator; fn process_allocator() -> ProcessAllocator { - ProcessAllocator::new(Command::new( - buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap(), - )) + ProcessAllocator::new(Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + ))) } #[cfg(fbcode_build)] // we use an external binary, produced by buck diff --git a/hyperactor_mesh/src/alloc.rs b/hyperactor_mesh/src/alloc.rs index 42e83cd69..d9126424d 100644 --- a/hyperactor_mesh/src/alloc.rs +++ b/hyperactor_mesh/src/alloc.rs @@ -713,8 +713,9 @@ pub(crate) mod testing { Duration::from_secs(1), ); - let command = - Command::new(buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap()); + let command = Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + )); let mut allocator = ProcessAllocator::new(command); let mut alloc = allocator .allocate(AllocSpec { diff --git a/hyperactor_mesh/src/alloc/process.rs b/hyperactor_mesh/src/alloc/process.rs index 3e9b11068..c2d58f5b4 100644 --- a/hyperactor_mesh/src/alloc/process.rs +++ b/hyperactor_mesh/src/alloc/process.rs @@ -603,12 +603,12 @@ mod tests { #[cfg(fbcode_build)] // we use an external binary, produced by buck crate::alloc_test_suite!(ProcessAllocator::new(Command::new( - buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap() + crate::testresource::get("monarch/hyperactor_mesh/bootstrap") ))); #[tokio::test] async fn test_sigterm_on_group_fail() { - let bootstrap_binary = buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap(); + let bootstrap_binary = crate::testresource::get("monarch/hyperactor_mesh/bootstrap"); let mut allocator = ProcessAllocator::new(Command::new(bootstrap_binary)); let mut alloc = allocator diff --git a/hyperactor_mesh/src/alloc/remoteprocess.rs b/hyperactor_mesh/src/alloc/remoteprocess.rs index 7ea4e5b70..1e2ec12a9 100644 --- a/hyperactor_mesh/src/alloc/remoteprocess.rs +++ b/hyperactor_mesh/src/alloc/remoteprocess.rs @@ -2042,13 +2042,15 @@ mod test_alloc { let task1_allocator = RemoteProcessAllocator::new(); let task1_addr = ChannelAddr::any(ChannelTransport::Unix); let task1_addr_string = task1_addr.to_string(); - let task1_cmd = - Command::new(buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap()); + let task1_cmd = Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + )); let task2_allocator = RemoteProcessAllocator::new(); let task2_addr = ChannelAddr::any(ChannelTransport::Unix); let task2_addr_string = task2_addr.to_string(); - let task2_cmd = - Command::new(buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap()); + let task2_cmd = Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + )); let task1_allocator_copy = task1_allocator.clone(); let task1_allocator_handle = tokio::spawn(async move { tracing::info!("spawning task1"); @@ -2169,13 +2171,15 @@ mod test_alloc { let task1_allocator = RemoteProcessAllocator::new(); let task1_addr = ChannelAddr::any(ChannelTransport::Unix); let task1_addr_string = task1_addr.to_string(); - let task1_cmd = - Command::new(buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap()); + let task1_cmd = Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + )); let task2_allocator = RemoteProcessAllocator::new(); let task2_addr = ChannelAddr::any(ChannelTransport::Unix); let task2_addr_string = task2_addr.to_string(); - let task2_cmd = - Command::new(buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap()); + let task2_cmd = Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + )); let task1_allocator_copy = task1_allocator.clone(); let task1_allocator_handle = tokio::spawn(async move { tracing::info!("spawning task1"); @@ -2297,8 +2301,9 @@ mod test_alloc { let task1_allocator = RemoteProcessAllocator::new(); let task1_addr = ChannelAddr::any(ChannelTransport::Unix); let task1_addr_string = task1_addr.to_string(); - let task1_cmd = - Command::new(buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap()); + let task1_cmd = Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + )); let task2_allocator = RemoteProcessAllocator::new(); let task2_addr = ChannelAddr::any(ChannelTransport::Unix); let task2_addr_string = task2_addr.to_string(); @@ -2421,10 +2426,9 @@ mod test_alloc { let remote_process_allocators = addresses .iter() .map(|addr| { - Command::new( - buck_resources::get("monarch/hyperactor_mesh/remote_process_allocator") - .unwrap(), - ) + Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/remote_process_allocator", + )) .env("RUST_LOG", "info") .arg(format!("--addr={addr}")) .stdout(std::process::Stdio::piped()) @@ -2436,9 +2440,9 @@ mod test_alloc { let done_allocating_addr = ChannelAddr::any(ChannelTransport::Unix); let (done_allocating_addr, mut done_allocating_rx) = channel::serve::<()>(done_allocating_addr).unwrap(); - let mut remote_process_alloc = Command::new( - buck_resources::get("monarch/hyperactor_mesh/remote_process_alloc").unwrap(), - ) + let mut remote_process_alloc = Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/remote_process_alloc", + )) .arg(format!("--done-allocating-addr={}", done_allocating_addr)) .arg(format!("--addresses={}", addresses.join(","))) .arg(format!("--num-proc-meshes={}", num_proc_meshes)) diff --git a/hyperactor_mesh/src/bootstrap.rs b/hyperactor_mesh/src/bootstrap.rs index 404405aa0..d3238794c 100644 --- a/hyperactor_mesh/src/bootstrap.rs +++ b/hyperactor_mesh/src/bootstrap.rs @@ -401,11 +401,14 @@ impl Bootstrap { /// Install "kill me if parent dies" and close the race window. pub fn install_pdeathsig_kill() -> io::Result<()> { - // SAFETY: Calling into libc; does not dereference memory, just - // asks the kernel to deliver SIGKILL on parent death. - let rc = unsafe { libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL as c_int) }; - if rc != 0 { - return Err(io::Error::last_os_error()); + #[cfg(target_os = "linux")] + { + // SAFETY: Calling into libc; does not dereference memory, just + // asks the kernel to deliver SIGKILL on parent death. + let rc = unsafe { libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL as c_int) }; + if rc != 0 { + return Err(io::Error::last_os_error()); + } } // Race-close: if the parent died between our exec and prctl(), // we won't get a signal, so detect that and exit now. @@ -1348,7 +1351,7 @@ impl BootstrapCommand { #[cfg(test)] pub(crate) fn test() -> Self { Self { - program: buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap(), + program: crate::testresource::get("monarch/hyperactor_mesh/bootstrap"), arg0: None, args: vec![], env: HashMap::new(), @@ -2553,7 +2556,7 @@ mod tests { let manager = BootstrapProcManager::new(command); // Spawn a fast-exiting child. - let mut cmd = Command::new("/bin/true"); + let mut cmd = Command::new("true"); cmd.stdout(Stdio::null()).stderr(Stdio::null()); let child = cmd.spawn().expect("spawn true"); @@ -3230,9 +3233,9 @@ mod tests { let (instance, _handle) = proc.instance("client").unwrap(); // Configure a ProcessAllocator with the bootstrap binary. - let mut allocator = ProcessAllocator::new(Command::new( - buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap(), - )); + let mut allocator = ProcessAllocator::new(Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + ))); // Request a new allocation of procs from the ProcessAllocator. let alloc = allocator .allocate(AllocSpec { diff --git a/hyperactor_mesh/src/lib.rs b/hyperactor_mesh/src/lib.rs index 20cb1f5f5..cc21cbb4c 100644 --- a/hyperactor_mesh/src/lib.rs +++ b/hyperactor_mesh/src/lib.rs @@ -32,6 +32,7 @@ mod router; pub mod shared_cell; pub mod shortuuid; pub mod test_utils; +mod testresource; pub mod v1; pub use actor_mesh::RootActorMesh; diff --git a/hyperactor_mesh/src/testresource.rs b/hyperactor_mesh/src/testresource.rs new file mode 100644 index 000000000..edffc23f2 --- /dev/null +++ b/hyperactor_mesh/src/testresource.rs @@ -0,0 +1,49 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#![cfg(test)] + +use std::path::PathBuf; + +/// Fetch the named (BUCK) named resource, heuristically falling back on +/// the cargo-built path when possible. Beware! This is not actually a +/// true cargo dependency, so the binaries have to be built independently. +/// +/// We should convert these tests to integration tests, so that cargo can +/// also manage the binaries. +pub fn get(name: S) -> PathBuf +where + S: AsRef, +{ + let name = name.as_ref().to_owned(); + // TODO: actually check if we're running in Buck context or not. + if let Ok(path) = buck_resources::get(name.clone()) { + return path; + } + + assert!( + name.starts_with("monarch/hyperactor_mesh/"), + "invalid resource {}: must start with \"monarch/hyperactor_mesh/\"", + name + ); + + let path: PathBuf = name + .replace( + "monarch/hyperactor_mesh/", + "../target/debug/hyperactor_mesh_test_", + ) + .into(); + + assert!( + path.exists(), + "no cargo-built resource at {}", + path.display() + ); + + path +} diff --git a/hyperactor_mesh/src/v1/host_mesh.rs b/hyperactor_mesh/src/v1/host_mesh.rs index 30dad3a74..554fada9c 100644 --- a/hyperactor_mesh/src/v1/host_mesh.rs +++ b/hyperactor_mesh/src/v1/host_mesh.rs @@ -831,7 +831,7 @@ mod tests { let config = hyperactor::config::global::lock(); let _guard = config.override_key(crate::bootstrap::MESH_BOOTSTRAP_ENABLE_PDEATHSIG, false); - let program = buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap(); + let program = crate::testresource::get("monarch/hyperactor_mesh/bootstrap"); let hosts = vec![free_localhost_addr(), free_localhost_addr()]; diff --git a/hyperactor_mesh/src/v1/testing.rs b/hyperactor_mesh/src/v1/testing.rs index a00012a39..4b454e4ad 100644 --- a/hyperactor_mesh/src/v1/testing.rs +++ b/hyperactor_mesh/src/v1/testing.rs @@ -65,9 +65,9 @@ pub async fn proc_meshes(cx: &impl context::Actor, extent: Extent) -> Vec Vec> { vec![ // Box::new(LocalAllocator.allocate(spec.clone()).await.unwrap()), Box::new( - ProcessAllocator::new(Command::new( - buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap(), - )) + ProcessAllocator::new(Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + ))) .allocate(spec.clone()) .await .unwrap(), @@ -135,9 +135,9 @@ pub async fn local_proc_mesh(extent: Extent) -> (ProcMesh, Instance<()>, DialMai /// Create a host mesh using multiple processes running on the test machine. pub async fn host_mesh(extent: Extent) -> HostMesh { - let mut allocator = ProcessAllocator::new(Command::new( - buck_resources::get("monarch/hyperactor_mesh/bootstrap").unwrap(), - )); + let mut allocator = ProcessAllocator::new(Command::new(crate::testresource::get( + "monarch/hyperactor_mesh/bootstrap", + ))); let alloc = allocator .allocate(AllocSpec { extent,