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