Skip to content

Commit 22ae62b

Browse files
committed
stdbuf: add test_setvbuf_resolution
This test verifies that stdbuf does work when cross-compiled. At the moment the test passes when compiled normally, but fails when compiled with cross-rs, due to #6591 This passes: ``` cargo test --features stdbuf test_stdbuf::test_setvbuf_resolution -- --nocapture ``` This fails: ``` cross test --target aarch64-unknown-linux-gnu --features stdbuf test_stdbuf::test_setvbuf_resolution -- --nocapture ``` Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com>
1 parent 3a05fa9 commit 22ae62b

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

.github/workflows/CICD.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,3 +1208,19 @@ jobs:
12081208
lima bash -c "cd work && cargo test --features 'feat_selinux'"
12091209
- name: Lint with SELinux
12101210
run: lima bash -c "cd work && cargo clippy --all-targets --features 'feat_selinux' -- -D warnings"
1211+
1212+
test-aarch64-stdbuf:
1213+
name: Test stdbuf (aarch64-unknown-linux-gnu, cross)
1214+
runs-on: ubuntu-latest
1215+
steps:
1216+
- uses: actions/checkout@v4
1217+
- name: Install Rust toolchain
1218+
uses: dtolnay/rust-toolchain@stable
1219+
with:
1220+
targets: aarch64-unknown-linux-gnu
1221+
- name: Install cross
1222+
run: cargo install cross
1223+
- name: Run only stdbuf tests for aarch64 (cross)
1224+
run: cross test --target aarch64-unknown-linux-gnu --features stdbuf test_stdbuf::test_setvbuf_resolution
1225+
# https://github.com/uutils/coreutils/issues/6591
1226+
continue-on-error: true

tests/by-util/test_stdbuf.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
5+
// spell-checker:ignore setvbuf
6+
use std::process::Command;
57
use uutests::new_ucmd;
68
#[cfg(not(target_os = "windows"))]
79
use uutests::util::TestScenario;
@@ -34,6 +36,9 @@ fn test_no_such() {
3436
#[test]
3537
fn test_stdbuf_unbuffered_stdout() {
3638
// This is a basic smoke test
39+
// Note: This test only verifies that stdbuf does not crash and that output is passed through as expected
40+
// for simple, short-lived commands. It does not guarantee that buffering is actually modified or that
41+
// libstdbuf is loaded and functioning correctly.
3742
new_ucmd!()
3843
.args(&["-o0", "head"])
3944
.pipe_in("The quick brown fox jumps over the lazy dog.")
@@ -44,6 +49,9 @@ fn test_stdbuf_unbuffered_stdout() {
4449
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
4550
#[test]
4651
fn test_stdbuf_line_buffered_stdout() {
52+
// Note: This test only verifies that stdbuf does not crash and that output is passed through as expected
53+
// for simple, short-lived commands. It does not guarantee that buffering is actually modified or that
54+
// libstdbuf is loaded and functioning correctly.
4755
new_ucmd!()
4856
.args(&["-oL", "head"])
4957
.pipe_in("The quick brown fox jumps over the lazy dog.")
@@ -105,3 +113,52 @@ fn test_stdbuf_invalid_mode_fails() {
105113
}
106114
}
107115
}
116+
117+
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
118+
#[test]
119+
fn test_setvbuf_resolution() {
120+
// Run a simple program with LD_DEBUG=symbols to see which setvbuf is being used
121+
// Written in a way that it can run with cross-rs and be used as regression test
122+
// for https://github.com/uutils/coreutils/issues/6591
123+
124+
let scene = TestScenario::new(util_name!());
125+
let coreutils_bin = &scene.bin_path;
126+
127+
// Test with our own echo (should have the correct architecture even when cross-compiled using cross-rs,
128+
// in which case the "system" echo will be the host architecture)
129+
let uutils_echo_cmd = format!(
130+
"LD_DEBUG=symbols {} stdbuf -oL {} echo test 2>&1",
131+
coreutils_bin.display(),
132+
coreutils_bin.display()
133+
);
134+
let uutils_output = Command::new("sh")
135+
.arg("-c")
136+
.arg(&uutils_echo_cmd)
137+
.output()
138+
.expect("Failed to run uutils echo test");
139+
140+
let uutils_debug = String::from_utf8_lossy(&uutils_output.stdout);
141+
142+
// Check if libstdbuf.so / libstdbuf.dylib is in the lookup path. The log should contain something like this:
143+
// "symbol=setvbuf; lookup in file=/tmp/.tmp0mfmCg/libstdbuf.so [0]"
144+
let libstdbuf_in_path = uutils_debug.contains("symbol=setvbuf")
145+
&& uutils_debug.contains("lookup in file=")
146+
&& uutils_debug.contains("libstdbuf");
147+
148+
// Check for lack of architecture mismatch error. The potential error message is:
149+
// "ERROR: ld.so: object '/tmp/.tmpCLq8jl/libstdbuf.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored."
150+
let no_arch_mismatch = !uutils_debug.contains("cannot be preloaded");
151+
152+
println!("libstdbuf in lookup path: {}", libstdbuf_in_path);
153+
println!("No architecture mismatch: {}", no_arch_mismatch);
154+
println!("LD_DEBUG output: {}", uutils_debug);
155+
156+
assert!(
157+
libstdbuf_in_path,
158+
"libstdbuf should be in lookup path with uutils echo"
159+
);
160+
assert!(
161+
no_arch_mismatch,
162+
"uutils echo should not show architecture mismatch"
163+
);
164+
}

0 commit comments

Comments
 (0)