#![cfg(all(target_os = "linux", feature = "nvidia"))]
use std::path::{Path, PathBuf};
use std::process::Command;
use std::sync::OnceLock;
use nvml_wrapper::enum_wrappers::device::TemperatureSensor;
use nvml_wrapper::error::NvmlError;
use nvml_wrapper::Nvml;
fn stub_so() -> &'static Path {
static STUB: OnceLock<PathBuf> = OnceLock::new();
STUB.get_or_init(|| {
let src = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/nvml_stub/stub.rs");
let out = Path::new(env!("CARGO_TARGET_TMPDIR")).join("libgpv_nvml_stub.so");
let rustc = std::env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
let output = Command::new(rustc)
.arg("--edition=2021")
.arg("--crate-type=cdylib")
.arg("-o")
.arg(&out)
.arg(&src)
.output()
.expect("spawn rustc to build the NVML stub cdylib");
assert!(
output.status.success(),
"rustc failed to build the NVML stub:\n{}",
String::from_utf8_lossy(&output.stderr)
);
out
})
}
fn opt<T, E>(r: Result<T, E>) -> Option<T> {
r.ok()
}
#[test]
fn stub_init_via_lib_path_and_graceful_per_symbol_degradation() {
let nvml = Nvml::builder()
.lib_path(stub_so().as_os_str())
.init()
.expect("stub must initialize through the lib_path plumbing");
assert_eq!(nvml.sys_driver_version().unwrap(), "999.99-gpv-stub");
assert_eq!(nvml.device_count().unwrap(), 1);
let dev = nvml.device_by_index(0).unwrap();
assert_eq!(dev.name().unwrap(), "GPV-STUB");
assert!(matches!(
nvml.device_by_index(7),
Err(NvmlError::InvalidArg)
));
assert!(matches!(dev.fan_speed(0), Err(NvmlError::NotSupported)));
assert_eq!(opt(dev.fan_speed(0)).map(|f| f as f32), None);
assert!(matches!(
dev.temperature(TemperatureSensor::Gpu),
Err(NvmlError::FailedToLoadSymbol(_))
));
assert_eq!(opt(dev.temperature(TemperatureSensor::Gpu)), None);
assert!(matches!(
dev.memory_info(),
Err(NvmlError::FailedToLoadSymbol(_))
));
assert!(opt(dev.memory_info()).map(|m| m.total).is_none());
drop(nvml);
}
#[test]
fn missing_library_is_an_error_not_a_panic() {
let missing = std::ffi::OsStr::new("/nonexistent/libgpv-no-such-nvml.so.1");
let r = Nvml::builder().lib_path(missing).init();
assert!(r.is_err(), "a missing library must be Err, got Ok");
}