#![cfg(unix)]
use std::fs::Metadata;
use std::io;
use std::os::unix::fs::MetadataExt;
use std::path::Path;
use fs_err::{File, OpenOptions};
use uv_cache::Cache;
fn synced_metadata(path: &Path) -> io::Result<Metadata> {
let file = OpenOptions::new().write(true).open(path)?;
file.sync_all()?;
file.metadata()
}
#[test]
fn remove_path_allocated_blocks() -> io::Result<()> {
let cache = Cache::temp()?;
let path = cache.root().join("cached.bin");
fs_err::write(&path, [0])?;
if synced_metadata(&path)?.blocks() == 0 {
return Ok(());
}
let summary = cache.remove_path(&path)?;
assert_eq!(summary.num_files, 1);
assert!(summary.coarse_bytes >= 512);
assert!(!path.exists());
Ok(())
}
#[test]
fn prune_sparse_file() -> io::Result<()> {
let cache = Cache::temp()?;
let stale = cache.root().join("stale-v0");
let nested = stale.join("nested");
fs_err::create_dir_all(&nested)?;
let cached = stale.join("cached.bin");
fs_err::write(&cached, [0])?;
synced_metadata(&cached)?;
let sparse = nested.join("sparse.bin");
File::create(&sparse)?.set_len(1024 * 1024)?;
let sparse_metadata = synced_metadata(&sparse)?;
if sparse_metadata.blocks() >= sparse_metadata.len() / 512 {
return Ok(());
}
let summary = cache.prune(false)?;
assert_eq!(summary.num_files, 2);
assert_eq!(summary.num_dirs, 2);
assert!(summary.coarse_bytes < 1024 * 1024);
assert!(!stale.exists());
assert!(cache.root().is_dir());
Ok(())
}
#[test]
fn remove_path_retained_hardlink() -> io::Result<()> {
let root = tempfile::tempdir()?;
let cache = Cache::from_path(root.path().join("cache"));
fs_err::create_dir(cache.root())?;
let retained = root.path().join("retained.bin");
fs_err::write(&retained, vec![0; 1024 * 1024])?;
assert!(synced_metadata(&retained)?.blocks() > 0);
let cached = cache.root().join("cached.bin");
fs_err::hard_link(&retained, &cached)?;
let summary = cache.remove_path(&cached)?;
assert_eq!(summary.num_files, 1);
assert_eq!(summary.coarse_bytes, 0);
assert!(!cached.exists());
assert!(retained.is_file());
Ok(())
}
#[test]
fn prune_hardlinks_once() -> io::Result<()> {
let cache = Cache::temp()?;
let first = cache.root().join("stale-v0");
let second = cache.root().join("stale-v1");
fs_err::create_dir(&first)?;
fs_err::create_dir(&second)?;
let original = first.join("cached.bin");
fs_err::write(&original, vec![0; 1024 * 1024])?;
let metadata = synced_metadata(&original)?;
if metadata.blocks() < metadata.len() / 512 {
return Ok(());
}
fs_err::hard_link(&original, second.join("cached.bin"))?;
let summary = cache.prune(false)?;
assert_eq!(summary.num_files, 2);
assert_eq!(summary.num_dirs, 2);
assert!((1024 * 1024..2 * 1024 * 1024).contains(&summary.coarse_bytes));
assert!(!first.exists());
assert!(!second.exists());
Ok(())
}