Watch
0
0
Fork
You've already forked hyperhive
0

swarm-builder tests: write fake nix from a child process

This commit is contained in:
atlas 2026-10-25 13:07:46 +01:00
commit 8899dca807

View file

@ -548,36 +548,40 @@ mod tests {
assert!(error_tail.ends_with("error: attribute missing"));
}
/// Write the shell script `body` to `path` as an executable, from a child
/// process rather than from this one: a write fd on it held here could be
/// inherited by a child another test thread forks, and exec'ing a file
/// some process still holds open for writing fails with `ETXTBSY`.
fn write_executable(path: &std::path::Path, body: &str) {
let status = std::process::Command::new("/bin/sh")
.args([
"-c",
r#"printf '%s' "$1" > "$2" && chmod 755 "$2""#,
"sh",
&format!("#!/bin/sh\n{body}\n"),
])
.arg(path)
.status()
.expect("run /bin/sh");
assert!(status.success(), "writing {} failed", path.display());
}
/// A `nix` stand-in: runs `body` as a shell script, ignoring its arguments.
fn fake_nix(tag: &str, body: &str) -> PathBuf {
use std::os::unix::fs::PermissionsExt as _;
let dir = std::env::temp_dir().join(format!(
"swarm-builder-fake-nix-{tag}-{}",
std::process::id()
));
std::fs::create_dir_all(&dir).expect("scratch dir");
let path = dir.join("nix");
std::fs::write(&path, format!("#!/bin/sh\n{body}\n")).expect("write fake nix");
std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o755)).expect("chmod");
write_executable(&path, body);
path
}
/// Builds with `nix`, retrying while the kernel refuses to exec the script
/// just written (`ETXTBSY`, when another test's fork briefly inherits its
/// open write handle).
/// Builds with `nix`.
async fn build_with(nix: PathBuf) -> Reply {
let builder = Builder { nix, ..builder() };
for _ in 0..20 {
let reply = builder.build(&job(), "token").await;
match &reply {
Reply::Failed { error_tail } if error_tail.contains("Text file busy") => {
tokio::time::sleep(Duration::from_millis(50)).await;
}
_ => return reply,
}
}
panic!("the fake nix stayed busy")
builder.build(&job(), "token").await
}
#[tokio::test]
@ -677,13 +681,9 @@ mod tests {
/// A builder whose `nix` is the shell script `body`, in a directory the
/// returned guard removes.
fn scripted(body: &str) -> (Builder, Scratch) {
use std::os::unix::fs::PermissionsExt as _;
let dir = Scratch::new().expect("a temp dir");
let nix = dir.0.join("nix");
std::fs::write(&nix, format!("#!/bin/sh\n{body}\n")).expect("the script is written");
std::fs::set_permissions(&nix, std::fs::Permissions::from_mode(0o755))
.expect("the script is executable");
write_executable(&nix, body);
(Builder { nix, ..builder() }, dir)
}