Skip to content

Commit 2167722

Browse files
committed
FFI lib load integration test
1 parent e3c4c3b commit 2167722

File tree

5 files changed

+74
-5
lines changed

5 files changed

+74
-5
lines changed

Cargo.lock

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

livekit-ffi/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ prost-build = "0.14.1"
4545
webrtc-sys-build = { workspace = true }
4646

4747
[dev-dependencies]
48+
libloading = "0.8.9"
4849
livekit-api = { workspace = true }
4950

5051
[lib]

livekit-ffi/build.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::{env, path::Path};
15+
use std::{
16+
env,
17+
path::{Path, PathBuf},
18+
};
1619

1720
const PROTO_SRC_DIR: &str = "protocol";
1821

@@ -23,6 +26,7 @@ fn main() {
2326
download_webrtc();
2427
copy_webrtc_license();
2528
configure_linker();
29+
get_lib_path();
2630
generate_protobuf();
2731
}
2832

@@ -61,6 +65,30 @@ fn configure_linker() {
6165
}
6266
}
6367

68+
/// Get the path of the built library in the target directory, used for integration testing.
69+
fn get_lib_path() {
70+
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
71+
let target_dir = out_dir.ancestors().nth(4).expect("Failed to find target directory");
72+
73+
let build_profile = env::var("PROFILE").unwrap();
74+
let output_dir = target_dir.join(build_profile);
75+
76+
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
77+
let lib_extension = match target_os.as_str() {
78+
"windows" => "dll",
79+
"linux" | "android" => "so",
80+
"macos" => "dylib",
81+
"ios" => "a",
82+
_ => {
83+
panic!("Unsupported target, {}", target_os);
84+
}
85+
};
86+
let crate_name = env::var("CARGO_PKG_NAME").unwrap();
87+
let lib_name = format!("lib{}.{}", crate_name.replace("-", "_"), lib_extension);
88+
let lib_path = output_dir.join(lib_name);
89+
println!("cargo::rustc-env=FFI_LIB_PATH={}", lib_path.display());
90+
}
91+
6492
fn generate_protobuf() {
6593
let paths: Vec<_> = std::fs::read_dir(PROTO_SRC_DIR)
6694
.expect("Failed to read protobuf source directory")

livekit-ffi/src/server/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,4 @@ impl FfiServer {
272272
});
273273
handle
274274
}
275-
}
275+
}

livekit-ffi/tests/lib_load_test.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use libloading::{Library, Symbol};
2+
use std::{path::Path, process::Command};
3+
4+
const FFI_LIB_PATH: &str = env!("FFI_LIB_PATH"); // Set by build.rs
5+
6+
const EXPECTED_SYMBOLS: &[&str] = &[
7+
"livekit_ffi_initialize",
8+
"livekit_ffi_request",
9+
"livekit_ffi_drop_handle",
10+
"livekit_ffi_dispose",
11+
];
12+
13+
#[test]
14+
fn lib_load_test() {
15+
println!("Library path: {}", FFI_LIB_PATH);
16+
build_lib_if_required();
17+
unsafe {
18+
let lib = Library::new(FFI_LIB_PATH).expect("Unable to load library");
19+
for symbol in EXPECTED_SYMBOLS {
20+
let _loaded_symbol: Symbol<unsafe extern "C" fn() -> u32> =
21+
lib.get(symbol.as_bytes()).expect(&format!("Missing symbol: {}", symbol));
22+
}
23+
}
24+
}
25+
26+
fn build_lib_if_required() {
27+
let path = Path::new(FFI_LIB_PATH);
28+
if !path.try_exists().unwrap() {
29+
println!("Library not found, building…");
30+
let status = Command::new("cargo")
31+
.args(&["build", "--lib"])
32+
.status()
33+
.expect("Failed to run cargo build for test");
34+
35+
if !status.success() || !path.try_exists().unwrap() {
36+
panic!("Failed to build lib to run test");
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)