Skip to content

Commit 75add55

Browse files
yannhamclaude
andcommitted
test(ffi): assert cdylib exists and is readable before ELF inspection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e6a7b10 commit 75add55

2 files changed

Lines changed: 27 additions & 16 deletions

File tree

libdd-otel-thread-ctx-ffi/build.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,5 @@ fn main() {
2525
println!(
2626
"cargo:rustc-cdylib-link-arg=-Wl,--version-script={manifest_dir}/tls-dynamic-list.txt"
2727
);
28-
29-
// Expose the profile output directory to integration tests so they can
30-
// locate the cdylib without fragile path-walking.
31-
// OUT_DIR = <target>/[<triple>/]<profile>/build/<pkg>-<hash>/out
32-
// Three levels up lands on <target>/[<triple>/]<profile>.
33-
let profile_dir = std::path::PathBuf::from(&env::var("OUT_DIR").unwrap())
34-
.ancestors()
35-
.nth(3)
36-
.unwrap()
37-
.to_str()
38-
.unwrap()
39-
.to_owned();
40-
println!("cargo:rustc-env=CDYLIB_PROFILE_DIR={profile_dir}");
4128
}
4229
}

libdd-otel-thread-ctx-ffi/tests/elf_properties.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
//! - `otel_thread_ctx_v1` is accessed via TLSDESC relocations (R_X86_64_TLSDESC or
99
//! R_AARCH64_TLSDESC), as required by the OTel thread-level context sharing spec.
1010
//!
11-
//! The cdylib path is injected at compile time via `build.rs` from `OUT_DIR`.
11+
//! The cdylib path is derived at runtime from the test executable location:
12+
//! the test binary lives in `target/<[triple/]profile>/deps/`, so the cdylib
13+
//! is one level up at `target/<[triple/]profile>/liblibdd_otel_thread_ctx_ffi.so`.
1214
1315
#![cfg(target_os = "linux")]
1416

@@ -18,22 +20,43 @@ use std::process::Command;
1820
const SYMBOL: &str = "otel_thread_ctx_v1";
1921

2022
fn cdylib_path() -> PathBuf {
21-
PathBuf::from(env!("CDYLIB_PROFILE_DIR")).join("liblibdd_otel_thread_ctx_ffi.so")
23+
// test binary: target/<[triple/]profile>/deps/<name>
24+
// cdylib: target/<[triple/]profile>/liblibdd_otel_thread_ctx_ffi.so
25+
let exe = std::env::current_exe().expect("failed to read current executable path");
26+
exe.parent() // deps/
27+
.and_then(|p| p.parent()) // <profile>/
28+
.expect("unexpected test executable path structure")
29+
.join("liblibdd_otel_thread_ctx_ffi.so")
30+
}
31+
32+
fn check_cdylib_exists(path: &PathBuf) {
33+
assert!(
34+
path.exists(),
35+
"cdylib not found at {}: \
36+
ensure `cargo build -p libdd-otel-thread-ctx-ffi` has been run for this profile",
37+
path.display()
38+
);
39+
assert!(
40+
std::fs::File::open(path).is_ok(),
41+
"cdylib exists at {} but could not be opened for reading",
42+
path.display()
43+
);
2244
}
2345

2446
fn readelf(args: &[&str], path: &PathBuf) -> String {
2547
let out = Command::new("readelf")
2648
.args(args)
2749
.arg(path)
2850
.output()
29-
.expect("failed to run readelf — is binutils installed?");
51+
.expect("failed to run readelf. Is binutils installed?");
3052
String::from_utf8_lossy(&out.stdout).into_owned()
3153
}
3254

3355
#[test]
3456
#[cfg_attr(miri, ignore)]
3557
fn otel_thread_ctx_v1_in_dynsym() {
3658
let path = cdylib_path();
59+
check_cdylib_exists(&path);
3760
let output = readelf(&["-W", "--dyn-syms"], &path);
3861
let line = output
3962
.lines()
@@ -49,6 +72,7 @@ fn otel_thread_ctx_v1_in_dynsym() {
4972
#[cfg_attr(miri, ignore)]
5073
fn otel_thread_ctx_v1_tlsdesc_reloc() {
5174
let path = cdylib_path();
75+
check_cdylib_exists(&path);
5276
let output = readelf(&["-W", "--relocs"], &path);
5377
let found = output.lines().any(|l| {
5478
l.contains(SYMBOL) && (l.contains("R_X86_64_TLSDESC") || l.contains("R_AARCH64_TLSDESC"))

0 commit comments

Comments
 (0)