use super::*;
use wsb::peer::identity::{Fingerprint, PairedPeer};
use wsb::peer::model::{PeerId, RepositoryId, WorkspaceId};
use crate::machine::MachineState;
fn machine() -> (tokio::runtime::Runtime, tempfile::TempDir, Arc<MachineState>) {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("a runtime");
let dir = tempfile::tempdir().expect("a scratch directory");
let machine = {
let _inside = runtime.enter();
MachineState::new(
dir.path().to_path_buf(),
std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST),
0,
std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST),
0,
)
.expect("a machine with an identity and a store")
};
(runtime, dir, machine)
}
fn pair(machine: &Arc<MachineState>, id: &str, name: &str) -> PeerId {
let peer = PeerId::parse(id).expect("a peer id");
machine
.store
.add_peer(&PairedPeer {
id: peer.clone(),
name: name.to_string(),
public_key: format!("key-{id}"),
fingerprint: Fingerprint::from_stored(format!("{id}-{id}-{id}")),
address: "127.0.0.1:9494".to_string(),
paired_at: 0,
})
.expect("the peer is remembered");
peer
}
fn conflict(
machine: &Arc<MachineState>,
peer: &PeerId,
workspace: &str,
repository: &str,
path: &str,
) {
machine
.store
.record_conflict(
peer,
&WorkspaceId::parse(workspace).expect("a workspace id"),
&if repository.is_empty() {
RepositoryId::root()
} else {
RepositoryId::parse(repository).expect("a repository id")
},
path,
None,
None,
None,
0,
)
.expect("the conflict is recorded");
}
#[test]
fn test9583_conflicts_are_counted_by_workspace_repository_and_peer() {
let (runtime, _scratch, machine) = machine();
let laptop = pair(&machine, "laptop", "bahram-mac");
let desktop = pair(&machine, "desktop", "bahram-linux");
machine
.store
.register_worktree(&wsb::daemon::RegisteredWorktree {
id: wsb::daemon::WorktreeId::parse("machinefabric:main").expect("a worktree id"),
project: Some("machinefabric".to_string()),
name: "main".to_string(),
workspace: Some(WorkspaceId::parse("db3f3a6e071ee7e0@main").expect("a workspace id")),
super_root: std::path::PathBuf::from("/ws/prj/machinefabric/main-worktree"),
root_commit: Some(format!("{:040x}", 1)),
last_seen: 0,
available: true,
})
.expect("the worktree is recorded");
conflict(&machine, &laptop, "db3f3a6e071ee7e0@main", "wsb", "src/main.rs");
conflict(&machine, &laptop, "db3f3a6e071ee7e0@main", "wsb", "src/lib.rs");
conflict(&machine, &desktop, "db3f3a6e071ee7e0@main", "wsb", "src/main.rs");
conflict(&machine, &laptop, "db3f3a6e071ee7e0@main", "", "README.md");
let Json(census) = runtime.block_on(conflicts(State(machine.clone())));
assert_eq!(census.total, 4, "every waiting conflict is counted");
assert_eq!(census.workspaces.len(), 1);
let workspace = &census.workspaces[0];
assert_eq!(
workspace.display_name, "machinefabric/main",
"named as the projects list names the worktree, not by its id"
);
assert_eq!(workspace.total, 4);
let repositories: Vec<(&str, usize, Vec<&str>)> = workspace
.repositories
.iter()
.map(|repository| {
(
repository.repository.as_str(),
repository.conflicts,
repository.peers.iter().map(String::as_str).collect(),
)
})
.collect();
assert_eq!(
repositories,
vec![
("", 1, vec!["bahram-mac"]),
("wsb", 3, vec!["bahram-linux", "bahram-mac"]),
],
"the superproject is the empty repository, exactly as the tree \
addresses it, and each repository names the machines it disagrees \
with, in the order a person reads them"
);
}
#[test]
fn test9584_a_conflict_in_an_unregistered_workspace_is_still_counted() {
let (runtime, _scratch, machine) = machine();
let laptop = pair(&machine, "laptop", "bahram-mac");
conflict(&machine, &laptop, "2502501b3cb21cc4@main", "", "README.md");
let Json(census) = runtime.block_on(conflicts(State(machine.clone())));
assert_eq!(census.total, 1);
assert_eq!(
census.workspaces[0].display_name, "2502501b3cb21cc4@main",
"with no name to give it, the page shows the id rather than nothing"
);
}