1a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes/* 2a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * Copyright (C) 2009 The Android Open Source Project 3a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * 4a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * you may not use this file except in compliance with the License. 6a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * You may obtain a copy of the License at 7a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * 8a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * 10a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * Unless required by applicable law or agreed to in writing, software 11a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * See the License for the specific language governing permissions and 14a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes * limitations under the License. 15a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes */ 16a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 17a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughespackage java.io; 18a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 197006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughesimport java.util.UUID; 207006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes 21a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughesimport junit.framework.Test; 22a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughesimport junit.framework.TestSuite; 23a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 24a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughespublic class FileTest extends junit.framework.TestCase { 25a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes private static File createTemporaryDirectory() throws Exception { 26a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes String base = System.getProperty("java.io.tmpdir"); 277006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes File directory = new File(base, UUID.randomUUID().toString()); 287006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertTrue(directory.mkdirs()); 297006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes return directory; 30a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes } 31a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 32a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes private static String longString(int n) { 33a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes StringBuilder result = new StringBuilder(); 34a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes for (int i = 0; i < n; ++i) { 35a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes result.append('x'); 36a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes } 37a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes return result.toString(); 38a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes } 39a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 40a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes private static File createDeepStructure(File base) throws Exception { 41a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // ext has a limit of around 256 characters for each path entry. 42a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // 128 characters should be safe for everything but FAT. 43a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes String longString = longString(128); 44a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // Keep creating subdirectories until the path length is greater than 1KiB. 45a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // Ubuntu 8.04's kernel is happy up to about 4KiB. 46a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes File f = base; 47a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes for (int i = 0; f.toString().length() <= 1024; ++i) { 48a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes f = new File(f, longString); 49a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes assertTrue(f.mkdir()); 50a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes } 51a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes return f; 52a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes } 53a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 54a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // Rather than test all methods, assume that if createTempFile creates a long path and 55a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // exists can see it, the code for coping with long paths (shared by all methods) works. 56a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes public void test_longPath() throws Exception { 57a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes File base = createTemporaryDirectory(); 58a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes assertTrue(createDeepStructure(base).exists()); 59a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes } 60a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 61a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // readlink(2) is a special case,. 62a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes public void test_longReadlink() throws Exception { 63a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes File base = createTemporaryDirectory(); 64a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes File target = createDeepStructure(base); 65a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes File source = new File(base, "source"); 66a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes assertFalse(source.exists()); 67a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes assertTrue(target.exists()); 68a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes assertTrue(target.getCanonicalPath().length() > 1024); 69a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes Runtime.getRuntime().exec(new String[] { "ln", "-s", target.toString(), source.toString() }).waitFor(); 70a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes assertTrue(source.exists()); 71a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes assertEquals(target.getCanonicalPath(), source.getCanonicalPath()); 72a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes } 73a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes 74a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // TODO: File.list is a special case too, but I haven't fixed it yet, and the new code, 75a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes // like the old code, will die of a native buffer overrun if we exercise it. 767006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes 777006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes public void test_emptyFilename() throws Exception { 787006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes // The behavior of the empty filename is an odd mixture. 797006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes File f = new File(""); 807006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes // Mostly it behaves like an invalid path... 817006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.canRead()); 827006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.canWrite()); 837006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes try { 847006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes f.createNewFile(); 857006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes fail("expected IOException"); 867006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes } catch (IOException expected) { 877006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes } 887006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.delete()); 897006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes f.deleteOnExit(); 907006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.exists()); 917006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals("", f.getName()); 927006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(null, f.getParent()); 937006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(null, f.getParentFile()); 947006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals("", f.getPath()); 957006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.isAbsolute()); 967006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.isDirectory()); 977006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.isFile()); 987006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.isHidden()); 997006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(0, f.lastModified()); 1007006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(0, f.length()); 1017006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(null, f.list()); 1027006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(null, f.list(null)); 1037006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(null, f.listFiles()); 1047006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(null, f.listFiles((FileFilter) null)); 1057006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(null, f.listFiles((FilenameFilter) null)); 1067006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.mkdir()); 1077006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.mkdirs()); 1087006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.renameTo(f)); 1097006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.setLastModified(123)); 1107006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertFalse(f.setReadOnly()); 1117006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes // ...but sometimes it behaves like "user.dir". 1127006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes String cwd = System.getProperty("user.dir"); 1137006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(new File(cwd), f.getAbsoluteFile()); 1147006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(cwd, f.getAbsolutePath()); 1157006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(new File(cwd), f.getCanonicalFile()); 1167006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes assertEquals(cwd, f.getCanonicalPath()); 1177006487c694842aa4993e5ac3bf5b1a753a65f8dElliott Hughes } 118fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes 119fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes // http://b/2486943 - between eclair and froyo, we added a call to 120fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes // isAbsolute from the File constructor, potentially breaking subclasses. 121fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes public void test_subclassing() throws Exception { 122fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes class MyFile extends File { 123fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes private String field; 124fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes MyFile(String s) { 125fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes super(s); 126fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes field = ""; 127fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes } 128fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes @Override public boolean isAbsolute() { 129fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes field.length(); 130fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes return super.isAbsolute(); 131fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes } 132fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes } 133fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes new MyFile(""); 134fa2ad81d0b839083c711f5f0ef17030af3000f69Elliott Hughes } 135a171559499e05c4ab3c09a27fba41db99ea8d5bbElliott Hughes} 136