mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #7972 from Ecordonnier/eco/stdbuf-regression-test
stdbuf: fix cross-compilation
This commit is contained in:
commit
b5d4b0ee1d
11 changed files with 532 additions and 250 deletions
|
@ -2,6 +2,7 @@
|
|||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore dyld dylib setvbuf
|
||||
use uutests::new_ucmd;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use uutests::util::TestScenario;
|
||||
|
@ -30,10 +31,21 @@ fn test_no_such() {
|
|||
.stderr_contains("No such file or directory");
|
||||
}
|
||||
|
||||
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
|
||||
// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
|
||||
// does not provide musl-compiled system utilities (like head), leading to dynamic linker errors
|
||||
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.
|
||||
#[cfg(all(
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "openbsd"),
|
||||
not(all(target_arch = "x86_64", target_env = "musl"))
|
||||
))]
|
||||
#[test]
|
||||
fn test_stdbuf_unbuffered_stdout() {
|
||||
// This is a basic smoke test
|
||||
// Note: This test only verifies that stdbuf does not crash and that output is passed through as expected
|
||||
// for simple, short-lived commands. It does not guarantee that buffering is actually modified or that
|
||||
// libstdbuf is loaded and functioning correctly.
|
||||
new_ucmd!()
|
||||
.args(&["-o0", "head"])
|
||||
.pipe_in("The quick brown fox jumps over the lazy dog.")
|
||||
|
@ -41,9 +53,20 @@ fn test_stdbuf_unbuffered_stdout() {
|
|||
.stdout_is("The quick brown fox jumps over the lazy dog.");
|
||||
}
|
||||
|
||||
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
|
||||
// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
|
||||
// does not provide musl-compiled system utilities (like head), leading to dynamic linker errors
|
||||
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.
|
||||
#[cfg(all(
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "openbsd"),
|
||||
not(all(target_arch = "x86_64", target_env = "musl"))
|
||||
))]
|
||||
#[test]
|
||||
fn test_stdbuf_line_buffered_stdout() {
|
||||
// Note: This test only verifies that stdbuf does not crash and that output is passed through as expected
|
||||
// for simple, short-lived commands. It does not guarantee that buffering is actually modified or that
|
||||
// libstdbuf is loaded and functioning correctly.
|
||||
new_ucmd!()
|
||||
.args(&["-oL", "head"])
|
||||
.pipe_in("The quick brown fox jumps over the lazy dog.")
|
||||
|
@ -62,7 +85,15 @@ fn test_stdbuf_no_buffer_option_fails() {
|
|||
.stderr_contains("the following required arguments were not provided:");
|
||||
}
|
||||
|
||||
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
|
||||
// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
|
||||
// does not provide musl-compiled system utilities (like tail), leading to dynamic linker errors
|
||||
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.
|
||||
#[cfg(all(
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "freebsd"),
|
||||
not(target_os = "openbsd"),
|
||||
not(all(target_arch = "x86_64", target_env = "musl"))
|
||||
))]
|
||||
#[test]
|
||||
fn test_stdbuf_trailing_var_arg() {
|
||||
new_ucmd!()
|
||||
|
@ -105,3 +136,83 @@ fn test_stdbuf_invalid_mode_fails() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// macos uses DYLD_PRINT_LIBRARIES, not LD_DEBUG, so disable on macos at the moment.
|
||||
// On modern Android (Bionic, API 37+), LD_DEBUG is supported and behaves similarly to glibc.
|
||||
// On older Android versions (Bionic, API < 37), LD_DEBUG uses integer values instead of strings
|
||||
// and is sometimes disabled. Disable test on Android for now.
|
||||
// musl libc dynamic loader does not support LD_DEBUG, so disable on musl targets as well.
|
||||
#[cfg(all(
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "openbsd"),
|
||||
not(target_os = "macos"),
|
||||
not(target_os = "android"),
|
||||
not(target_env = "musl")
|
||||
))]
|
||||
#[test]
|
||||
fn test_libstdbuf_preload() {
|
||||
use std::process::Command;
|
||||
|
||||
// Run a simple program with LD_DEBUG=symbols to verify that libstdbuf is loaded correctly
|
||||
// and that there are no architecture mismatches when preloading the library.
|
||||
// Note: This does not check which setvbuf implementation is used, as our libstdbuf does not override setvbuf.
|
||||
// for https://github.com/uutils/coreutils/issues/6591
|
||||
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let coreutils_bin = &scene.bin_path;
|
||||
|
||||
// Test with our own echo (should have the correct architecture even when cross-compiled using cross-rs,
|
||||
// in which case the "system" echo will be the host architecture)
|
||||
let uutils_echo_cmd = format!(
|
||||
"LD_DEBUG=symbols {} stdbuf -oL {} echo test 2>&1",
|
||||
coreutils_bin.display(),
|
||||
coreutils_bin.display()
|
||||
);
|
||||
let uutils_output = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(&uutils_echo_cmd)
|
||||
.output()
|
||||
.expect("Failed to run uutils echo test");
|
||||
|
||||
let uutils_debug = String::from_utf8_lossy(&uutils_output.stdout);
|
||||
|
||||
// Check if libstdbuf.so / libstdbuf.dylib is in the lookup path.
|
||||
// With GLIBC, the log should contain something like:
|
||||
// "symbol=setvbuf; lookup in file=/tmp/.tmp0mfmCg/libstdbuf.so [0]"
|
||||
// With FreeBSD dynamic loader, the log should contain something like:
|
||||
// cspell:disable-next-line
|
||||
// "calling init function for /tmp/.tmpu11rhP/libstdbuf.so at ..."
|
||||
let libstdbuf_in_path = if cfg!(target_os = "freebsd") {
|
||||
uutils_debug
|
||||
.lines()
|
||||
.any(|line| line.contains("calling init function") && line.contains("libstdbuf"))
|
||||
} else {
|
||||
uutils_debug.contains("symbol=setvbuf")
|
||||
&& uutils_debug.contains("lookup in file=")
|
||||
&& uutils_debug.contains("libstdbuf")
|
||||
};
|
||||
|
||||
// Check for lack of architecture mismatch error. The potential error message with GLIBC is:
|
||||
// cspell:disable-next-line
|
||||
// "ERROR: ld.so: object '/tmp/.tmpCLq8jl/libstdbuf.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored."
|
||||
let arch_mismatch_line = uutils_debug
|
||||
.lines()
|
||||
.find(|line| line.contains("cannot be preloaded"));
|
||||
println!("LD_DEBUG output: {}", uutils_debug);
|
||||
let no_arch_mismatch = arch_mismatch_line.is_none();
|
||||
|
||||
println!("libstdbuf in lookup path: {}", libstdbuf_in_path);
|
||||
println!("No architecture mismatch: {}", no_arch_mismatch);
|
||||
if let Some(error_line) = arch_mismatch_line {
|
||||
println!("Architecture mismatch error: {}", error_line);
|
||||
}
|
||||
|
||||
assert!(
|
||||
libstdbuf_in_path,
|
||||
"libstdbuf should be in lookup path with uutils echo"
|
||||
);
|
||||
assert!(
|
||||
no_arch_mismatch,
|
||||
"uutils echo should not show architecture mismatch"
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue