This commit is contained in:
Nathan Sobo 2022-04-07 09:29:47 -06:00
parent 7a151ffc75
commit 717f53e3d2
2 changed files with 52 additions and 23 deletions

View file

@ -14,7 +14,6 @@ required-features = ["seed-support"]
[dependencies] [dependencies]
collections = { path = "../collections" } collections = { path = "../collections" }
settings = { path = "../settings" }
rpc = { path = "../rpc" } rpc = { path = "../rpc" }
anyhow = "1.0.40" anyhow = "1.0.40"
async-io = "1.3" async-io = "1.3"
@ -65,6 +64,7 @@ editor = { path = "../editor", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] } language = { path = "../language", features = ["test-support"] }
lsp = { path = "../lsp", features = ["test-support"] } lsp = { path = "../lsp", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] } project = { path = "../project", features = ["test-support"] }
settings = { path = "../settings", features = ["test-support"] }
workspace = { path = "../workspace", features = ["test-support"] } workspace = { path = "../workspace", features = ["test-support"] }
ctor = "0.1" ctor = "0.1"
env_logger = "0.8" env_logger = "0.8"

View file

@ -1080,7 +1080,7 @@ mod tests {
use ::rpc::Peer; use ::rpc::Peer;
use client::{ use client::{
self, test::FakeHttpClient, Channel, ChannelDetails, ChannelList, Client, Credentials, self, test::FakeHttpClient, Channel, ChannelDetails, ChannelList, Client, Credentials,
EstablishConnectionError, UserStore, EstablishConnectionError, UserStore, RECEIVE_TIMEOUT,
}; };
use collections::BTreeMap; use collections::BTreeMap;
use editor::{ use editor::{
@ -4983,6 +4983,7 @@ mod tests {
let operations = Rc::new(Cell::new(0)); let operations = Rc::new(Cell::new(0));
let mut server = TestServer::start(cx.foreground(), cx.background()).await; let mut server = TestServer::start(cx.foreground(), cx.background()).await;
let mut clients = Vec::new(); let mut clients = Vec::new();
let mut user_ids = Vec::new();
let files = Arc::new(Mutex::new(Vec::new())); let files = Arc::new(Mutex::new(Vec::new()));
let mut next_entity_id = 100000; let mut next_entity_id = 100000;
@ -5150,13 +5151,14 @@ mod tests {
}); });
host_language_registry.add(Arc::new(language)); host_language_registry.add(Arc::new(language));
user_ids.push(host.current_user_id(&host_cx));
clients.push(cx.foreground().spawn(host.simulate_host( clients.push(cx.foreground().spawn(host.simulate_host(
host_project, host_project,
files, files,
operations.clone(), operations.clone(),
max_operations, max_operations,
rng.clone(), rng.clone(),
host_cx, &mut host_cx,
))); )));
while operations.get() < max_operations { while operations.get() < max_operations {
@ -5191,6 +5193,7 @@ mod tests {
) )
.await .await
.unwrap(); .unwrap();
user_ids.push(guest.current_user_id(&guest_cx));
clients.push(cx.foreground().spawn(guest.simulate_guest( clients.push(cx.foreground().spawn(guest.simulate_guest(
guest_id, guest_id,
guest_project, guest_project,
@ -5201,6 +5204,30 @@ mod tests {
))); )));
log::info!("Guest {} added", guest_id); log::info!("Guest {} added", guest_id);
} else if rng.lock().gen_bool(0.05) {
server.disconnect_client(user_ids[0]);
cx.foreground().advance_clock(RECEIVE_TIMEOUT);
let mut clients = futures::future::join_all(clients).await;
cx.foreground().run_until_parked();
let store = server.store.read();
let (host, host_cx) = clients.remove(0);
host.project
.as_ref()
.unwrap()
.read_with(&host_cx, |project, _| assert!(!project.is_shared()));
for (guest, guest_cx) in clients {
assert!(store
.contacts_for_user(guest.current_user_id(&guest_cx))
.is_empty());
guest
.project
.as_ref()
.unwrap()
.read_with(&guest_cx, |project, _| assert!(project.is_read_only()));
}
return;
} }
} }
@ -5471,6 +5498,14 @@ mod tests {
} }
} }
impl Deref for TestServer {
type Target = Server;
fn deref(&self) -> &Self::Target {
&self.server
}
}
impl Drop for TestServer { impl Drop for TestServer {
fn drop(&mut self) { fn drop(&mut self) {
self.peer.reset(); self.peer.reset();
@ -5584,15 +5619,15 @@ mod tests {
} }
async fn simulate_host( async fn simulate_host(
mut self, &mut self,
project: ModelHandle<Project>, project: ModelHandle<Project>,
files: Arc<Mutex<Vec<PathBuf>>>, files: Arc<Mutex<Vec<PathBuf>>>,
operations: Rc<Cell<usize>>, operations: Rc<Cell<usize>>,
max_operations: usize, max_operations: usize,
rng: Arc<Mutex<StdRng>>, rng: Arc<Mutex<StdRng>>,
mut cx: TestAppContext, cx: &mut TestAppContext,
) -> (Self, TestAppContext) { ) -> anyhow::Result<()> {
let fs = project.read_with(&cx, |project, _| project.fs().clone()); let fs = project.read_with(cx, |project, _| project.fs().clone());
while operations.get() < max_operations { while operations.get() < max_operations {
operations.set(operations.get() + 1); operations.set(operations.get() + 1);
@ -5609,29 +5644,25 @@ mod tests {
} }
log::info!("Host: find/create local worktree {:?}", path); log::info!("Host: find/create local worktree {:?}", path);
let find_or_create_worktree = project.update(&mut cx, |project, cx| { let find_or_create_worktree = project.update(cx, |project, cx| {
project.find_or_create_local_worktree(path, true, cx) project.find_or_create_local_worktree(path, true, cx)
}); });
let find_or_create_worktree = async move {
find_or_create_worktree.await.unwrap();
};
if rng.lock().gen() { if rng.lock().gen() {
cx.background().spawn(find_or_create_worktree).detach(); cx.background().spawn(find_or_create_worktree).detach();
} else { } else {
find_or_create_worktree.await; find_or_create_worktree.await?;
} }
} }
10..=80 if !files.lock().is_empty() => { 10..=80 if !files.lock().is_empty() => {
let buffer = if self.buffers.is_empty() || rng.lock().gen() { let buffer = if self.buffers.is_empty() || rng.lock().gen() {
let file = files.lock().choose(&mut *rng.lock()).unwrap().clone(); let file = files.lock().choose(&mut *rng.lock()).unwrap().clone();
let (worktree, path) = project let (worktree, path) = project
.update(&mut cx, |project, cx| { .update(cx, |project, cx| {
project.find_or_create_local_worktree(file.clone(), true, cx) project.find_or_create_local_worktree(file.clone(), true, cx)
}) })
.await .await?;
.unwrap();
let project_path = let project_path =
worktree.read_with(&cx, |worktree, _| (worktree.id(), path)); worktree.read_with(cx, |worktree, _| (worktree.id(), path));
log::info!( log::info!(
"Host: opening path {:?}, worktree {}, relative_path {:?}", "Host: opening path {:?}, worktree {}, relative_path {:?}",
file, file,
@ -5639,9 +5670,7 @@ mod tests {
project_path.1 project_path.1
); );
let buffer = project let buffer = project
.update(&mut cx, |project, cx| { .update(cx, |project, cx| project.open_buffer(project_path, cx))
project.open_buffer(project_path, cx)
})
.await .await
.unwrap(); .unwrap();
self.buffers.insert(buffer.clone()); self.buffers.insert(buffer.clone());
@ -5664,7 +5693,7 @@ mod tests {
drop(buffer); drop(buffer);
}); });
} else { } else {
buffer.update(&mut cx, |buffer, cx| { buffer.update(cx, |buffer, cx| {
log::info!( log::info!(
"Host: updating buffer {:?} ({})", "Host: updating buffer {:?} ({})",
buffer.file().unwrap().full_path(cx), buffer.file().unwrap().full_path(cx),
@ -5701,10 +5730,10 @@ mod tests {
cx.background().simulate_random_delay().await; cx.background().simulate_random_delay().await;
} }
log::info!("Host done");
self.project = Some(project); self.project = Some(project);
(self, cx)
log::info!("Host done");
Ok(())
} }
pub async fn simulate_guest( pub async fn simulate_guest(