c90c85bd5b3dfd0b175305a89d034c1c0b865068
[idea/community.git] / platform / platform-tests / testSrc / com / intellij / openapi / vfs / VfsUtilTest.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.vfs;
17
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.application.Result;
20 import com.intellij.openapi.application.WriteAction;
21 import com.intellij.openapi.application.ex.PathManagerEx;
22 import com.intellij.openapi.util.SystemInfo;
23 import com.intellij.openapi.util.io.FileUtil;
24 import com.intellij.openapi.util.io.IoTestUtil;
25 import com.intellij.openapi.vfs.newvfs.ManagingFS;
26 import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
27 import com.intellij.testFramework.PlatformTestCase;
28 import com.intellij.testFramework.UsefulTestCase;
29 import com.intellij.testFramework.vcs.DirectoryData;
30 import com.intellij.util.ThrowableRunnable;
31 import com.intellij.util.TimeoutUtil;
32 import com.intellij.util.concurrency.Semaphore;
33 import org.jetbrains.annotations.NotNull;
34
35 import java.io.File;
36 import java.io.IOException;
37 import java.net.URI;
38 import java.net.URL;
39 import java.nio.charset.Charset;
40 import java.util.Collections;
41 import java.util.List;
42
43 public class VfsUtilTest extends PlatformTestCase {
44   @Override
45   protected boolean isRunInEdt() {
46     return false;
47   }
48
49   @Override
50   protected boolean isRunInWriteAction() {
51     return false;
52   }
53
54   @Override
55   protected void setUp() throws Exception {
56     invokeAndWaitIfNeeded(new ThrowableRunnable<Exception>() {
57       @Override
58       public void run() throws Exception {
59         VfsUtilTest.super.setUp();
60       }
61     });
62   }
63
64   @Override
65   protected void tearDown() throws Exception {
66     invokeAndWaitIfNeeded(new ThrowableRunnable<Exception>() {
67       @Override
68       public void run() throws Exception {
69         VfsUtilTest.super.tearDown();
70       }
71     });
72   }
73
74   public void testFixIdeaUrl() {
75     assertEquals("file:/C:/Temp/README.txt", VfsUtilCore.fixIDEAUrl("file://C:/Temp/README.txt"));
76     assertEquals("file:/C:/Temp/README.txt", VfsUtilCore.fixIDEAUrl("file:///C:/Temp/README.txt"));
77     assertEquals("file:/tmp/foo.bar", VfsUtilCore.fixIDEAUrl("file:///tmp/foo.bar"));
78   }
79
80   public void testFindFileByUrl() throws Exception {
81     File file1 = new File(PathManagerEx.getTestDataPath());
82     file1 = new File(file1, "vfs");
83     file1 = new File(file1, "findFileByUrl");
84     VirtualFile file0 = VfsUtil.findFileByURL(file1.toURI().toURL());
85     assertNotNull(file0);
86     assertTrue(file0.isDirectory());
87     List<VirtualFile> list = VfsUtil.getChildren(file0, new VirtualFileFilter() {
88       @Override
89       public boolean accept(VirtualFile file) {
90         return !file.getName().endsWith(".new");
91       }
92     });
93     assertEquals(2, list.size());     // "CVS" dir ignored
94
95     File file2 = new File(file1, "test.zip");
96     URL url2 = file2.toURI().toURL();
97
98     url2 = new URL("jar", "", url2.toExternalForm() + "!/");
99     file0 = VfsUtil.findFileByURL(url2);
100     assertNotNull(file0);
101     assertTrue(file0.isDirectory());
102
103     url2 = new URL(url2, "com/intellij/installer");
104     file0 = VfsUtil.findFileByURL(url2);
105     assertNotNull(file0);
106     assertTrue(file0.isDirectory());
107
108     File file3 = new File(file1, "1.txt");
109     file0 = VfsUtil.findFileByURL(file3.toURI().toURL());
110     String content = VfsUtilCore.loadText(file0);
111     assertNotNull(file0);
112     assertFalse(file0.isDirectory());
113     assertEquals("test text", content);
114   }
115
116   public void testRelativePath() throws Exception {
117     final File root = new File(PathManagerEx.getTestDataPath());
118     final File testRoot = new File(new File(root, "vfs"), "relativePath");
119     VirtualFile vTestRoot = LocalFileSystem.getInstance().findFileByIoFile(testRoot);
120     assertNotNull(vTestRoot);
121     assertTrue(vTestRoot.isDirectory());
122
123     final File subDir = new File(testRoot, "subDir");
124     final VirtualFile vSubDir = LocalFileSystem.getInstance().findFileByIoFile(subDir);
125     assertNotNull(vSubDir);
126
127     final File subSubDir = new File(subDir, "subSubDir");
128     final VirtualFile vSubSubDir = LocalFileSystem.getInstance().findFileByIoFile(subSubDir);
129     assertNotNull(vSubSubDir);
130
131     assertEquals("subDir", VfsUtilCore.getRelativePath(vSubDir, vTestRoot, '/'));
132     assertEquals("subDir/subSubDir", VfsUtilCore.getRelativePath(vSubSubDir, vTestRoot, '/'));
133     assertEquals("", VfsUtilCore.getRelativePath(vTestRoot, vTestRoot, '/'));
134   }
135
136   public void testVisitRecursively() throws Exception {
137     final DirectoryData data = new DirectoryData(myProject.getBaseDir());
138     try {
139       data.clear();
140       data.create();
141
142       final File subDir = new File(data.getBase().getPath(), "DL0N1");
143       final VirtualFile vSubDir = LocalFileSystem.getInstance().findFileByIoFile(subDir);
144       assertNotNull(vSubDir);
145
146       VfsUtilCore.visitChildrenRecursively(data.getBase(), new VirtualFileVisitor() {
147         @Override
148         public boolean visitFile(@NotNull VirtualFile file) {
149           assertTrue(!VfsUtilCore.isAncestor(vSubDir, file, true));
150           return !vSubDir.equals(file);
151         }
152       });
153     }
154     finally {
155       data.clear();
156     }
157   }
158
159   public void testFindChildWithTrailingSpace() throws IOException {
160     File tempDir = createTempDirectory();
161     VirtualFile vDir = LocalFileSystem.getInstance().findFileByIoFile(tempDir);
162     assertNotNull(vDir);
163     assertTrue(vDir.isDirectory());
164
165     VirtualFile child = vDir.findChild(" ");
166     assertNull(child);
167
168     UsefulTestCase.assertEmpty(vDir.getChildren());
169   }
170
171   public void testDirAttributeRefreshes() throws IOException {
172     File tempDir = createTempDirectory();
173     VirtualFile vDir = refreshAndFindFile(tempDir);
174     assertNotNull(vDir);
175     assertTrue(vDir.isDirectory());
176
177     File file = FileUtil.createTempFile(tempDir, "xxx", "yyy", true);
178     assertNotNull(file);
179     VirtualFile vFile = refreshAndFindFile(file);
180     assertNotNull(vFile);
181     assertFalse(vFile.isDirectory());
182
183     boolean deleted = file.delete();
184     assertTrue(deleted);
185     boolean created = file.mkdir();
186     assertTrue(created);
187     assertTrue(file.exists());
188
189     VirtualFile vFile2 = refreshAndFindFile(file);
190     assertNotNull(vFile2);
191     assertTrue(vFile2.isDirectory());
192   }
193
194   public void testPresentableUrlSurvivesDeletion() throws IOException {
195     final VirtualFile file = createTempFile("txt", null, "content", Charset.defaultCharset());
196     String url = file.getPresentableUrl();
197     assertNotNull(url);
198     new WriteAction() {
199       @Override
200       protected void run(@NotNull Result result) throws Throwable {
201         file.delete(this);
202       }
203     }.execute();
204     assertEquals(url, file.getPresentableUrl());
205   }
206
207   public void testToUri() {
208     if (!SystemInfo.isWindows) {
209       assertEquals("file:///asd", VfsUtil.toUri(new File("/asd")).toASCIIString());
210       assertEquals("file:///asd%20/sd", VfsUtil.toUri(new File("/asd /sd")).toASCIIString());
211     }
212
213     URI uri = VfsUtil.toUri("file:///asd");
214     assertNotNull(uri);
215     assertEquals("file", uri.getScheme());
216     assertEquals("/asd", uri.getPath());
217
218     uri = VfsUtil.toUri("file:///asd/ ads/ad#test");
219     assertNotNull(uri);
220     assertEquals("file", uri.getScheme());
221     assertEquals("/asd/ ads/ad", uri.getPath());
222     assertEquals("test", uri.getFragment());
223
224     uri = VfsUtil.toUri("file:///asd/ ads/ad#");
225     assertNotNull(uri);
226     assertEquals("file:///asd/%20ads/ad#", uri.toString());
227
228     uri = VfsUtil.toUri("mailto:someone@example.com");
229     assertNotNull(uri);
230     assertEquals("someone@example.com", uri.getSchemeSpecificPart());
231
232     if (SystemInfo.isWindows) {
233       uri = VfsUtil.toUri("file://C:/p");
234       assertNotNull(uri);
235       assertEquals("file", uri.getScheme());
236       assertEquals("/C:/p", uri.getPath());
237     }
238
239     uri = VfsUtil.toUri("file:///Users/S pace");
240     assertNotNull(uri);
241     assertEquals("file", uri.getScheme());
242     assertEquals("/Users/S pace", uri.getPath());
243     assertEquals("/Users/S%20pace", uri.getRawPath());
244     assertEquals("file:///Users/S%20pace", uri.toString());
245
246     uri = VfsUtil.toUri("http://developer.android.com/guide/developing/tools/avd.html");
247     assertNotNull(uri);
248     assertEquals("http", uri.getScheme());
249     assertEquals("/guide/developing/tools/avd.html", uri.getRawPath());
250     assertEquals("http://developer.android.com/guide/developing/tools/avd.html", uri.toString());
251
252     uri = VfsUtil.toUri("http://developer.android.com/guide/developing/tools/avd.html?f=23r2ewd");
253     assertNotNull(uri);
254     assertEquals("http", uri.getScheme());
255     assertEquals("/guide/developing/tools/avd.html", uri.getRawPath());
256     assertEquals("http://developer.android.com/guide/developing/tools/avd.html?f=23r2ewd", uri.toString());
257     assertEquals("f=23r2ewd", uri.getQuery());
258   }
259
260   public void testIsAncestor() {
261     assertTrue(VfsUtilCore.isEqualOrAncestor("file:///my/dir", "file:///my/dir"));
262     assertTrue(VfsUtilCore.isEqualOrAncestor("file:///my/dir", "file:///my/dir/file.txt"));
263     assertTrue(VfsUtilCore.isEqualOrAncestor("file:///my/dir/", "file:///my/dir/file.txt"));
264     assertFalse(VfsUtilCore.isEqualOrAncestor("file:///my/dir2", "file:///my/dir/file.txt"));
265     assertFalse(VfsUtilCore.isEqualOrAncestor("file:///my/dir", "file:///my/dir2"));
266     assertFalse(VfsUtilCore.isEqualOrAncestor("file:///my/dir/", "file:///my/dir2"));
267   }
268
269   public void testFindRootWithDenormalizedPath() throws IOException {
270     File tempJar = IoTestUtil.createTestJar();
271     VirtualFile jar = refreshAndFindFile(tempJar);
272     assertNotNull(jar);
273
274     JarFileSystem fs = JarFileSystem.getInstance();
275     NewVirtualFile root1 = ManagingFS.getInstance().findRoot(jar.getPath() + "!/", fs);
276     NewVirtualFile root2 = ManagingFS.getInstance().findRoot(jar.getParent().getPath() + "//" + jar.getName() + "!/", fs);
277     assertNotNull(root1);
278     assertSame(root1, root2);
279   }
280
281   public void testNotCanonicallyNamedChild() throws IOException {
282     File tempDir = createTempDirectory();
283     assertTrue(new File(tempDir, "libFiles").createNewFile());
284     assertTrue(new File(tempDir, "CssInvalidElement").createNewFile());
285     assertTrue(new File(tempDir, "extFiles").createNewFile());
286
287     VirtualFile vDir = refreshAndFindFile(tempDir);
288     assertNotNull(vDir);
289     assertTrue(vDir.isDirectory());
290
291     assertNotNull(vDir.findChild("libFiles"));
292     assertNotNull(vDir.findChild("CssInvalidElement"));
293
294     assertNotNull(vDir.findChild("extFiles"));
295     assertNotNull(vDir.findChild("/extFiles/"));
296     assertNotNull(vDir.findChild("extFiles/"));
297     assertNotNull(vDir.findChild("/extFiles"));
298     assertNotNull(vDir.findChild("//extFiles"));
299     assertNotNull(vDir.findChild("extFiles///"));
300
301     assertNull(vDir.findChild("/xxx/extFiles/"));
302     assertNull(vDir.findChild("xxx/extFiles/"));
303     assertNull(vDir.findChild("/xxx/extFiles"));
304     assertNull(vDir.findChild("xxx/extFiles"));
305     assertNull(vDir.findChild("xxx//extFiles"));
306   }
307
308   public void testRenameDuringFullRefresh() throws IOException { doRenameAndRefreshTest(true); }
309   public void testRenameDuringPartialRefresh() throws IOException { doRenameAndRefreshTest(false); }
310
311   private void doRenameAndRefreshTest(boolean full) throws IOException {
312     assertFalse(ApplicationManager.getApplication().isDispatchThread());
313
314     File tempDir = createTempDirectory();
315     assertTrue(new File(tempDir, "child").createNewFile());
316
317     VirtualFile parent = refreshAndFindFile(tempDir);
318     assertNotNull(parent);
319     if (full) {
320       assertEquals(1, parent.getChildren().length);
321     }
322     final VirtualFile child = parent.findChild("child");
323     assertNotNull(child);
324
325     List<VirtualFile> files = Collections.singletonList(parent);
326
327     final Semaphore semaphore = new Semaphore();
328     for (int i = 0; i < 1000; i++) {
329       semaphore.down();
330       VfsUtil.markDirty(true, false, parent);
331       LocalFileSystem.getInstance().refreshFiles(files, true, true, new Runnable() {
332         @Override
333         public void run() {
334           semaphore.up();
335         }
336       });
337
338       assertTrue(child.isValid());
339       final String newName = "name" + i;
340       new WriteAction() {
341         @Override
342         protected void run(@NotNull Result result) throws Throwable {
343           child.rename(this, newName);
344         }
345       }.execute();
346       assertTrue(child.isValid());
347
348       TimeoutUtil.sleep(1);  // needed to prevent frequent event detector from triggering
349     }
350
351     assertTrue(semaphore.waitFor(60000));
352   }
353 }