Add random delays in FakeFs

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2022-01-24 16:50:38 -08:00
parent 2b8685c1a2
commit 0cfb9ff1ae
6 changed files with 30 additions and 21 deletions

View file

@ -181,11 +181,12 @@ impl FakeFsState {
pub struct FakeFs {
// Use an unfair lock to ensure tests are deterministic.
state: futures::lock::Mutex<FakeFsState>,
executor: std::sync::Arc<gpui::executor::Background>,
}
#[cfg(any(test, feature = "test-support"))]
impl FakeFs {
pub fn new() -> Self {
pub fn new(executor: std::sync::Arc<gpui::executor::Background>) -> Self {
let (events_tx, _) = postage::broadcast::channel(2048);
let mut entries = std::collections::BTreeMap::new();
entries.insert(
@ -201,6 +202,7 @@ impl FakeFs {
},
);
Self {
executor,
state: futures::lock::Mutex::new(FakeFsState {
entries,
next_inode: 1,
@ -330,6 +332,7 @@ impl FakeFs {
#[async_trait::async_trait]
impl Fs for FakeFs {
async fn load(&self, path: &Path) -> Result<String> {
self.executor.simulate_random_delay().await;
let state = self.state.lock().await;
let text = state
.entries
@ -340,6 +343,7 @@ impl Fs for FakeFs {
}
async fn save(&self, path: &Path, text: &Rope) -> Result<()> {
self.executor.simulate_random_delay().await;
let mut state = self.state.lock().await;
state.validate_path(path)?;
if let Some(entry) = state.entries.get_mut(path) {
@ -370,10 +374,12 @@ impl Fs for FakeFs {
}
async fn canonicalize(&self, path: &Path) -> Result<PathBuf> {
self.executor.simulate_random_delay().await;
Ok(path.to_path_buf())
}
async fn is_file(&self, path: &Path) -> bool {
self.executor.simulate_random_delay().await;
let state = self.state.lock().await;
state
.entries
@ -382,6 +388,7 @@ impl Fs for FakeFs {
}
async fn metadata(&self, path: &Path) -> Result<Option<Metadata>> {
self.executor.simulate_random_delay().await;
let state = self.state.lock().await;
Ok(state.entries.get(path).map(|entry| entry.metadata.clone()))
}
@ -391,6 +398,7 @@ impl Fs for FakeFs {
abs_path: &Path,
) -> Result<Pin<Box<dyn Send + Stream<Item = Result<PathBuf>>>>> {
use futures::{future, stream};
self.executor.simulate_random_delay().await;
let state = self.state.lock().await;
let abs_path = abs_path.to_path_buf();
Ok(Box::pin(stream::iter(state.entries.clone()).filter_map(
@ -410,6 +418,7 @@ impl Fs for FakeFs {
_: Duration,
) -> Pin<Box<dyn Send + Stream<Item = Vec<fsevent::Event>>>> {
let state = self.state.lock().await;
self.executor.simulate_random_delay().await;
let rx = state.events_tx.subscribe();
let path = path.to_path_buf();
Box::pin(futures::StreamExt::filter(rx, move |events| {

View file

@ -2439,7 +2439,7 @@ mod tests {
#[gpui::test]
async fn test_save_file(mut cx: gpui::TestAppContext) {
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx.background()));
fs.insert_tree(
"/dir",
json!({
@ -2477,7 +2477,7 @@ mod tests {
#[gpui::test]
async fn test_save_in_single_file_worktree(mut cx: gpui::TestAppContext) {
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx.background()));
fs.insert_tree(
"/dir",
json!({
@ -2664,7 +2664,7 @@ mod tests {
#[gpui::test]
async fn test_buffer_deduping(mut cx: gpui::TestAppContext) {
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx.background()));
fs.insert_tree(
"/the-dir",
json!({
@ -2953,7 +2953,7 @@ mod tests {
#[gpui::test]
async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx.background()));
fs.insert_tree(
"/the-dir",
json!({

View file

@ -2432,7 +2432,7 @@ mod tests {
#[gpui::test]
async fn test_traversal(cx: gpui::TestAppContext) {
let fs = FakeFs::new();
let fs = FakeFs::new(cx.background());
fs.insert_tree(
"/root",
json!({

View file

@ -1201,7 +1201,7 @@ mod tests {
async fn test_share_project(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
let (window_b, _) = cx_b.add_window(|_| EmptyView);
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
cx_a.foreground().forbid_parking();
// Connect to a server as 2 clients.
@ -1339,7 +1339,7 @@ mod tests {
#[gpui::test]
async fn test_unshare_project(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
cx_a.foreground().forbid_parking();
// Connect to a server as 2 clients.
@ -1440,7 +1440,7 @@ mod tests {
mut cx_c: TestAppContext,
) {
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
cx_a.foreground().forbid_parking();
// Connect to a server as 3 clients.
@ -1623,7 +1623,7 @@ mod tests {
async fn test_buffer_conflict_after_save(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
cx_a.foreground().forbid_parking();
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Connect to a server as 2 clients.
let mut server = TestServer::start(cx_a.foreground()).await;
@ -1716,7 +1716,7 @@ mod tests {
async fn test_buffer_reloading(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
cx_a.foreground().forbid_parking();
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Connect to a server as 2 clients.
let mut server = TestServer::start(cx_a.foreground()).await;
@ -1801,7 +1801,7 @@ mod tests {
) {
cx_a.foreground().forbid_parking();
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Connect to a server as 2 clients.
let mut server = TestServer::start(cx_a.foreground()).await;
@ -1881,7 +1881,7 @@ mod tests {
) {
cx_a.foreground().forbid_parking();
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Connect to a server as 2 clients.
let mut server = TestServer::start(cx_a.foreground()).await;
@ -1956,7 +1956,7 @@ mod tests {
async fn test_peer_disconnection(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
cx_a.foreground().forbid_parking();
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Connect to a server as 2 clients.
let mut server = TestServer::start(cx_a.foreground()).await;
@ -2030,7 +2030,7 @@ mod tests {
) {
cx_a.foreground().forbid_parking();
let mut lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Set up a fake language server.
let (language_server_config, mut fake_language_server) =
@ -2251,7 +2251,7 @@ mod tests {
async fn test_formatting_buffer(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
cx_a.foreground().forbid_parking();
let mut lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Set up a fake language server.
let (language_server_config, mut fake_language_server) =
@ -2355,7 +2355,7 @@ mod tests {
async fn test_definition(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
cx_a.foreground().forbid_parking();
let mut lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
fs.insert_tree(
"/root-1",
json!({
@ -2516,7 +2516,7 @@ mod tests {
) {
cx_a.foreground().forbid_parking();
let mut lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
fs.insert_tree(
"/root",
json!({
@ -3042,7 +3042,7 @@ mod tests {
) {
cx_a.foreground().forbid_parking();
let lang_registry = Arc::new(LanguageRegistry::new());
let fs = Arc::new(FakeFs::new());
let fs = Arc::new(FakeFs::new(cx_a.background()));
// Connect to a server as 3 clients.
let mut server = TestServer::start(cx_a.foreground()).await;

View file

@ -490,7 +490,7 @@ pub struct WorkspaceParams {
impl WorkspaceParams {
#[cfg(any(test, feature = "test-support"))]
pub fn test(cx: &mut MutableAppContext) -> Self {
let fs = Arc::new(project::FakeFs::new());
let fs = Arc::new(project::FakeFs::new(cx.background().clone()));
let languages = Arc::new(LanguageRegistry::new());
let http_client = client::test::FakeHttpClient::new(|_| async move {
Ok(client::http::ServerResponse::new(404))

View file

@ -40,7 +40,7 @@ pub fn test_app_state(cx: &mut MutableAppContext) -> Arc<AppState> {
channel_list: cx.add_model(|cx| ChannelList::new(user_store.clone(), client.clone(), cx)),
client,
user_store,
fs: Arc::new(FakeFs::new()),
fs: Arc::new(FakeFs::new(cx.background().clone())),
path_openers: Arc::from(path_openers),
build_window_options: &build_window_options,
build_workspace: &build_workspace,