Assert that buffers' file state matches in randomized collab test

Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2022-12-21 15:38:44 -08:00
parent 89da738fae
commit c321f5d94a
7 changed files with 31 additions and 12 deletions

View file

@ -356,6 +356,19 @@ async fn test_random_collaboration(
buffer_id, buffer_id,
path path
); );
let host_file = host_buffer.read_with(host_cx, |b, _| b.file().cloned());
let guest_file = guest_buffer.read_with(client_cx, |b, _| b.file().cloned());
match (host_file, guest_file) {
(Some(host_file), Some(guest_file)) => {
assert_eq!(host_file.mtime(), guest_file.mtime());
assert_eq!(host_file.path(), guest_file.path());
assert_eq!(host_file.is_deleted(), guest_file.is_deleted());
}
(None, None) => {}
(None, _) => panic!("host's file is None, guest's isn't "),
(_, None) => panic!("guest's file is None, hosts's isn't "),
}
} }
} }
} }

View file

@ -1114,7 +1114,7 @@ fn path_for_buffer<'a>(
cx: &'a AppContext, cx: &'a AppContext,
) -> Option<Cow<'a, Path>> { ) -> Option<Cow<'a, Path>> {
let file = buffer.read(cx).as_singleton()?.read(cx).file()?; let file = buffer.read(cx).as_singleton()?.read(cx).file()?;
path_for_file(file, height, include_filename, cx) path_for_file(file.as_ref(), height, include_filename, cx)
} }
fn path_for_file<'a>( fn path_for_file<'a>(

View file

@ -1311,7 +1311,7 @@ impl MultiBuffer {
.and_then(|(buffer, offset)| buffer.read(cx).language_at(offset)) .and_then(|(buffer, offset)| buffer.read(cx).language_at(offset))
} }
pub fn files<'a>(&'a self, cx: &'a AppContext) -> SmallVec<[&'a dyn File; 2]> { pub fn files<'a>(&'a self, cx: &'a AppContext) -> SmallVec<[&'a Arc<dyn File>; 2]> {
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
buffers buffers
.values() .values()

View file

@ -23,7 +23,7 @@ use std::{
time::{Duration, SystemTime}, time::{Duration, SystemTime},
}; };
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use util::ResultExt; use util::{post_inc, ResultExt};
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
use collections::{btree_map, BTreeMap}; use collections::{btree_map, BTreeMap};
@ -389,6 +389,7 @@ pub struct FakeFs {
struct FakeFsState { struct FakeFsState {
root: Arc<Mutex<FakeFsEntry>>, root: Arc<Mutex<FakeFsEntry>>,
next_inode: u64, next_inode: u64,
next_mtime: SystemTime,
event_txs: Vec<smol::channel::Sender<Vec<fsevent::Event>>>, event_txs: Vec<smol::channel::Sender<Vec<fsevent::Event>>>,
} }
@ -521,6 +522,7 @@ impl FakeFs {
entries: Default::default(), entries: Default::default(),
git_repo_state: None, git_repo_state: None,
})), })),
next_mtime: SystemTime::UNIX_EPOCH,
next_inode: 1, next_inode: 1,
event_txs: Default::default(), event_txs: Default::default(),
}), }),
@ -531,10 +533,12 @@ impl FakeFs {
let mut state = self.state.lock().await; let mut state = self.state.lock().await;
let path = path.as_ref(); let path = path.as_ref();
let inode = state.next_inode; let inode = state.next_inode;
let mtime = state.next_mtime;
state.next_inode += 1; state.next_inode += 1;
state.next_mtime += Duration::from_millis(1);
let file = Arc::new(Mutex::new(FakeFsEntry::File { let file = Arc::new(Mutex::new(FakeFsEntry::File {
inode, inode,
mtime: SystemTime::now(), mtime,
content, content,
})); }));
state state
@ -816,6 +820,9 @@ impl Fs for FakeFs {
let source = normalize_path(source); let source = normalize_path(source);
let target = normalize_path(target); let target = normalize_path(target);
let mut state = self.state.lock().await; let mut state = self.state.lock().await;
let mtime = state.next_mtime;
let inode = post_inc(&mut state.next_inode);
state.next_mtime += Duration::from_millis(1);
let source_entry = state.read_path(&source).await?; let source_entry = state.read_path(&source).await?;
let content = source_entry.lock().await.file_content(&source)?.clone(); let content = source_entry.lock().await.file_content(&source)?.clone();
let entry = state let entry = state
@ -831,8 +838,8 @@ impl Fs for FakeFs {
} }
btree_map::Entry::Vacant(e) => Ok(Some( btree_map::Entry::Vacant(e) => Ok(Some(
e.insert(Arc::new(Mutex::new(FakeFsEntry::File { e.insert(Arc::new(Mutex::new(FakeFsEntry::File {
inode: 0, inode,
mtime: SystemTime::now(), mtime,
content: String::new(), content: String::new(),
}))) })))
.clone(), .clone(),

View file

@ -514,8 +514,8 @@ impl Buffer {
self.text.snapshot() self.text.snapshot()
} }
pub fn file(&self) -> Option<&dyn File> { pub fn file(&self) -> Option<&Arc<dyn File>> {
self.file.as_deref() self.file.as_ref()
} }
pub fn save( pub fn save(
@ -2373,8 +2373,8 @@ impl BufferSnapshot {
self.selections_update_count self.selections_update_count
} }
pub fn file(&self) -> Option<&dyn File> { pub fn file(&self) -> Option<&Arc<dyn File>> {
self.file.as_deref() self.file.as_ref()
} }
pub fn resolve_file_path(&self, cx: &AppContext, include_root: bool) -> Option<PathBuf> { pub fn resolve_file_path(&self, cx: &AppContext, include_root: bool) -> Option<PathBuf> {

View file

@ -1981,7 +1981,7 @@ impl File {
}) })
} }
pub fn from_dyn(file: Option<&dyn language::File>) -> Option<&Self> { pub fn from_dyn(file: Option<&Arc<dyn language::File>>) -> Option<&Self> {
file.and_then(|f| f.as_any().downcast_ref()) file.and_then(|f| f.as_any().downcast_ref())
} }

View file

@ -170,7 +170,6 @@ message RejoinRoom {
uint64 id = 1; uint64 id = 1;
repeated UpdateProject reshared_projects = 2; repeated UpdateProject reshared_projects = 2;
repeated RejoinProject rejoined_projects = 3; repeated RejoinProject rejoined_projects = 3;
// relay open buffers and their vector clock
} }
message RejoinProject { message RejoinProject {