use super::*;
#[test]
fn rollback_failure_leaves_every_ambiguous_tree_for_operator_recovery() {
let temp = tempfile::tempdir().unwrap();
let output = Utf8PathBuf::from_path_buf(temp.path().join("wiki")).unwrap();
let paths = TransactionPaths::new(&output).unwrap();
std::fs::create_dir(&output).unwrap();
std::fs::write(output.join("generation"), "old").unwrap();
std::fs::create_dir(&paths.stage).unwrap();
std::fs::write(paths.stage.join("generation"), "new").unwrap();
let mut rename_count = 0;
let error = replace_output_with(
&output,
&paths,
|_, _| {
rename_count += 1;
if rename_count > 1 {
Err(std::io::Error::other("injected rename failure"))
} else {
Ok(())
}
},
|_| Ok(()),
)
.unwrap_err();
assert!(matches!(error, PublishError::RollbackFailed { .. }));
assert!(!output.exists());
assert_eq!(
std::fs::read_to_string(paths.backup.join("generation")).unwrap(),
"old"
);
assert_eq!(
std::fs::read_to_string(paths.stage.join("generation")).unwrap(),
"new"
);
}
#[test]
fn no_replace_rename_preserves_an_output_that_appeared() {
let temp = tempfile::tempdir().unwrap();
let output = Utf8PathBuf::from_path_buf(temp.path().join("wiki")).unwrap();
let stage = Utf8PathBuf::from_path_buf(temp.path().join("stage")).unwrap();
std::fs::create_dir(&output).unwrap();
std::fs::write(output.join("caller"), "keep me").unwrap();
std::fs::create_dir(&stage).unwrap();
std::fs::write(stage.join("generated"), "new").unwrap();
let parent = ownership::open_directory_no_follow(temp.path()).unwrap();
let error =
replacement::rename_no_replace_at(&parent, output.parent().unwrap(), "stage", "wiki")
.unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::AlreadyExists);
assert_eq!(
std::fs::read_to_string(output.join("caller")).unwrap(),
"keep me"
);
assert_eq!(
std::fs::read_to_string(stage.join("generated")).unwrap(),
"new"
);
}