use super::*;
fn temp_broker() -> (tempfile::TempDir, Arc<Broker>) {
let dir = tempfile::tempdir().expect("tempdir");
let store = Arc::new(CommsStore::open(dir.path()).expect("store"));
(dir, Arc::new(Broker::new(store)))
}
fn git(repo: &std::path::Path, args: &[&str]) {
let status = std::process::Command::new("git")
.args(args)
.current_dir(repo)
.env("GIT_AUTHOR_NAME", "t")
.env("GIT_AUTHOR_EMAIL", "t@e.x")
.env("GIT_COMMITTER_NAME", "t")
.env("GIT_COMMITTER_EMAIL", "t@e.x")
.status()
.expect("git in PATH");
assert!(status.success(), "git {args:?} failed");
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn hosted_git_history_runs_in_process() {
use crate::git_history::proto::{GitHistoryOp, GitHistoryReply};
use crate::git_history::remote::HistoryHost;
crate::store::init_isolated_cache();
let (_d, broker) = temp_broker();
let repo = tempfile::tempdir().expect("workspace");
let root = repo.path();
git(root, &["init", "-q"]);
git(root, &["config", "commit.gpgsign", "false"]);
std::fs::write(root.join("lib.rs"), "pub fn hosted_history() {}\n").expect("write source");
git(root, &["add", "lib.rs"]);
git(root, &["commit", "-qm", "seed hosted history"]);
match broker
.run_git_history_inproc(root.to_path_buf(), GitHistoryOp::Sync)
.await
.expect("in-process sync")
{
GitHistoryReply::Synced(_) => {}
other => panic!("expected Synced, got {other:?}"),
}
let host: Arc<dyn HistoryHost> = Arc::clone(&broker) as Arc<dyn HistoryHost>;
let reply = host
.run_history(
root.to_path_buf(),
GitHistoryOp::RecentCommits {
skip: 0,
take: 10,
include_files: false,
},
)
.await
.expect("in-process recent-commits");
match reply {
GitHistoryReply::Commits(commits) => {
assert_eq!(
commits.len(),
1,
"the one seeded commit is indexed and read back in-process"
);
assert_eq!(commits[0].summary, "seed hosted history");
}
other => panic!("expected Commits, got {other:?}"),
}
}
#[tokio::test]
async fn rescan_is_refused_while_draining() {
crate::store::init_isolated_cache();
let (_d, broker) = temp_broker();
let (tx, _rx) = mpsc::channel(8);
broker.begin_drain().await;
let ws = tempfile::tempdir().expect("workspace");
std::fs::write(ws.path().join("main.rs"), "pub fn f() {}\n").expect("write source");
let mut session = Session::default();
let resp = broker
.handle(
CommsRequest::Rescan {
root: ws.path().to_path_buf(),
paths: None,
full: true,
embed: false,
},
&mut session,
&tx,
)
.await;
match resp {
CommsResponse::Error { code, .. } => {
assert_eq!(code, "rescan_draining", "the refusal is distinguishable from a failure")
}
other => panic!("a draining daemon must refuse the rescan, got {other:?}"),
}
}
#[tokio::test]
async fn rescan_request_indexes_a_workspace_and_surfaces_it_as_accessed() {
crate::store::init_isolated_cache();
let (_d, broker) = temp_broker();
let (tx, _rx) = mpsc::channel(8);
let mut session = Session::default();
let ws = tempfile::tempdir().expect("workspace");
std::fs::write(ws.path().join("lib.rs"), "pub fn indexed() -> u32 { 7 }\n").expect("write source");
let resp = broker
.handle(
CommsRequest::Rescan {
root: ws.path().to_path_buf(),
paths: None,
full: false,
embed: false,
},
&mut session,
&tx,
)
.await;
match resp {
CommsResponse::Rescanned { scanned, updated, .. } => {
assert_eq!(scanned, 1);
assert_eq!(updated, 1);
}
other => panic!("expected Rescanned, got {other:?}"),
}
let accessed = broker.handle(CommsRequest::AccessedPaths, &mut session, &tx).await;
match accessed {
CommsResponse::Accessed { workspaces } => {
assert_eq!(workspaces.len(), 1);
assert_eq!(workspaces[0].root, ws.path());
}
other => panic!("expected Accessed, got {other:?}"),
}
}