0755222562
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
64 lines
2.4 KiB
Rust
64 lines
2.4 KiB
Rust
//! The built shared library, loaded the way a CFFI caller loads it.
|
|
//! Evidence: `context/test-evidence/zset-ffi.md`.
|
|
|
|
use libloading::{Library, Symbol};
|
|
use std::path::PathBuf;
|
|
use std::ptr::null_mut;
|
|
|
|
type Opaque = std::ffi::c_void;
|
|
|
|
/// Cargo puts the cdylib in `target/<profile>/deps` beside this test binary's own directory.
|
|
fn library() -> PathBuf {
|
|
let exe = std::env::current_exe().unwrap();
|
|
let deps = exe.parent().unwrap();
|
|
let ext = if cfg!(target_os = "macos") {
|
|
"dylib"
|
|
} else {
|
|
"so"
|
|
};
|
|
let name = format!("{}zset_ffi.{ext}", if cfg!(windows) { "" } else { "lib" });
|
|
[deps.join(&name), deps.parent().unwrap().join(&name)]
|
|
.into_iter()
|
|
.find(|p| p.exists())
|
|
.unwrap_or_else(|| panic!("{name} was not built next to {}", deps.display()))
|
|
}
|
|
|
|
#[test]
|
|
fn a_loaded_library_adds_queries_frees_and_reports_overflow() {
|
|
// SAFETY: loads this workspace's own library; the symbols below have the header's types.
|
|
unsafe {
|
|
let lib = Library::new(library()).unwrap();
|
|
let version: Symbol<extern "C" fn() -> u32> = lib.get(b"zs_abi_version").unwrap();
|
|
let new: Symbol<extern "C" fn(*mut *mut Opaque) -> i32> = lib.get(b"zs_zset_new").unwrap();
|
|
let free: Symbol<extern "C" fn(*mut Opaque)> = lib.get(b"zs_zset_free").unwrap();
|
|
let insert: Symbol<extern "C" fn(*mut Opaque, *const u8, usize, i64) -> i32> =
|
|
lib.get(b"zs_zset_insert").unwrap();
|
|
let weight: Symbol<extern "C" fn(*const Opaque, *const u8, usize, *mut i64) -> i32> =
|
|
lib.get(b"zs_zset_weight").unwrap();
|
|
let last: Symbol<extern "C" fn() -> *const std::ffi::c_char> =
|
|
lib.get(b"zs_last_error").unwrap();
|
|
assert_eq!(version(), 1);
|
|
let mut z = null_mut();
|
|
assert_eq!(new(&mut z), 0);
|
|
assert_eq!(insert(z, b"k".as_ptr(), 1, 40), 0);
|
|
assert_eq!(insert(z, b"k".as_ptr(), 1, 2), 0);
|
|
let mut w = 0;
|
|
assert_eq!(weight(z, b"k".as_ptr(), 1, &mut w), 0);
|
|
assert_eq!(w, 42);
|
|
assert_eq!(
|
|
insert(z, b"k".as_ptr(), 1, i64::MAX),
|
|
2,
|
|
"overflow is ZS_ERR_OVERFLOW"
|
|
);
|
|
assert!(
|
|
std::ffi::CStr::from_ptr(last())
|
|
.to_str()
|
|
.unwrap()
|
|
.contains("overflow")
|
|
);
|
|
assert_eq!(weight(z, b"k".as_ptr(), 1, &mut w), 0);
|
|
assert_eq!(w, 42, "the failed insert changed nothing");
|
|
free(z);
|
|
}
|
|
}
|