use std::path::Path;
use trusty_common::sys_metrics::dir_allocated_bytes;
#[derive(Debug, Clone, Copy, Default)]
pub(super) struct DaemonUsage {
pub(super) ram_bytes: Option<u64>,
pub(super) ram_heap_bytes: Option<u64>,
pub(super) ram_file_backed_bytes: Option<u64>,
pub(super) ram_compressed_bytes: Option<u64>,
pub(super) disk_bytes: u64,
}
pub(super) fn sample(data_root: &Path) -> DaemonUsage {
let breakdown = trusty_common::sys_metrics::self_memory_breakdown();
DaemonUsage {
ram_bytes: process_footprint_bytes(),
ram_heap_bytes: breakdown.map(|b| b.heap_bytes),
ram_file_backed_bytes: breakdown.map(|b| b.file_backed_bytes),
ram_compressed_bytes: breakdown.map(|b| b.compressed_bytes),
disk_bytes: dir_allocated_bytes(data_root),
}
}
pub(super) fn palace_disk_bytes(data_dir: &Path) -> u64 {
dir_allocated_bytes(data_dir)
}
fn process_footprint_bytes() -> Option<u64> {
#[cfg(target_os = "macos")]
{
trusty_common::sys_metrics::physical_footprint_bytes(std::process::id())
}
#[cfg(not(target_os = "macos"))]
{
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn usage_sample_reports_a_footprint_and_a_disk_figure() {
let tmp = tempfile::TempDir::new().expect("tempdir");
std::fs::write(tmp.path().join("kg.redb"), vec![0u8; 40_000]).expect("write");
let usage = sample(tmp.path());
assert!(
usage.disk_bytes >= 40_000,
"disk_bytes must cover the fixture file, got {}",
usage.disk_bytes
);
#[cfg(target_os = "macos")]
{
let ram = usage.ram_bytes.expect("macOS reports a footprint");
assert!(ram > 1024 * 1024, "a live process holds more than 1 MB");
assert!(
usage.ram_heap_bytes.is_some(),
"macOS supplies the heap/file-backed/compressed split"
);
}
}
#[test]
fn palace_disk_bytes_counts_a_palace_directory() {
let tmp = tempfile::TempDir::new().expect("tempdir");
let palace = tmp.path().join("scratch");
std::fs::create_dir(&palace).expect("mkdir");
std::fs::write(palace.join("kg.redb"), vec![0u8; 8_000]).expect("write");
let other = tmp.path().join("other");
std::fs::create_dir(&other).expect("mkdir");
std::fs::write(other.join("kg.redb"), vec![0u8; 900_000]).expect("write");
let measured = palace_disk_bytes(&palace);
assert!(measured >= 8_000, "got {measured}");
assert!(measured < 900_000, "a sibling palace leaked in: {measured}");
}
#[test]
fn palace_disk_bytes_is_zero_for_a_missing_directory() {
let tmp = tempfile::TempDir::new().expect("tempdir");
assert_eq!(palace_disk_bytes(&tmp.path().join("gone")), 0);
}
}