75 lines
2.3 KiB
Rust
75 lines
2.3 KiB
Rust
//! 中间归档只检查文件属性;读取计数与异常文件覆盖不启动 Go 工具。
|
|
|
|
use super::*;
|
|
use std::os::unix::fs::symlink;
|
|
|
|
fn stage() -> Stage {
|
|
let root = std::env::temp_dir().join(format!(
|
|
"dever-go-output-{}-{}",
|
|
std::process::id(),
|
|
std::time::SystemTime::now()
|
|
.duration_since(std::time::UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_nanos()
|
|
));
|
|
fs::DirBuilder::new().mode(0o700).create(&root).unwrap();
|
|
Stage {
|
|
root,
|
|
resources: BTreeMap::new(),
|
|
written: 0,
|
|
started: Instant::now(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn go_intermediate_output_checks_metadata_without_reading_archive() {
|
|
let stage = stage();
|
|
let path = stage.root.join("package.a");
|
|
let length = 8 * 1024 * 1024;
|
|
fs::File::create(&path).unwrap().set_len(length).unwrap();
|
|
let read_chars = || {
|
|
fs::read_to_string("/proc/thread-self/io")
|
|
.unwrap()
|
|
.lines()
|
|
.find_map(|line| line.strip_prefix("rchar: "))
|
|
.unwrap()
|
|
.parse::<u64>()
|
|
.unwrap()
|
|
};
|
|
let before = read_chars();
|
|
drop(stage.output(&path).unwrap());
|
|
let consumed = read_chars() - before;
|
|
eprintln!("go intermediate: fixture=sparse-zero bytes={length} rchar={consumed}");
|
|
assert!(
|
|
consumed < 4096,
|
|
"read {consumed} bytes for a metadata check"
|
|
);
|
|
assert_eq!(fs::metadata(path).unwrap().len(), length);
|
|
}
|
|
|
|
#[test]
|
|
fn go_output_rejects_links_empty_special_and_oversized_files() {
|
|
let stage = stage();
|
|
let path = stage.root.join("output");
|
|
fs::write(&path, b"archive").unwrap();
|
|
drop(stage.output(&path).unwrap());
|
|
let link = stage.root.join("symbolic");
|
|
symlink(&path, &link).unwrap();
|
|
assert!(stage.output(&link).is_err());
|
|
fs::remove_file(link).unwrap();
|
|
let link = stage.root.join("hard");
|
|
fs::hard_link(&path, &link).unwrap();
|
|
assert!(stage.output(&path).is_err());
|
|
fs::remove_file(link).unwrap();
|
|
assert!(stage.output(&stage.root).is_err());
|
|
fs::File::create(&path).unwrap();
|
|
assert!(stage.output(&path).is_err());
|
|
fs::File::create(&path)
|
|
.unwrap()
|
|
.set_len(128 * 1024 * 1024 + 1)
|
|
.unwrap();
|
|
assert!(stage.output(&path).is_err());
|
|
fs::remove_file(&path).unwrap();
|
|
assert!(stage.output(&path).is_err());
|
|
}
|