#![allow(clippy::expect_used)]
use polyplug::ffi::polyplug_runtime_create;
use polyplug::ffi::polyplug_runtime_destroy;
use polyplug_abi::HostApi;
fn read_last_error(host: *const HostApi) -> String {
let mut buf: Vec<u8> = vec![0_u8; 512];
let n: usize = unsafe { ((*host).get_last_error)(host, buf.as_mut_ptr(), buf.len()) };
String::from_utf8_lossy(&buf[..n]).into_owned()
}
#[test]
fn test_load_bundle_invalid_utf8_path() {
let host: *const HostApi = unsafe { polyplug_runtime_create(core::ptr::null()) };
assert!(!host.is_null(), "runtime_new must succeed");
let bad_path: &[u8] = &[0xff_u8, 0xfe_u8, b'/', b'p', b'a', b't', b'h'];
let mut result: polyplug_abi::AbiError = polyplug_abi::AbiError::ok();
unsafe { ((*host).load_bundle)(host, bad_path.as_ptr(), bad_path.len(), &mut result) };
assert_ne!(
result.code,
polyplug_abi::AbiErrorCode::Ok as u32,
"load_bundle with invalid UTF-8 path must return error"
);
let err: String = read_last_error(host);
assert!(
!err.is_empty(),
"last_error must be set after invalid UTF-8 path"
);
unsafe { polyplug_runtime_destroy(host) };
}
#[test]
fn test_reload_bundle_invalid_utf8_path() {
let host: *const HostApi = unsafe { polyplug_runtime_create(core::ptr::null()) };
assert!(!host.is_null(), "runtime_new must succeed");
let bad_path: &[u8] = &[0xff_u8, 0xfe_u8, b'/', b'p', b'l', b'u', b'g'];
let mut result: polyplug_abi::AbiError = polyplug_abi::AbiError::ok();
unsafe { ((*host).reload_bundle)(host, bad_path.as_ptr(), bad_path.len(), &mut result) };
assert_ne!(
result.code,
polyplug_abi::AbiErrorCode::Ok as u32,
"reload_bundle with invalid UTF-8 path must return error"
);
let err: String = read_last_error(host);
assert!(
!err.is_empty(),
"last_error must be set after invalid UTF-8 path"
);
unsafe { polyplug_runtime_destroy(host) };
}
#[test]
fn test_runtime_healthy_after_invalid_utf8() {
let host: *const HostApi = unsafe { polyplug_runtime_create(core::ptr::null()) };
assert!(!host.is_null());
let bad_path: &[u8] = &[0xff_u8, 0xfe_u8];
unsafe {
((*host).load_bundle)(
host,
bad_path.as_ptr(),
bad_path.len(),
core::ptr::null_mut(),
)
};
let good_path: &[u8] = b"/tmp/nonexistent_plugin_dir";
let mut result2: polyplug_abi::AbiError = polyplug_abi::AbiError::ok();
unsafe { ((*host).load_bundle)(host, good_path.as_ptr(), good_path.len(), &mut result2) };
let err2: String = read_last_error(host);
assert!(
!err2.is_empty(),
"runtime must be healthy and set last_error on second call"
);
let _ = result2;
unsafe { polyplug_runtime_destroy(host) };
}