fix for iterating content of directories that were changed outside IDE

Reverting part of fa409e4 to ensure iterInDbChildren to load all children when
IDE loaded all children in previous sessions. The change allows VFS event
listeners to process all directory's children when handling directory deletion event.
This commit is contained in:
Maxim.Mossienko
2018-05-25 18:02:34 +02:00
parent 7f56a9dbd0
commit 8a33bd39e1
2 changed files with 63 additions and 6 deletions
@@ -299,13 +299,16 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
return Collections.emptyList();
}
if (!ourPersistence.areChildrenLoaded(this)) {
final String[] names = ourPersistence.listPersisted(this);
final NewVirtualFileSystem delegate = PersistentFS.replaceWithNativeFS(getFileSystem());
for (String name : names) {
findChild(name, false, false, delegate);
}
if (ourPersistence.areChildrenLoaded(this)) {
return Arrays.asList(getChildren());
}
final String[] names = ourPersistence.listPersisted(this);
final NewVirtualFileSystem delegate = PersistentFS.replaceWithNativeFS(getFileSystem());
for (String name : names) {
findChild(name, false, false, delegate);
}
return getCachedChildren();
}
@@ -187,6 +187,60 @@ public class PersistentFsTest extends PlatformTestCase {
assertEquals(1, logCount[0]);
}
public void testIterInDbChildrenWorksForRemovedDirsAfterRestart() throws IOException {
// test (re)creates <testName>/subDir/subSubDir/Foo.txt outside tested/watched project and checks removal events on subDir / subSubDir / Foo.txt
// test starts real testing ("after restart") after launching second time using same VFS
// hours spent writing this test: 4
VirtualFile projectStructure = createTestProjectStructure();
String testName = getTestName(false);
// wrt persistence subDir becomes partially loaded and subsubDir becomes fully loaded
File nestedDirOutsideTheProject = new File(projectStructure.getPath() + "../../../"+testName + "/subDir", "subSubDir");
Disposable disposable = null;
try {
boolean atleastSecondRun = nestedDirOutsideTheProject.getParentFile().getParentFile().exists();
StringBuilder eventLog = new StringBuilder();
if (atleastSecondRun) {
disposable = Disposer.newDisposable();
getProject().getMessageBus().connect(disposable).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
@Override
public void before(@NotNull List<? extends VFileEvent> events) {
for(VFileEvent event:events) {
if (event instanceof VFileDeleteEvent) process(((VFileDeleteEvent)event).getFile());
}
}
private void process(VirtualFile file) {
String path = file.getPath();
eventLog.append(path.substring(path.indexOf(testName) + testName.length() + 1)).append("\n");
Iterable<VirtualFile> files = ((NewVirtualFile)file).iterInDbChildren();
for(VirtualFile nested:files) process(nested);
}
});
}
// recreating structure will fire vfs removal events
VirtualFile nestedDirOutsideTheProjectFile = VfsUtil.createDirectories(nestedDirOutsideTheProject.getPath());
WriteAction.run(() -> nestedDirOutsideTheProjectFile.createChildData(null, "Foo.txt"));
// subsubDir becomes fully loaded wrt persistence
nestedDirOutsideTheProjectFile.getChildren();
if (atleastSecondRun) {
assertEquals("subDir\n" +
"subDir/subSubDir\n" +
"subDir/subSubDir/Foo.txt\n",
eventLog.toString()
);
}
} finally {
if (disposable != null) Disposer.dispose(disposable);
// remove <testName>/subDir via java.io to have vfs events on next test launch
FileUtil.delete(nestedDirOutsideTheProject.getParentFile());
}
}
public void testModCountIncreases() throws IOException {
VirtualFile vFile = setupFile();
ManagingFS managingFS = ManagingFS.getInstance();