Add test coverage for FS events happening inside unloaded dirs

This commit is contained in:
Max Brunsfeld 2023-06-29 11:55:25 -07:00
parent ba80c53278
commit 8609ccdcf7
3 changed files with 43 additions and 20 deletions

View file

@ -388,6 +388,7 @@ struct FakeFsState {
event_txs: Vec<smol::channel::Sender<Vec<fsevent::Event>>>, event_txs: Vec<smol::channel::Sender<Vec<fsevent::Event>>>,
events_paused: bool, events_paused: bool,
buffered_events: Vec<fsevent::Event>, buffered_events: Vec<fsevent::Event>,
metadata_call_count: usize,
read_dir_call_count: usize, read_dir_call_count: usize,
} }
@ -538,6 +539,7 @@ impl FakeFs {
buffered_events: Vec::new(), buffered_events: Vec::new(),
events_paused: false, events_paused: false,
read_dir_call_count: 0, read_dir_call_count: 0,
metadata_call_count: 0,
}), }),
}) })
} }
@ -774,10 +776,16 @@ impl FakeFs {
result result
} }
/// How many `read_dir` calls have been issued.
pub fn read_dir_call_count(&self) -> usize { pub fn read_dir_call_count(&self) -> usize {
self.state.lock().read_dir_call_count self.state.lock().read_dir_call_count
} }
/// How many `metadata` calls have been issued.
pub fn metadata_call_count(&self) -> usize {
self.state.lock().metadata_call_count
}
async fn simulate_random_delay(&self) { async fn simulate_random_delay(&self) {
self.executor self.executor
.upgrade() .upgrade()
@ -1098,7 +1106,8 @@ impl Fs for FakeFs {
async fn metadata(&self, path: &Path) -> Result<Option<Metadata>> { async fn metadata(&self, path: &Path) -> Result<Option<Metadata>> {
self.simulate_random_delay().await; self.simulate_random_delay().await;
let path = normalize_path(path); let path = normalize_path(path);
let state = self.state.lock(); let mut state = self.state.lock();
state.metadata_call_count += 1;
if let Some((mut entry, _)) = state.try_read_path(&path, false) { if let Some((mut entry, _)) = state.try_read_path(&path, false) {
let is_symlink = entry.lock().is_symlink(); let is_symlink = entry.lock().is_symlink();
if is_symlink { if is_symlink {

View file

@ -3774,26 +3774,23 @@ impl BackgroundScanner {
// Scan any directories that were previously ignored and weren't // Scan any directories that were previously ignored and weren't
// previously scanned. // previously scanned.
if was_ignored if was_ignored && !entry.is_ignored && entry.kind.is_unloaded() {
&& !entry.is_ignored let state = self.state.lock();
&& !entry.is_external if state.should_scan_directory(&entry) {
&& entry.kind == EntryKind::UnloadedDir
{
job.scan_queue job.scan_queue
.try_send(ScanJob { .try_send(ScanJob {
abs_path: abs_path.clone(), abs_path: abs_path.clone(),
path: entry.path.clone(), path: entry.path.clone(),
ignore_stack: child_ignore_stack.clone(), ignore_stack: child_ignore_stack.clone(),
scan_queue: job.scan_queue.clone(), scan_queue: job.scan_queue.clone(),
ancestor_inodes: self ancestor_inodes: state
.state
.lock()
.snapshot .snapshot
.ancestor_inodes_for_path(&entry.path), .ancestor_inodes_for_path(&entry.path),
is_external: false, is_external: false,
}) })
.unwrap(); .unwrap();
} }
}
job.ignore_queue job.ignore_queue
.send(UpdateIgnoreStatusJob { .send(UpdateIgnoreStatusJob {

View file

@ -454,6 +454,10 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
"b1.js": "b1", "b1.js": "b1",
"b2.js": "b2", "b2.js": "b2",
}, },
"c": {
"c1.js": "c1",
"c2.js": "c2",
}
}, },
}, },
"two": { "two": {
@ -521,6 +525,7 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
(Path::new("one/node_modules/b"), true), (Path::new("one/node_modules/b"), true),
(Path::new("one/node_modules/b/b1.js"), true), (Path::new("one/node_modules/b/b1.js"), true),
(Path::new("one/node_modules/b/b2.js"), true), (Path::new("one/node_modules/b/b2.js"), true),
(Path::new("one/node_modules/c"), true),
(Path::new("two"), false), (Path::new("two"), false),
(Path::new("two/x.js"), false), (Path::new("two/x.js"), false),
(Path::new("two/y.js"), false), (Path::new("two/y.js"), false),
@ -564,6 +569,7 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
(Path::new("one/node_modules/b"), true), (Path::new("one/node_modules/b"), true),
(Path::new("one/node_modules/b/b1.js"), true), (Path::new("one/node_modules/b/b1.js"), true),
(Path::new("one/node_modules/b/b2.js"), true), (Path::new("one/node_modules/b/b2.js"), true),
(Path::new("one/node_modules/c"), true),
(Path::new("two"), false), (Path::new("two"), false),
(Path::new("two/x.js"), false), (Path::new("two/x.js"), false),
(Path::new("two/y.js"), false), (Path::new("two/y.js"), false),
@ -578,6 +584,17 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
// Only the newly-expanded directory is scanned. // Only the newly-expanded directory is scanned.
assert_eq!(fs.read_dir_call_count() - prev_read_dir_count, 1); assert_eq!(fs.read_dir_call_count() - prev_read_dir_count, 1);
}); });
// No work happens when files and directories change within an unloaded directory.
let prev_fs_call_count = fs.read_dir_call_count() + fs.metadata_call_count();
fs.create_dir("/root/one/node_modules/c/lib".as_ref())
.await
.unwrap();
cx.foreground().run_until_parked();
assert_eq!(
fs.read_dir_call_count() + fs.metadata_call_count() - prev_fs_call_count,
0
);
} }
#[gpui::test] #[gpui::test]