Add local file conflict metadata
This commit is contained in:
parent
e1f36ffafb
commit
20c88af800
13 changed files with 673 additions and 15 deletions
|
|
@ -21,5 +21,6 @@ geth-config = { path = "../geth-config" }
|
|||
geth-control = { path = "../geth-control" }
|
||||
geth-node = { path = "../geth-node" }
|
||||
geth-store = { path = "../geth-store" }
|
||||
geth-types = { path = "../geth-types" }
|
||||
rusqlite.workspace = true
|
||||
tempfile.workspace = true
|
||||
|
|
|
|||
|
|
@ -247,6 +247,106 @@ fn cas_file_root_add_list_scan_detects_changes() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cas_file_conflict_record_list_and_resolve() {
|
||||
let home = tempfile::tempdir().expect("tempdir");
|
||||
let paths = geth_config::GethPaths::from_home(home.path());
|
||||
let node = geth_node::init_node(&paths).expect("init node");
|
||||
let root_path = home.path().join("notes-root");
|
||||
std::fs::create_dir_all(&root_path).expect("create root");
|
||||
std::fs::write(root_path.join("todo.md"), b"local").expect("write file");
|
||||
|
||||
geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::CasRootAdd {
|
||||
name: "notes".to_owned(),
|
||||
path: root_path,
|
||||
},
|
||||
)
|
||||
.expect("add root");
|
||||
let local_tree = match geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::CasRootScan {
|
||||
name: "notes".to_owned(),
|
||||
},
|
||||
)
|
||||
.expect("scan root")
|
||||
{
|
||||
geth_control::ControlResponse::CasRootScanned { scan } => scan.tree.hash,
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
};
|
||||
let remote_tree = geth_types::BlobHash::new(
|
||||
"fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
|
||||
);
|
||||
|
||||
let response = geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::CasConflictRecord {
|
||||
root: "notes".to_owned(),
|
||||
path: "todo.md".to_owned(),
|
||||
kind: "concurrent-edit".to_owned(),
|
||||
detail: "local and remote edits touched todo.md".to_owned(),
|
||||
base_tree: None,
|
||||
local_tree: Some(local_tree.clone()),
|
||||
remote_tree: Some(remote_tree.clone()),
|
||||
},
|
||||
)
|
||||
.expect("record conflict");
|
||||
let conflict_id = match response {
|
||||
geth_control::ControlResponse::CasConflictRecorded { conflict } => {
|
||||
assert_eq!(conflict.root, "notes");
|
||||
assert_eq!(conflict.path, "todo.md");
|
||||
assert_eq!(conflict.kind, geth_cas::FileConflictKind::ConcurrentEdit);
|
||||
assert_eq!(conflict.status, geth_cas::FileConflictStatus::Open);
|
||||
assert_eq!(conflict.local_tree, Some(local_tree));
|
||||
assert_eq!(conflict.remote_tree, Some(remote_tree));
|
||||
conflict.id
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
};
|
||||
|
||||
let response = geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::CasConflictList {
|
||||
root: Some("notes".to_owned()),
|
||||
},
|
||||
)
|
||||
.expect("list conflicts");
|
||||
match response {
|
||||
geth_control::ControlResponse::CasConflictList { conflicts } => {
|
||||
assert_eq!(conflicts.len(), 1);
|
||||
assert_eq!(conflicts[0].id, conflict_id);
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
|
||||
let response = geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::CasConflictResolve {
|
||||
conflict_id: conflict_id.clone(),
|
||||
resolution: "keep-local".to_owned(),
|
||||
note: Some("local file is authoritative".to_owned()),
|
||||
},
|
||||
)
|
||||
.expect("resolve conflict");
|
||||
match response {
|
||||
geth_control::ControlResponse::CasConflictResolved { conflict } => {
|
||||
assert_eq!(conflict.id, conflict_id);
|
||||
assert_eq!(conflict.status, geth_cas::FileConflictStatus::Resolved);
|
||||
assert_eq!(
|
||||
conflict.resolution,
|
||||
Some(geth_cas::FileConflictResolution::KeepLocal)
|
||||
);
|
||||
assert_eq!(
|
||||
conflict.resolution_note,
|
||||
Some("local file is authoritative".to_owned())
|
||||
);
|
||||
assert!(conflict.resolved_at_ms.is_some());
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cas_cleanup_removes_unpinned_and_retains_pinned_blobs() {
|
||||
let home = tempfile::tempdir().expect("tempdir");
|
||||
|
|
|
|||
Loading…
Reference in a new issue