swarm-builder tests: write fake nix from a child process
This commit is contained in:
parent
31cb6bfa42
commit
8899dca807
1 changed files with 22 additions and 22 deletions
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue