use std::process::Command;
use std::sync::Mutex;
static PTHREAD_TEST_LOCK: Mutex<()> = Mutex::new(());
#[test]
fn pthread_functions_under_libc_so() {
let _guard = PTHREAD_TEST_LOCK.lock();
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let fixtures = manifest_dir.join("tests/fixtures");
let include = manifest_dir.join("include");
let ldso_path = manifest_dir.join("target/debug/libldso.so");
let libc_path = manifest_dir.join("target/debug/libc.so");
assert!(ldso_path.exists(), "libldso.so not found");
assert!(libc_path.exists(), "libc.so not found");
let src = fixtures.join("pthread_test.c");
let bin = fixtures.join("pthread_test");
let status = Command::new("musl-gcc")
.args([
"-fPIE",
"-pie",
"-I",
include.to_str().unwrap(),
"-Wl,--dynamic-linker",
ldso_path.to_str().unwrap(),
"-L",
manifest_dir.join("target/debug").to_str().unwrap(),
src.to_str().unwrap(),
"-Wl,--allow-shlib-undefined",
"-lc",
"-o",
bin.to_str().unwrap(),
])
.status()
.expect("failed to run musl-gcc for pthread_test");
assert!(status.success(), "musl-gcc pthread_test compilation failed");
let output = Command::new(&bin)
.env("LD_LIBRARY_PATH", manifest_dir.join("target/debug").to_str().unwrap())
.output()
.expect("failed to run pthread_test");
assert!(
output.status.success(),
"pthread_test exited with {:?}, stderr: {}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
assert_eq!(String::from_utf8_lossy(&output.stdout), "pthread ok\n");
}
#[test]
fn pthread_full_test() {
let _guard = PTHREAD_TEST_LOCK.lock();
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let fixtures = manifest_dir.join("tests/fixtures");
let include = manifest_dir.join("include");
let ldso_path = manifest_dir.join("target/debug/libldso.so");
assert!(ldso_path.exists(), "libldso.so not found");
let src = fixtures.join("pthread_full_test.c");
let bin = fixtures.join("pthread_full_test");
let status = Command::new("musl-gcc")
.args([
"-fPIE", "-pie",
"-I", include.to_str().unwrap(),
"-Wl,--dynamic-linker", ldso_path.to_str().unwrap(),
"-L", manifest_dir.join("target/debug").to_str().unwrap(),
src.to_str().unwrap(),
"-Wl,--allow-shlib-undefined",
"-lc",
"-o", bin.to_str().unwrap(),
])
.status()
.expect("failed to run musl-gcc for pthread_full_test");
assert!(status.success(), "musl-gcc pthread_full_test compilation failed");
let output = Command::new(&bin)
.env("LD_LIBRARY_PATH", manifest_dir.join("target/debug").to_str().unwrap())
.output()
.expect("failed to run pthread_full_test");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
output.status.success(),
"pthread_full_test exited with {:?}, stdout: {}, stderr: {}",
output.status.code(), stdout, stderr
);
assert!(stdout.contains("pthread_full ok"), "unexpected output: {}", stdout);
}