Request definitions as guests in random collaboration integration test
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
64098247cb
commit
dbe9c54857
1 changed files with 108 additions and 61 deletions
|
@ -1165,7 +1165,7 @@ mod tests {
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use sqlx::types::time::OffsetDateTime;
|
use sqlx::types::time::OffsetDateTime;
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Cell, RefCell},
|
cell::Cell,
|
||||||
env,
|
env,
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
path::Path,
|
path::Path,
|
||||||
|
@ -3840,7 +3840,7 @@ mod tests {
|
||||||
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||||
.unwrap_or(10);
|
.unwrap_or(10);
|
||||||
|
|
||||||
let rng = Rc::new(RefCell::new(rng));
|
let rng = Arc::new(Mutex::new(rng));
|
||||||
|
|
||||||
let guest_lang_registry = Arc::new(LanguageRegistry::new());
|
let guest_lang_registry = Arc::new(LanguageRegistry::new());
|
||||||
let (language_server_config, _fake_language_servers) = LanguageServerConfig::fake();
|
let (language_server_config, _fake_language_servers) = LanguageServerConfig::fake();
|
||||||
|
@ -3906,7 +3906,7 @@ mod tests {
|
||||||
|
|
||||||
while operations.get() < max_operations {
|
while operations.get() < max_operations {
|
||||||
cx.background().simulate_random_delay().await;
|
cx.background().simulate_random_delay().await;
|
||||||
if clients.len() < max_peers && rng.borrow_mut().gen_bool(0.05) {
|
if clients.len() < max_peers && rng.lock().gen_bool(0.05) {
|
||||||
operations.set(operations.get() + 1);
|
operations.set(operations.get() + 1);
|
||||||
|
|
||||||
let guest_id = clients.len();
|
let guest_id = clients.len();
|
||||||
|
@ -4233,39 +4233,66 @@ mod tests {
|
||||||
mut language_server_config: LanguageServerConfig,
|
mut language_server_config: LanguageServerConfig,
|
||||||
operations: Rc<Cell<usize>>,
|
operations: Rc<Cell<usize>>,
|
||||||
max_operations: usize,
|
max_operations: usize,
|
||||||
rng: Rc<RefCell<StdRng>>,
|
rng: Arc<Mutex<StdRng>>,
|
||||||
mut cx: TestAppContext,
|
mut cx: TestAppContext,
|
||||||
) -> impl Future<Output = (Self, TestAppContext)> {
|
) -> impl Future<Output = (Self, TestAppContext)> {
|
||||||
|
let files: Arc<Mutex<Vec<PathBuf>>> = Default::default();
|
||||||
|
|
||||||
// Set up a fake language server.
|
// Set up a fake language server.
|
||||||
language_server_config.set_fake_initializer(|fake_server| {
|
language_server_config.set_fake_initializer({
|
||||||
fake_server.handle_request::<lsp::request::Completion, _>(|_| {
|
let rng = rng.clone();
|
||||||
Some(lsp::CompletionResponse::Array(vec![lsp::CompletionItem {
|
let files = files.clone();
|
||||||
text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
|
move |fake_server| {
|
||||||
range: lsp::Range::new(
|
fake_server.handle_request::<lsp::request::Completion, _>(|_| {
|
||||||
lsp::Position::new(0, 0),
|
Some(lsp::CompletionResponse::Array(vec![lsp::CompletionItem {
|
||||||
lsp::Position::new(0, 0),
|
text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
|
||||||
),
|
range: lsp::Range::new(
|
||||||
new_text: "the-new-text".to_string(),
|
lsp::Position::new(0, 0),
|
||||||
})),
|
lsp::Position::new(0, 0),
|
||||||
..Default::default()
|
),
|
||||||
}]))
|
new_text: "the-new-text".to_string(),
|
||||||
});
|
})),
|
||||||
|
|
||||||
fake_server.handle_request::<lsp::request::CodeActionRequest, _>(|_| {
|
|
||||||
Some(vec![lsp::CodeActionOrCommand::CodeAction(
|
|
||||||
lsp::CodeAction {
|
|
||||||
title: "the-code-action".to_string(),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
}]))
|
||||||
)])
|
});
|
||||||
});
|
|
||||||
|
|
||||||
fake_server.handle_request::<lsp::request::PrepareRenameRequest, _>(|params| {
|
fake_server.handle_request::<lsp::request::CodeActionRequest, _>(|_| {
|
||||||
Some(lsp::PrepareRenameResponse::Range(lsp::Range::new(
|
Some(vec![lsp::CodeActionOrCommand::CodeAction(
|
||||||
params.position,
|
lsp::CodeAction {
|
||||||
params.position,
|
title: "the-code-action".to_string(),
|
||||||
)))
|
..Default::default()
|
||||||
});
|
},
|
||||||
|
)])
|
||||||
|
});
|
||||||
|
|
||||||
|
fake_server.handle_request::<lsp::request::PrepareRenameRequest, _>(|params| {
|
||||||
|
Some(lsp::PrepareRenameResponse::Range(lsp::Range::new(
|
||||||
|
params.position,
|
||||||
|
params.position,
|
||||||
|
)))
|
||||||
|
});
|
||||||
|
|
||||||
|
fake_server.handle_request::<lsp::request::GotoDefinition, _>({
|
||||||
|
let files = files.clone();
|
||||||
|
let rng = rng.clone();
|
||||||
|
move |_| {
|
||||||
|
let files = files.lock();
|
||||||
|
let mut rng = rng.lock();
|
||||||
|
let count = rng.gen_range::<usize, _>(1..3);
|
||||||
|
Some(lsp::GotoDefinitionResponse::Array(
|
||||||
|
(0..count)
|
||||||
|
.map(|_| {
|
||||||
|
let file = files.choose(&mut *rng).unwrap().as_path();
|
||||||
|
lsp::Location {
|
||||||
|
uri: lsp::Url::from_file_path(file).unwrap(),
|
||||||
|
range: Default::default(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
project.update(&mut cx, |project, _| {
|
project.update(&mut cx, |project, _| {
|
||||||
|
@ -4282,17 +4309,17 @@ mod tests {
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let fs = project.read_with(&cx, |project, _| project.fs().clone());
|
let fs = project.read_with(&cx, |project, _| project.fs().clone());
|
||||||
let mut files: Vec<PathBuf> = Default::default();
|
|
||||||
while operations.get() < max_operations {
|
while operations.get() < max_operations {
|
||||||
operations.set(operations.get() + 1);
|
operations.set(operations.get() + 1);
|
||||||
|
|
||||||
let distribution = rng.borrow_mut().gen_range(0..100);
|
let distribution = rng.lock().gen_range::<usize, _>(0..100);
|
||||||
match distribution {
|
match distribution {
|
||||||
0..=20 if !files.is_empty() => {
|
0..=20 if !files.lock().is_empty() => {
|
||||||
let mut path = files.choose(&mut *rng.borrow_mut()).unwrap().as_path();
|
let path = files.lock().choose(&mut *rng.lock()).unwrap().clone();
|
||||||
|
let mut path = path.as_path();
|
||||||
while let Some(parent_path) = path.parent() {
|
while let Some(parent_path) = path.parent() {
|
||||||
path = parent_path;
|
path = parent_path;
|
||||||
if rng.borrow_mut().gen() {
|
if rng.lock().gen() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4305,9 +4332,9 @@ mod tests {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
10..=80 if !files.is_empty() => {
|
10..=80 if !files.lock().is_empty() => {
|
||||||
let buffer = if self.buffers.is_empty() || rng.borrow_mut().gen() {
|
let buffer = if self.buffers.is_empty() || rng.lock().gen() {
|
||||||
let file = files.choose(&mut *rng.borrow_mut()).unwrap();
|
let file = files.lock().choose(&mut *rng.lock()).unwrap().clone();
|
||||||
let (worktree, path) = project
|
let (worktree, path) = project
|
||||||
.update(&mut cx, |project, cx| {
|
.update(&mut cx, |project, cx| {
|
||||||
project.find_or_create_local_worktree(file, false, cx)
|
project.find_or_create_local_worktree(file, false, cx)
|
||||||
|
@ -4328,12 +4355,12 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
self.buffers
|
self.buffers
|
||||||
.iter()
|
.iter()
|
||||||
.choose(&mut *rng.borrow_mut())
|
.choose(&mut *rng.lock())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
if rng.borrow_mut().gen_bool(0.1) {
|
if rng.lock().gen_bool(0.1) {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
log::info!(
|
log::info!(
|
||||||
"Host: dropping buffer {:?}",
|
"Host: dropping buffer {:?}",
|
||||||
|
@ -4348,26 +4375,27 @@ mod tests {
|
||||||
"Host: updating buffer {:?}",
|
"Host: updating buffer {:?}",
|
||||||
buffer.file().unwrap().full_path(cx)
|
buffer.file().unwrap().full_path(cx)
|
||||||
);
|
);
|
||||||
buffer.randomly_edit(&mut *rng.borrow_mut(), 5, cx)
|
buffer.randomly_edit(&mut *rng.lock(), 5, cx)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => loop {
|
_ => loop {
|
||||||
let path_component_count = rng.borrow_mut().gen_range(1..=5);
|
let path_component_count = rng.lock().gen_range::<usize, _>(1..=5);
|
||||||
let mut path = PathBuf::new();
|
let mut path = PathBuf::new();
|
||||||
path.push("/");
|
path.push("/");
|
||||||
for _ in 0..path_component_count {
|
for _ in 0..path_component_count {
|
||||||
let letter = rng.borrow_mut().gen_range(b'a'..=b'z');
|
let letter = rng.lock().gen_range(b'a'..=b'z');
|
||||||
path.push(std::str::from_utf8(&[letter]).unwrap());
|
path.push(std::str::from_utf8(&[letter]).unwrap());
|
||||||
}
|
}
|
||||||
path.set_extension("rs");
|
path.set_extension("rs");
|
||||||
let parent_path = path.parent().unwrap();
|
let parent_path = path.parent().unwrap();
|
||||||
|
|
||||||
log::info!("Host: creating file {:?}", path);
|
log::info!("Host: creating file {:?}", path,);
|
||||||
|
|
||||||
if fs.create_dir(&parent_path).await.is_ok()
|
if fs.create_dir(&parent_path).await.is_ok()
|
||||||
&& fs.create_file(&path, Default::default()).await.is_ok()
|
&& fs.create_file(&path, Default::default()).await.is_ok()
|
||||||
{
|
{
|
||||||
files.push(path);
|
files.lock().push(path);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
log::info!("Host: cannot create file");
|
log::info!("Host: cannot create file");
|
||||||
|
@ -4389,18 +4417,18 @@ mod tests {
|
||||||
project: ModelHandle<Project>,
|
project: ModelHandle<Project>,
|
||||||
operations: Rc<Cell<usize>>,
|
operations: Rc<Cell<usize>>,
|
||||||
max_operations: usize,
|
max_operations: usize,
|
||||||
rng: Rc<RefCell<StdRng>>,
|
rng: Arc<Mutex<StdRng>>,
|
||||||
mut cx: TestAppContext,
|
mut cx: TestAppContext,
|
||||||
) -> (Self, TestAppContext) {
|
) -> (Self, TestAppContext) {
|
||||||
while operations.get() < max_operations {
|
while operations.get() < max_operations {
|
||||||
let buffer = if self.buffers.is_empty() || rng.borrow_mut().gen() {
|
let buffer = if self.buffers.is_empty() || rng.lock().gen() {
|
||||||
let worktree = if let Some(worktree) = project.read_with(&cx, |project, cx| {
|
let worktree = if let Some(worktree) = project.read_with(&cx, |project, cx| {
|
||||||
project
|
project
|
||||||
.worktrees(&cx)
|
.worktrees(&cx)
|
||||||
.filter(|worktree| {
|
.filter(|worktree| {
|
||||||
worktree.read(cx).entries(false).any(|e| e.is_file())
|
worktree.read(cx).entries(false).any(|e| e.is_file())
|
||||||
})
|
})
|
||||||
.choose(&mut *rng.borrow_mut())
|
.choose(&mut *rng.lock())
|
||||||
}) {
|
}) {
|
||||||
worktree
|
worktree
|
||||||
} else {
|
} else {
|
||||||
|
@ -4413,7 +4441,7 @@ mod tests {
|
||||||
let entry = worktree
|
let entry = worktree
|
||||||
.entries(false)
|
.entries(false)
|
||||||
.filter(|e| e.is_file())
|
.filter(|e| e.is_file())
|
||||||
.choose(&mut *rng.borrow_mut())
|
.choose(&mut *rng.lock())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(worktree.id(), entry.path.clone())
|
(worktree.id(), entry.path.clone())
|
||||||
});
|
});
|
||||||
|
@ -4429,12 +4457,12 @@ mod tests {
|
||||||
|
|
||||||
self.buffers
|
self.buffers
|
||||||
.iter()
|
.iter()
|
||||||
.choose(&mut *rng.borrow_mut())
|
.choose(&mut *rng.lock())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let choice = rng.borrow_mut().gen_range(0..100);
|
let choice = rng.lock().gen_range(0..100);
|
||||||
match choice {
|
match choice {
|
||||||
0..=9 => {
|
0..=9 => {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
|
@ -4454,13 +4482,13 @@ mod tests {
|
||||||
guest_id,
|
guest_id,
|
||||||
buffer.read(cx).file().unwrap().full_path(cx)
|
buffer.read(cx).file().unwrap().full_path(cx)
|
||||||
);
|
);
|
||||||
let offset = rng.borrow_mut().gen_range(0..=buffer.read(cx).len());
|
let offset = rng.lock().gen_range(0..=buffer.read(cx).len());
|
||||||
project.completions(&buffer, offset, cx)
|
project.completions(&buffer, offset, cx)
|
||||||
});
|
});
|
||||||
let completions = cx.background().spawn(async move {
|
let completions = cx.background().spawn(async move {
|
||||||
completions.await.expect("completions request failed");
|
completions.await.expect("completions request failed");
|
||||||
});
|
});
|
||||||
if rng.borrow_mut().gen_bool(0.3) {
|
if rng.lock().gen_bool(0.3) {
|
||||||
log::info!("Guest {}: detaching completions request", guest_id);
|
log::info!("Guest {}: detaching completions request", guest_id);
|
||||||
completions.detach();
|
completions.detach();
|
||||||
} else {
|
} else {
|
||||||
|
@ -4474,14 +4502,13 @@ mod tests {
|
||||||
guest_id,
|
guest_id,
|
||||||
buffer.read(cx).file().unwrap().full_path(cx)
|
buffer.read(cx).file().unwrap().full_path(cx)
|
||||||
);
|
);
|
||||||
let range =
|
let range = buffer.read(cx).random_byte_range(0, &mut *rng.lock());
|
||||||
buffer.read(cx).random_byte_range(0, &mut *rng.borrow_mut());
|
|
||||||
project.code_actions(&buffer, range, cx)
|
project.code_actions(&buffer, range, cx)
|
||||||
});
|
});
|
||||||
let code_actions = cx.background().spawn(async move {
|
let code_actions = cx.background().spawn(async move {
|
||||||
code_actions.await.expect("code actions request failed");
|
code_actions.await.expect("code actions request failed");
|
||||||
});
|
});
|
||||||
if rng.borrow_mut().gen_bool(0.3) {
|
if rng.lock().gen_bool(0.3) {
|
||||||
log::info!("Guest {}: detaching code actions request", guest_id);
|
log::info!("Guest {}: detaching code actions request", guest_id);
|
||||||
code_actions.detach();
|
code_actions.detach();
|
||||||
} else {
|
} else {
|
||||||
|
@ -4504,7 +4531,7 @@ mod tests {
|
||||||
assert!(saved_version.observed_all(&requested_version));
|
assert!(saved_version.observed_all(&requested_version));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if rng.borrow_mut().gen_bool(0.3) {
|
if rng.lock().gen_bool(0.3) {
|
||||||
log::info!("Guest {}: detaching save request", guest_id);
|
log::info!("Guest {}: detaching save request", guest_id);
|
||||||
save.detach();
|
save.detach();
|
||||||
} else {
|
} else {
|
||||||
|
@ -4518,19 +4545,39 @@ mod tests {
|
||||||
guest_id,
|
guest_id,
|
||||||
buffer.read(cx).file().unwrap().full_path(cx)
|
buffer.read(cx).file().unwrap().full_path(cx)
|
||||||
);
|
);
|
||||||
let offset = rng.borrow_mut().gen_range(0..=buffer.read(cx).len());
|
let offset = rng.lock().gen_range(0..=buffer.read(cx).len());
|
||||||
project.prepare_rename(buffer, offset, cx)
|
project.prepare_rename(buffer, offset, cx)
|
||||||
});
|
});
|
||||||
let prepare_rename = cx.background().spawn(async move {
|
let prepare_rename = cx.background().spawn(async move {
|
||||||
prepare_rename.await.expect("prepare rename request failed");
|
prepare_rename.await.expect("prepare rename request failed");
|
||||||
});
|
});
|
||||||
if rng.borrow_mut().gen_bool(0.3) {
|
if rng.lock().gen_bool(0.3) {
|
||||||
log::info!("Guest {}: detaching prepare rename request", guest_id);
|
log::info!("Guest {}: detaching prepare rename request", guest_id);
|
||||||
prepare_rename.detach();
|
prepare_rename.detach();
|
||||||
} else {
|
} else {
|
||||||
prepare_rename.await;
|
prepare_rename.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46..=49 => {
|
||||||
|
let definitions = project.update(&mut cx, |project, cx| {
|
||||||
|
log::info!(
|
||||||
|
"Guest {}: requesting defintions for buffer {:?}",
|
||||||
|
guest_id,
|
||||||
|
buffer.read(cx).file().unwrap().full_path(cx)
|
||||||
|
);
|
||||||
|
let offset = rng.lock().gen_range(0..=buffer.read(cx).len());
|
||||||
|
project.definition(&buffer, offset, cx)
|
||||||
|
});
|
||||||
|
let definitions = cx.background().spawn(async move {
|
||||||
|
definitions.await.expect("definitions request failed");
|
||||||
|
});
|
||||||
|
if rng.lock().gen_bool(0.3) {
|
||||||
|
log::info!("Guest {}: detaching definitions request", guest_id);
|
||||||
|
definitions.detach();
|
||||||
|
} else {
|
||||||
|
definitions.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
buffer.update(&mut cx, |buffer, cx| {
|
buffer.update(&mut cx, |buffer, cx| {
|
||||||
log::info!(
|
log::info!(
|
||||||
|
@ -4538,7 +4585,7 @@ mod tests {
|
||||||
guest_id,
|
guest_id,
|
||||||
buffer.file().unwrap().full_path(cx)
|
buffer.file().unwrap().full_path(cx)
|
||||||
);
|
);
|
||||||
buffer.randomly_edit(&mut *rng.borrow_mut(), 5, cx)
|
buffer.randomly_edit(&mut *rng.lock(), 5, cx)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue