97 lines
3.6 KiB
Rust
97 lines
3.6 KiB
Rust
#![cfg(target_os = "linux")]
|
|
|
|
use sized::{scan_tree, ScanControl, ScanOptions};
|
|
use std::{fs, io::Write, os::unix::fs::MetadataExt, path::PathBuf, process::Command};
|
|
use tempfile::NamedTempFile;
|
|
|
|
#[test]
|
|
#[ignore = "requires the two owned tmpfs mounts from scripts/check-linux.sh"]
|
|
fn real_mount_boundary_is_respected_by_scanner_and_cli() {
|
|
let root = PathBuf::from(
|
|
std::env::var_os("SIZED_TEST_MOUNT_ROOT").expect("missing mounted Linux fixture"),
|
|
);
|
|
let foreign = root.join("foreign");
|
|
let root_metadata = fs::metadata(&root).unwrap();
|
|
let foreign_metadata = fs::metadata(&foreign).unwrap();
|
|
assert_ne!(
|
|
root_metadata.dev(),
|
|
foreign_metadata.dev(),
|
|
"not a real boundary"
|
|
);
|
|
let mut local_file = NamedTempFile::new_in(&root).unwrap();
|
|
let mut mounted_file = NamedTempFile::new_in(&foreign).unwrap();
|
|
local_file.write_all(b"local allocation").unwrap();
|
|
mounted_file.write_all(&[7; 8192]).unwrap();
|
|
local_file.as_file().sync_all().unwrap();
|
|
mounted_file.as_file().sync_all().unwrap();
|
|
|
|
for bounded in [false, true] {
|
|
let report = scan_tree(
|
|
&root,
|
|
&ScanOptions {
|
|
stay_on_filesystem: bounded,
|
|
threads: Some(2),
|
|
..ScanOptions::default()
|
|
},
|
|
&ScanControl::default(),
|
|
)
|
|
.unwrap();
|
|
assert!(report.root.complete);
|
|
assert!(report.issues.is_empty());
|
|
let mount = report
|
|
.root
|
|
.children
|
|
.iter()
|
|
.find(|n| n.path == foreign)
|
|
.unwrap();
|
|
assert_eq!(mount.identity.unwrap().device, foreign_metadata.dev());
|
|
assert_eq!(mount.skipped_mount, bounded);
|
|
assert_eq!(report.entries_scanned, if bounded { 3 } else { 4 });
|
|
let expected_blocks =
|
|
root_metadata.blocks() + local_file.as_file().metadata().unwrap().blocks();
|
|
if bounded {
|
|
assert!(mount.children.is_empty());
|
|
assert_eq!(mount.blocks, 0);
|
|
assert_eq!(mount.size_bytes, 0);
|
|
assert_eq!(report.root.blocks, expected_blocks);
|
|
} else {
|
|
assert_eq!(mount.children.len(), 1);
|
|
assert_eq!(mount.children[0].path, mounted_file.path());
|
|
assert_eq!(mount.children[0].size_bytes, 8192);
|
|
assert_eq!(
|
|
report.root.blocks,
|
|
expected_blocks
|
|
+ foreign_metadata.blocks()
|
|
+ mounted_file.as_file().metadata().unwrap().blocks()
|
|
);
|
|
}
|
|
|
|
let mut command = Command::new(env!("CARGO_BIN_EXE_sized"));
|
|
command
|
|
.arg(&root)
|
|
.args(["--format", "json", "--apparent", "--threads", "2"]);
|
|
if bounded {
|
|
command.arg("--one-file-system");
|
|
}
|
|
let output = command.output().unwrap();
|
|
assert!(
|
|
output.status.success(),
|
|
"{}",
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
assert!(output.stderr.is_empty());
|
|
let json: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
|
|
assert_eq!(json["complete"], true);
|
|
assert_eq!(json["total_blocks"], report.root.blocks);
|
|
let mount_json = json["entries"]
|
|
.as_array()
|
|
.unwrap()
|
|
.iter()
|
|
.find(|entry| entry["path"] == foreign.to_str().unwrap())
|
|
.unwrap();
|
|
assert_eq!(mount_json["skipped_mount"], bounded);
|
|
assert_eq!(mount_json["blocks"], mount.blocks);
|
|
assert_eq!(mount_json["apparent_size"], mount.size_bytes);
|
|
}
|
|
}
|