use super::root_publication;
use crate::fsutil::{TestFailPoint, fail_after_for_test, fail_once_for_test};
use crate::test_support::unique_temp_dir;
use crate::{FileObjectStore, ObjectReader, RefStore, RepositoryLayout};
#[test]
fn object_finalization_failures_precede_pointer_and_log_mutation() -> prikk_error::Result<()> {
for (skip, installed_after_error) in [(3, false), (4, true)] {
let root = unique_temp_dir("dc38-object-finalization-retry");
let layout = RepositoryLayout::init(root.clone())?;
let publication = root_publication(&layout, "heads/main")?;
let state_id = publication.ref_state.object_id();
let store = RefStore::new(layout.clone());
fail_after_for_test(TestFailPoint::RequiredFileSync, skip);
assert!(store.publish(&publication).is_err());
assert_eq!(
FileObjectStore::new(layout.clone())
.read_object(state_id)?
.is_some(),
installed_after_error
);
assert_eq!(store.read_current_ref_state_id("heads/main")?, None);
assert_eq!(store.replay_log("heads/main")?.records.len(), 0);
store.publish(&publication)?;
assert_eq!(
store.read_current_ref_state_id("heads/main")?,
Some(state_id)
);
assert_eq!(store.replay_log("heads/main")?.records.len(), 1);
let _ = std::fs::remove_dir_all(root);
}
Ok(())
}
#[test]
fn partial_tail_truncate_failure_preserves_state_for_retry() -> prikk_error::Result<()> {
let root = unique_temp_dir("dc38-partial-truncate-retry");
let layout = RepositoryLayout::init(root.clone())?;
let publication = root_publication(&layout, "heads/main")?;
let store = RefStore::new(layout.clone());
fail_after_for_test(TestFailPoint::AppendWrite, 3);
assert!(store.publish(&publication).is_err());
super::super::super::append_torn_ref_log_tail_for_test(
&layout,
crate::layout::ref_name_key_bytes("heads/main"),
&publication.ref_update,
)?;
fail_once_for_test(TestFailPoint::Truncate);
assert!(
store
.finish_interrupted_publication_for_test(&publication)
.is_err()
);
assert_ne!(store.replay_log("heads/main")?.trailing_partial_bytes, 0);
store.finish_interrupted_publication_for_test(&publication)?;
assert_eq!(store.replay_log("heads/main")?.records.len(), 1);
let _ = std::fs::remove_dir_all(root);
Ok(())
}