mod common; use common::setup; use libbtrfsutil::{subvolume_info, subvolume_read_only}; use std::{ num::NonZeroU64, path::PathBuf, time::{Duration, SystemTime}, }; #[test] fn test_subvolume_info() { let device = setup( "test_subvolume_info".into(), "test_subvolume_info_dir".into(), ); let subvol_path = device.mountpoint().unwrap().clone().join("subvol"); libbtrfsutil::CreateSubvolumeOptions::new() .create(&subvol_path) .unwrap(); let snapshot_path = device.mountpoint().unwrap().clone().join("snapshot"); libbtrfsutil::CreateSnapshotOptions::new() .readonly(true) .create(&subvol_path, &snapshot_path) .unwrap(); let root_info = subvolume_info(device.mountpoint().unwrap()).unwrap(); assert_eq!(root_info.id(), 5); assert_eq!(root_info.parent_id(), None); assert_eq!(root_info.dir_id(), None); assert_eq!(root_info.flags(), 0); assert!(!root_info.uuid().is_nil()); assert_eq!(root_info.parent_uuid(), None); assert_eq!(root_info.received_uuid(), None); assert_ne!(root_info.generation(), 0); assert_ne!(root_info.ctransid(), 0); assert_eq!(root_info.otransid(), 0); assert_eq!(root_info.stransid(), None); assert_eq!(root_info.rtransid(), None); assert_ne!(root_info.ctime(), 0); assert_ne!(root_info.otime(), 0); assert_eq!(root_info.stime(), None); assert_eq!(root_info.stime_nsec(), None); assert_eq!(root_info.rtime(), None); assert_eq!(root_info.rtime_nsec(), None); assert_eq!( root_info .created() .duration_since(SystemTime::UNIX_EPOCH) .unwrap(), Duration::new(root_info.otime() as u64, root_info.otime_nsec() as u32) ); assert_eq!( root_info .changed() .duration_since(SystemTime::UNIX_EPOCH) .unwrap(), Duration::new(root_info.ctime() as u64, root_info.ctime_nsec() as u32) ); assert_eq!(root_info.received(), None); let subvol_info = subvolume_info(subvol_path).unwrap(); assert_eq!(subvol_info.id(), 256); assert_eq!(subvol_info.parent_id(), NonZeroU64::new(5)); assert_eq!(subvol_info.dir_id(), NonZeroU64::new(256)); assert_eq!(subvol_info.flags(), 0); assert!(!subvol_info.uuid().is_nil()); assert_eq!(subvol_info.parent_uuid(), None); assert_eq!(subvol_info.received_uuid(), None); assert_ne!(subvol_info.generation(), 0); assert_ne!(subvol_info.ctransid(), 0); assert!(subvol_info.otransid() > root_info.otransid()); assert_eq!(subvol_info.stransid(), None); assert_eq!(subvol_info.rtransid(), None); assert_ne!(subvol_info.ctime(), 0); assert_ne!(subvol_info.otime(), 0); assert_eq!(subvol_info.stime(), None); assert_eq!(subvol_info.stime_nsec(), None); assert_eq!(subvol_info.rtime(), None); assert_eq!(subvol_info.rtime_nsec(), None); assert_eq!( subvol_info .created() .duration_since(SystemTime::UNIX_EPOCH) .unwrap(), Duration::new(subvol_info.otime() as u64, subvol_info.otime_nsec() as u32) ); assert_eq!( subvol_info .changed() .duration_since(SystemTime::UNIX_EPOCH) .unwrap(), Duration::new(subvol_info.ctime() as u64, subvol_info.ctime_nsec() as u32) ); assert_eq!(subvol_info.received(), None); let snapshot_info = subvolume_info(&snapshot_path).unwrap(); assert_eq!(snapshot_info.parent_id(), NonZeroU64::new(5)); assert_eq!(snapshot_info.dir_id(), NonZeroU64::new(256)); assert_eq!(snapshot_info.parent_uuid(), Some(subvol_info.uuid())); let is_readonly = subvolume_read_only(&snapshot_path).unwrap(); assert_eq!(is_readonly, true); } #[test] fn test_subvolume_path() { let device = setup( "test_subvolume_path".into(), "test_subvolume_path_dir".into(), ); let subvol_path = device.mountpoint().unwrap().clone().join("subvol"); libbtrfsutil::CreateSubvolumeOptions::new() .create(&subvol_path) .unwrap(); let ret_path = libbtrfsutil::subvolume_path(subvol_path).unwrap(); assert_eq!(ret_path, PathBuf::from("subvol")); }