| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package libcore.java.nio.file; |
| |
| import com.sun.nio.file.ExtendedWatchEventModifier; |
| |
| import java.nio.file.WatchEvent.Kind; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.nio.file.ClosedWatchServiceException; |
| import java.nio.file.FileSystems; |
| import java.nio.file.Files; |
| import java.nio.file.LinkOption; |
| import java.nio.file.NoSuchFileException; |
| import java.nio.file.NotDirectoryException; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.nio.file.WatchEvent; |
| import java.nio.file.WatchKey; |
| import java.nio.file.WatchService; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; |
| import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; |
| import static junit.framework.TestCase.assertFalse; |
| import static junit.framework.TestCase.assertNull; |
| import static junit.framework.TestCase.assertTrue; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.fail; |
| |
| public class LinuxPathTest { |
| |
| @Rule |
| public FilesSetup filesSetup = new FilesSetup(); |
| |
| /** |
| * CTS doesn't allow creating files in the test directory, however, Vogar allows creation of |
| * new files in the test directory. Therefore, for the tests which don't require write |
| * permission, fakePath would serve the purpose, however, for the others, {@link |
| * FilesSetup#getTestDirPath()} should be used. |
| */ |
| private static final Path fakePath = Paths.get("fakePath"); |
| |
| @Test |
| public void test_getFileSystem() { |
| assertTrue(fakePath.getFileSystem().provider() instanceof |
| sun.nio.fs.LinuxFileSystemProvider); |
| } |
| |
| @Test |
| public void test_isAbsolute() { |
| assertFalse(fakePath.isAbsolute()); |
| Path absolutePath = fakePath.toAbsolutePath(); |
| assertTrue(absolutePath.isAbsolute()); |
| } |
| |
| @Test |
| public void test_getRoot() { |
| assertEquals(Paths.get("/"), fakePath.toAbsolutePath().getRoot()); |
| assertNull(fakePath.getRoot()); |
| } |
| |
| @Test |
| public void test_getFileName() { |
| assertEquals(fakePath, fakePath.getFileName()); |
| assertEquals(fakePath, fakePath.toAbsolutePath().getFileName()); |
| assertNull(fakePath.getRoot()); |
| assertEquals(Paths.get("data"), Paths.get("/data").getFileName()); |
| assertEquals(Paths.get("data"), Paths.get("/data/").getFileName()); |
| assertEquals(Paths.get(".."), Paths.get("/data/dir1/..").getFileName()); |
| } |
| |
| @Test |
| public void test_getParent() { |
| assertNull(fakePath.getParent()); |
| assertEquals(Paths.get("rootDir"), Paths.get("rootDir/dir").getParent()); |
| } |
| |
| @Test |
| public void test_getNameCount() { |
| assertEquals(0, Paths.get("/").getNameCount()); |
| assertEquals(1, Paths.get("/dir").getNameCount()); |
| assertEquals(2, Paths.get("/dir/dir").getNameCount()); |
| assertEquals(2, Paths.get("/dir/..").getNameCount()); |
| } |
| |
| @Test |
| public void test_getName() { |
| assertEquals(Paths.get("t"), Paths.get("/t/t1/t2/t3").getName(0)); |
| assertEquals(Paths.get("t2"), Paths.get("/t/t1/t2/t3").getName(2)); |
| assertEquals(Paths.get("t3"), Paths.get("/t/t1/t2/t3").getName(3)); |
| |
| // Without root. |
| assertEquals(Paths.get("t3"), Paths.get("t/t1/t2/t3").getName(3)); |
| |
| // Invalid index. |
| try { |
| Paths.get("/t/t1/t2/t3").getName(4); |
| fail(); |
| } catch (IllegalArgumentException expected) {} |
| |
| // Negative index value. |
| try { |
| Paths.get("/t/t1/t2/t3").getName(-1); |
| fail(); |
| } catch (IllegalArgumentException expected) {} |
| } |
| |
| @Test |
| public void test_subPath() { |
| assertEquals(Paths.get("t1/t2"), Paths.get("t1/t2/t3").subpath(0, 2)); |
| assertEquals(Paths.get("t2"), Paths.get("t1/t2/t3").subpath(1, 2)); |
| |
| try { |
| Paths.get("t1/t2/t3").subpath(1, 1); |
| fail(); |
| } catch (IllegalArgumentException expected) {} |
| |
| try { |
| assertEquals(Paths.get("t1/t1"), Paths.get("t1/t2/t3").subpath(1, 0)); |
| fail(); |
| } catch (IllegalArgumentException expected) {} |
| |
| try { |
| assertEquals(Paths.get("t1/t1"), Paths.get("t1/t2/t3").subpath(1, 5)); |
| fail(); |
| } catch (IllegalArgumentException expected) {} |
| } |
| |
| @Test |
| public void test_startsWith$String() { |
| assertTrue(Paths.get("t1/t2").startsWith("t1")); |
| assertTrue(fakePath.toAbsolutePath().startsWith("/")); |
| assertTrue(Paths.get("t1/t2/t3").startsWith("t1/t2")); |
| assertFalse(Paths.get("t1/t2").startsWith("t2")); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_startsWith$String_NPE() { |
| filesSetup.getTestPath().startsWith((String) null); |
| } |
| |
| @Test |
| public void test_startsWith$Path() { |
| assertTrue(Paths.get("t1/t2").startsWith(Paths.get("t1"))); |
| assertTrue(fakePath.toAbsolutePath().startsWith(Paths.get("/"))); |
| assertTrue(Paths.get("t1/t2/t3").startsWith(Paths.get("t1/t2"))); |
| assertFalse(Paths.get("t1/t2").startsWith(Paths.get("t2"))); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_startsWith$Path_NPE() { |
| filesSetup.getTestPath().startsWith((Path) null); |
| } |
| |
| @Test |
| public void test_endsWith$Path() { |
| assertTrue(Paths.get("t1/t2").endsWith(Paths.get("t2"))); |
| assertTrue(Paths.get("t1/t2/t3").endsWith(Paths.get("t2/t3"))); |
| assertFalse(Paths.get("t1/t2").endsWith(Paths.get("t1"))); |
| assertTrue(Paths.get("/").endsWith(Paths.get("/"))); |
| assertFalse(Paths.get("/data/").endsWith(Paths.get("/"))); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_endsWith$Path_NPE() { |
| filesSetup.getTestPath().endsWith((Path)null); |
| } |
| |
| @Test |
| public void test_endsWith$String() { |
| assertTrue(Paths.get("t1/t2").endsWith("t2")); |
| assertTrue(Paths.get("t1/t2/t3").endsWith("t2/t3")); |
| assertFalse(Paths.get("t1/t2").endsWith("t1")); |
| assertTrue(Paths.get("/").endsWith("/")); |
| assertFalse(Paths.get("/data/").endsWith("/")); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_endsWith$String_NPE() { |
| filesSetup.getTestPath().endsWith((String)null); |
| } |
| |
| @Test |
| public void test_normalize() { |
| assertEquals(Paths.get("t2/t3"), Paths.get("t1/../t2/t3").normalize()); |
| assertEquals(Paths.get("../t2/t3"), Paths.get("t1/../../t2/t3").normalize()); |
| assertEquals(Paths.get("t1/t2/t3"), Paths.get("t1/./t2/t3").normalize()); |
| assertEquals(Paths.get("t1/t2/t3"), Paths.get("t1/././t2/t3").normalize()); |
| assertEquals(Paths.get("t1/t2/t3"), Paths.get("t1/././t2/t3").normalize()); |
| assertEquals(Paths.get("t1"), Paths.get("t1/")); |
| } |
| |
| @Test |
| public void test_resolve$Path() { |
| Path p = Paths.get("p"); |
| Path p1 = Paths.get("p1"); |
| Path p1p = Paths.get("p1/p"); |
| assertEquals(p1p, p1.resolve(p)); |
| assertEquals(p.toAbsolutePath(), p1.resolve(p.toAbsolutePath())); |
| assertEquals(p1p.toAbsolutePath(), p1.toAbsolutePath().resolve(p)); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_resolve$Path_NPE() { |
| fakePath.resolve((Path)null); |
| } |
| |
| @Test |
| public void test_resolve$String() { |
| Path p = Paths.get("p"); |
| Path p1 = Paths.get("p1"); |
| Path p1p = Paths.get("p1/p"); |
| assertEquals(p1p, p1.resolve("p")); |
| assertEquals(p1p.toAbsolutePath(), p1.toAbsolutePath().resolve("p")); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_resolve$String_NPE() { |
| fakePath.resolve((String)null); |
| } |
| |
| @Test |
| public void test_resolveSibling$Path() { |
| Path c2 = Paths.get("c2"); |
| Path parent_c1 = Paths.get("parent/c1"); |
| Path parent_c2 = Paths.get("parent/c2"); |
| assertEquals(parent_c2, parent_c1.resolveSibling(c2)); |
| assertEquals(c2.toAbsolutePath(), parent_c1.resolveSibling(c2.toAbsolutePath())); |
| assertEquals(parent_c2.toAbsolutePath(), parent_c1.toAbsolutePath().resolveSibling(c2)); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_resolveSibling$String_Path() { |
| fakePath.resolveSibling((Path) null); |
| } |
| |
| @Test |
| public void test_resolveSibling$String() { |
| Path c2 = Paths.get("c2"); |
| Path parent_c1 = Paths.get("parent/c1"); |
| Path parent_c2 = Paths.get("parent/c2"); |
| assertEquals(parent_c2, parent_c1.resolveSibling(c2.toString())); |
| assertEquals(c2.toAbsolutePath(), parent_c1.resolveSibling(c2.toAbsolutePath().toString())); |
| assertEquals(parent_c2.toAbsolutePath(), parent_c1.toAbsolutePath() |
| .resolveSibling(c2.toString())); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_resolveSibling$String_NPE() { |
| fakePath.resolveSibling((String)null); |
| } |
| |
| @Test |
| public void test_relativize() { |
| Path p1 = Paths.get("t1/t2/t3"); |
| Path p2 = Paths.get("t1/t2"); |
| assertEquals(Paths.get(".."), p1.relativize(p2)); |
| assertEquals(Paths.get(".."), p1.toAbsolutePath().relativize(p2.toAbsolutePath())); |
| assertEquals(Paths.get("t3"), p2.relativize(p1)); |
| |
| // Can't be relativized as either of the paths are relative and the other is not. |
| try { |
| p1.relativize(p2.toAbsolutePath()); |
| fail(); |
| } catch (IllegalArgumentException expected) {} |
| |
| try { |
| p1.toAbsolutePath().relativize(p2); |
| fail(); |
| } catch (IllegalArgumentException expected) {} |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_relativize_NPE() { |
| fakePath.relativize(null); |
| } |
| |
| @Test |
| public void test_toURI() throws URISyntaxException { |
| assertEquals(new URI("file://" + fakePath.toAbsolutePath().toString()), fakePath.toUri()); |
| assertEquals(new URI("file:///"), Paths.get("/").toUri()); |
| assertEquals(new URI("file:///dir/.."), Paths.get(("/dir/..")).toUri()); |
| assertEquals(new URI("file:///../"), Paths.get(("/..")).toUri()); |
| assertEquals(new URI("file:///dir/.."), Paths.get(("/dir/..")).toUri()); |
| assertEquals(new URI("file:///./"), Paths.get(("/.")).toUri()); |
| assertEquals(new URI("file:///dir/."), Paths.get(("/dir/.")).toUri()); |
| // For unicode characters. |
| assertEquals(new URI("file:///%E0%A4%B0%E0%A4%BE%E0%A4%B9."), Paths.get(("/राह.")).toUri()); |
| } |
| |
| @Test |
| public void test_toAbsolutePath() { |
| assertFalse(fakePath.isAbsolute()); |
| assertTrue(fakePath.toAbsolutePath().isAbsolute()); |
| } |
| |
| @Test |
| public void test_toRealPath() throws IOException { |
| // When file doesn't exist. |
| try { |
| fakePath.toRealPath(); |
| fail(); |
| } catch (NoSuchFileException expected) {} |
| Files.createFile(filesSetup.getTestPath()); |
| Path realPath = filesSetup.getTestPath().toRealPath(); |
| assertTrue(Files.isSameFile(filesSetup.getTestPath().toAbsolutePath(), realPath)); |
| assertTrue(realPath.isAbsolute()); |
| assertFalse(Files.isSymbolicLink(realPath)); |
| |
| Path dir = Paths.get(filesSetup.getTestDir(), "dir1/dir2"); |
| Path file = Paths.get(filesSetup.getTestDir(), "dir1/dir2/../../file"); |
| Files.createDirectories(dir); |
| Files.createFile(file); |
| realPath = file.toRealPath(); |
| assertTrue(Files.isSameFile(file.toAbsolutePath(), realPath)); |
| assertTrue(realPath.isAbsolute()); |
| assertFalse(Files.isSymbolicLink(realPath)); |
| |
| // Sym links. |
| Path symLink = Paths.get(filesSetup.getTestDir(), "symlink"); |
| Files.createSymbolicLink(symLink, filesSetup.getTestPath().toAbsolutePath()); |
| realPath = symLink.toRealPath(); |
| assertTrue(Files.isSameFile(symLink, realPath)); |
| assertTrue(realPath.isAbsolute()); |
| assertFalse(Files.isSymbolicLink(realPath)); |
| |
| realPath = symLink.toRealPath(LinkOption.NOFOLLOW_LINKS); |
| assertTrue(Files.isSameFile(symLink, realPath)); |
| assertTrue(realPath.isAbsolute()); |
| assertTrue(Files.isSymbolicLink(realPath)); |
| } |
| |
| @Test |
| public void test_toFile() { |
| File file = fakePath.toFile(); |
| assertEquals(fakePath.toAbsolutePath().toString(), file.getAbsolutePath()); |
| } |
| |
| @Test |
| public void test_register$WatchService$WatchEvent_Kind() throws IOException, |
| InterruptedException { |
| WatchService watchService = FileSystems.getDefault().newWatchService(); |
| WatchEvent.Kind<?>[] events = {ENTRY_CREATE, ENTRY_DELETE}; |
| Path file = Paths.get(filesSetup.getTestDir(), "directory/file"); |
| assertFalse(Files.exists(file)); |
| Path directory = Paths.get(filesSetup.getTestDir(), "directory"); |
| Files.createDirectories(directory); |
| WatchKey key = directory.register(watchService, events); |
| |
| // Creating, modifying and deleting the file. |
| Files.createFile(file); |
| assertTrue(Files.exists(file)); |
| // EVENT_MODIFY should not be logged. |
| Files.newOutputStream(file).write("hello".getBytes()); |
| Files.delete(file); |
| assertFalse(Files.exists(file)); |
| |
| assertTrue(key.isValid()); |
| assertEquals(directory, key.watchable()); |
| List<WatchEvent<?>> eventList = new ArrayList<>(); |
| |
| // Wait for the events to be recorded by WatchService. |
| while(true) { |
| eventList.addAll(key.pollEvents()); |
| if (eventList.size() == 2) break; |
| Thread.sleep(1000); |
| } |
| // Wait for the events to be recorded by watchService. |
| assertEquals(2, eventList.size()); |
| assertEquals(ENTRY_CREATE, eventList.get(0).kind()); |
| assertEquals(ENTRY_DELETE, eventList.get(1).kind()); |
| } |
| |
| @Test |
| public void test_register$WatchService$WatchEvent_Kind_NPE() throws IOException, |
| InterruptedException { |
| WatchService watchService = FileSystems.getDefault().newWatchService(); |
| WatchEvent.Kind<?>[] events = {ENTRY_CREATE, ENTRY_DELETE}; |
| Path directory = Paths.get(filesSetup.getTestDir(), "directory"); |
| Files.createDirectories(directory); |
| try { |
| directory.register(null, events); |
| fail(); |
| } catch (NullPointerException expected) {} |
| |
| try { |
| directory.register(watchService, (WatchEvent.Kind<?>) null); |
| fail(); |
| } catch (NullPointerException expected) {} |
| } |
| |
| @Test |
| public void test_register$WatchService$WatchEvent_Kind_Exception() throws IOException { |
| WatchService watchService = FileSystems.getDefault().newWatchService(); |
| Path directory = Paths.get(filesSetup.getTestDir(), "directory1"); |
| Files.createFile(directory); |
| |
| // When file is not a directory. |
| try { |
| directory.register(watchService, ENTRY_CREATE); |
| fail(); |
| } catch (NotDirectoryException expected) {} |
| |
| // When the events are not supported. |
| Files.deleteIfExists(directory); |
| Files.createDirectories(directory); |
| WatchEvent.Kind<?>[] events = {new NonStandardEvent<>()}; |
| try { |
| directory.register(watchService, events); |
| fail(); |
| } catch (UnsupportedOperationException expected) {} |
| |
| // When the watch service is closed. |
| watchService.close(); |
| try { |
| directory.register(watchService, ENTRY_CREATE); |
| fail(); |
| } catch (ClosedWatchServiceException expected) {} |
| } |
| |
| @Test |
| public void test_register$WatchService$WatchEvent_Kind_Exception_NPE() throws IOException { |
| WatchService watchService = FileSystems.getDefault().newWatchService(); |
| Path directory = Paths.get(filesSetup.getTestDir(), "directory1"); |
| Files.createDirectories(directory); |
| |
| // When file is not a directory. |
| try { |
| directory.register(null, ENTRY_CREATE); |
| fail(); |
| } catch (NullPointerException expected) {} |
| |
| try { |
| directory.register(watchService, (Kind<?>) null); |
| fail(); |
| } catch (NullPointerException expected) {} |
| } |
| |
| @Test |
| public void test_register$WatchService$WatchEvent_Kind$WatchEvent_Modifier() throws IOException |
| { |
| WatchService watchService = FileSystems.getDefault().newWatchService(); |
| WatchEvent.Kind<?>[] events = {ENTRY_CREATE}; |
| Path dirRoot = Paths.get(filesSetup.getTestDir(), "dir"); |
| Files.createDirectories(dirRoot); |
| try { |
| WatchKey key = dirRoot.register(watchService, events, |
| ExtendedWatchEventModifier.FILE_TREE); |
| fail(); |
| } catch (UnsupportedOperationException expected) { |
| assertTrue(expected.getMessage().contains("Modifier not supported")); |
| } |
| } |
| |
| @Test |
| public void test_register$WatchService$WatchEvent_Kind$WatchEvent_Modifier_NPE() |
| throws IOException { |
| WatchService watchService = FileSystems.getDefault().newWatchService(); |
| WatchEvent.Kind<?>[] events = {ENTRY_CREATE}; |
| Path dirRoot = Paths.get(filesSetup.getTestDir(), "dir"); |
| Files.createDirectories(dirRoot); |
| try { |
| WatchKey key = dirRoot.register(null, events, |
| ExtendedWatchEventModifier.FILE_TREE); |
| fail(); |
| } catch (NullPointerException expected) {} |
| |
| try { |
| WatchKey key = dirRoot.register(watchService, null, |
| ExtendedWatchEventModifier.FILE_TREE); |
| fail(); |
| } catch (NullPointerException expected) {} |
| } |
| |
| @Test |
| public void test_iterator() { |
| Path p = Paths.get("f1/f2/f3"); |
| Iterator<Path> pathIterator = p.iterator(); |
| assertEquals(Paths.get("f1"), pathIterator.next()); |
| assertEquals(Paths.get("f2"), pathIterator.next()); |
| assertEquals(Paths.get("f3"), pathIterator.next()); |
| assertFalse(pathIterator.hasNext()); |
| } |
| |
| @Test |
| public void test_iterator_hasRoot() { |
| Path p = Paths.get("/f1/f2/f3"); |
| Iterator<Path> pathIterator = p.iterator(); |
| assertEquals(Paths.get("f1"), pathIterator.next()); |
| assertEquals(Paths.get("f2"), pathIterator.next()); |
| assertEquals(Paths.get("f3"), pathIterator.next()); |
| assertFalse(pathIterator.hasNext()); |
| } |
| |
| @Test |
| public void test_compareTo() { |
| Path p1 = Paths.get("d/a"); |
| Path p2 = Paths.get("d/b"); |
| assertTrue(p1.compareTo(p2) < 0); |
| assertTrue(p2.compareTo(p1) > 0); |
| assertTrue(p1.compareTo(p1) == 0); |
| } |
| |
| @Test(expected = NullPointerException.class) |
| public void test_compareTo_NPE() { |
| filesSetup.getTestPath().compareTo(null); |
| } |
| |
| @Test |
| public void test_equals() { |
| Path p1 = Paths.get("a/b"); |
| Path p2 = Paths.get("a/../a/b"); |
| Path p3 = p1.toAbsolutePath(); |
| assertFalse(p1.equals(p2)); |
| assertTrue(p1.equals(p1)); |
| assertFalse(p1.equals(p3)); |
| } |
| |
| @Test |
| public void test_equals_NPE() { |
| // Should not throw NPE. |
| filesSetup.getTestPath().equals(null); |
| } |
| |
| @Test |
| public void test_hashCode() { |
| Path p1 = Paths.get("f1/f2/f3"); |
| assertEquals(-642657684, p1.hashCode()); |
| |
| // With root component. |
| Path p2 = Paths.get("/f1/f2/f3"); |
| assertEquals(306328475, p2.hashCode()); |
| } |
| |
| @Test |
| public void test_toString() { |
| Path p = Paths.get("f1/f2/f3"); |
| assertEquals("f1/f2/f3", p.toString()); |
| |
| p = Paths.get(""); |
| assertEquals("", p.toString()); |
| |
| p = Paths.get(".."); |
| assertEquals("..", p.toString()); |
| |
| p = Paths.get("."); |
| assertEquals(".", p.toString()); |
| |
| p = Paths.get("dir/"); |
| assertEquals("dir", p.toString()); |
| |
| p = Paths.get("/dir"); |
| assertEquals("/dir", p.toString()); |
| } |
| |
| private static class NonStandardEvent<T> implements WatchEvent.Kind<T> { |
| |
| @Override |
| public String name() { |
| return null; |
| } |
| |
| @Override |
| public Class<T> type() { |
| return null; |
| } |
| } |
| } |