mod common;
#[cfg(target_os = "linux")]
#[test]
fn xattr_save_and_restore_preserves_attributes() {
use std::process::Command;
let dir = tempfile::tempdir().expect("tempdir");
let workspace = dir.path().to_str().unwrap();
let f = dir.path().join("with_xattr.txt");
std::fs::write(&f, "content v1\n").expect("write");
let setattr = Command::new("setfattr")
.args([
"-n",
"user.atomwrite_test",
"-v",
"marker",
f.to_str().unwrap(),
])
.output();
if setattr.is_err() || !setattr.as_ref().unwrap().status.success() {
eprintln!("setfattr not available or filesystem doesn't support xattrs; skipping");
return;
}
let output = common::atomwrite()
.args([
"--workspace",
workspace,
"edit",
f.to_str().unwrap(),
"--old",
"content v1",
"--new",
"content v2",
])
.output()
.expect("edit");
assert!(
output.status.success(),
"edit failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let getattr = Command::new("getfattr")
.args([
"--only-values",
"-n",
"user.atomwrite_test",
f.to_str().unwrap(),
])
.output()
.expect("getfattr");
let value = String::from_utf8_lossy(&getattr.stdout);
assert_eq!(
value.trim(),
"marker",
"xattr should be preserved after edit"
);
}
#[cfg(target_os = "linux")]
#[test]
fn reflink_fallback_to_copy_on_unsupported_fs() {
let dir = tempfile::tempdir().expect("tempdir");
let workspace = dir.path().to_str().unwrap();
let src = dir.path().join("src.txt");
let dst = dir.path().join("dst.txt");
std::fs::write(&src, "x".repeat(1024)).expect("write");
let output = common::atomwrite()
.args([
"--workspace",
workspace,
"copy",
src.to_str().unwrap(),
dst.to_str().unwrap(),
])
.output()
.expect("copy");
assert!(
output.status.success(),
"copy failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let src_meta = std::fs::metadata(&src).expect("src meta");
let dst_meta = std::fs::metadata(&dst).expect("dst meta");
assert_eq!(src_meta.len(), dst_meta.len(), "size should match");
}
#[cfg(target_os = "linux")]
#[test]
fn atomic_write_preserves_file_size_for_replace() {
let dir = tempfile::tempdir().expect("tempdir");
let workspace = dir.path().to_str().unwrap();
let f = dir.path().join("size_test.txt");
std::fs::write(&f, "AAAA").expect("write");
let original_meta = std::fs::metadata(&f).expect("meta");
let original_size = original_meta.len();
let output = common::atomwrite()
.args([
"--workspace",
workspace,
"edit",
f.to_str().unwrap(),
"--old",
"AAAA",
"--new",
"BBBB",
])
.output()
.expect("edit");
assert!(
output.status.success(),
"edit failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let new_meta = std::fs::metadata(&f).expect("meta");
assert_eq!(
new_meta.len(),
original_size,
"size should be preserved (or grow to 4 bytes)"
);
}
#[cfg(target_os = "linux")]
#[test]
fn exdev_fallback_message_in_stderr() {
use atomwrite::error::AtomwriteError;
let err: AtomwriteError = AtomwriteError::InvalidInput {
reason: "exdev test".to_string(),
};
matches!(err, AtomwriteError::InvalidInput { .. });
}