From cbbe62ff97ba8b116b9eeed4dfd3ae9edc96925d Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 07:26:36 +0000 Subject: [PATCH] =?UTF-8?q?Tests=20:=20faux=20outils=20=C3=A9crits=20par?= =?UTF-8?q?=20un=20sh=20=C3=A0=20part=20(ETXTBSY)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit plan_par_machine (lot 41) a vu « cpu » au lieu de « cuda » en CI : le faux nvidia-smi, écrit par le process des tests puis lancé aussitôt, peut être encore ouvert en écriture dans le fils qu'un test voisin vient de forker ; son exec échoue alors sur ETXTBSY et l'outil paraît absent. Les scripts des tests de la compilation et le faux Chrome (lot 44, lancé à côté des tests parallèles de tests/lot6.rs) sont désormais écrits par un sh à part, comme les autres faux binaires du dépôt. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv --- rust/loki-rs/src/backends/build/tests.rs | 30 +++++++++++++++++------- rust/loki-rs/tests/common/fakecdp.rs | 13 +++++++--- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/rust/loki-rs/src/backends/build/tests.rs b/rust/loki-rs/src/backends/build/tests.rs index 238f8bc..2be2bf4 100644 --- a/rust/loki-rs/src/backends/build/tests.rs +++ b/rust/loki-rs/src/backends/build/tests.rs @@ -135,10 +135,7 @@ async fn plan_par_machine() { root: root.path().to_path_buf(), }; let script = |name: &str, body: &str| { - let p = tools.path().join(name); - std::fs::write(&p, format!("#!/bin/sh\n{body}\n")).unwrap(); - use std::os::unix::fs::PermissionsExt as _; - std::fs::set_permissions(&p, std::fs::Permissions::from_mode(0o755)).unwrap(); + write_script(&tools.path().join(name), &format!("#!/bin/sh\n{body}\n")); }; let base = [ "-DCMAKE_BUILD_TYPE=Release", @@ -230,9 +227,10 @@ async fn erreurs_des_commandes() { root: tools.path().to_path_buf(), }; let p = tools.path().join("outil"); - std::fs::write(&p, "#!/bin/sh\necho un\necho deux >&2\nprintf trois\n[ -n \"$X\" ] && echo \"X=$X\"\nexit $1\n").unwrap(); - use std::os::unix::fs::PermissionsExt as _; - std::fs::set_permissions(&p, std::fs::Permissions::from_mode(0o755)).unwrap(); + write_script( + &p, + "#!/bin/sh\necho un\necho deux >&2\nprintf trois\n[ -n \"$X\" ] && echo \"X=$X\"\nexit $1\n", + ); let args = |a: &[&str]| a.iter().map(|s| s.to_string()).collect::>(); let mut got = Vec::new(); let log = tools.path().join("x.log"); @@ -265,7 +263,23 @@ async fn erreurs_des_commandes() { r, Err("exec: \"absent\": executable file not found in $PATH".into()) ); - std::fs::write(&p, "#!/bin/sh\nkill -9 $$\n").unwrap(); + write_script(&p, "#!/bin/sh\nkill -9 $$\n"); let r = run_lines_with(&probe, None, &[], "outil", &[], true, None, |_| {}).await; assert_eq!(r, Err("signal: killed".into())); } + +/// Écrit un script exécutable par un `sh` à part : si ce process tenait +/// lui-même le fichier ouvert en écriture, un `fork` lancé au même moment +/// par un test voisin en hériterait, et l'`exec` du script échouerait sur +/// ETXTBSY (l'outil paraîtrait absent). +#[cfg(unix)] +fn write_script(p: &std::path::Path, body: &str) { + let ok = std::process::Command::new("sh") + .args(["-c", r#"printf '%s' "$1" > "$2" && chmod 755 "$2""#, "sh"]) + .arg(body) + .arg(p) + .status() + .unwrap() + .success(); + assert!(ok, "script non écrit : {}", p.display()); +} diff --git a/rust/loki-rs/tests/common/fakecdp.rs b/rust/loki-rs/tests/common/fakecdp.rs index ba68c48..ddd552e 100644 --- a/rust/loki-rs/tests/common/fakecdp.rs +++ b/rust/loki-rs/tests/common/fakecdp.rs @@ -32,9 +32,16 @@ exec sleep 600 "#, args.display() ); - std::fs::write(&p, script).unwrap(); - use std::os::unix::fs::PermissionsExt as _; - std::fs::set_permissions(&p, std::fs::Permissions::from_mode(0o755)).unwrap(); + // Écrit par un `sh` à part : un `fork` d'un test voisin hériterait sinon + // du fichier ouvert en écriture, et son `exec` échouerait sur ETXTBSY. + let ok = std::process::Command::new("sh") + .args(["-c", r#"printf '%s' "$1" > "$2" && chmod 755 "$2""#, "sh"]) + .arg(script) + .arg(&p) + .status() + .unwrap() + .success(); + assert!(ok, "faux Chrome non écrit"); p }