13652b361896defff06be1f37c5200f27c7610b97Neil Fuller/*
23652b361896defff06be1f37c5200f27c7610b97Neil Fuller * Copyright (C) 2015 The Android Open Source Project
33652b361896defff06be1f37c5200f27c7610b97Neil Fuller *
43652b361896defff06be1f37c5200f27c7610b97Neil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
53652b361896defff06be1f37c5200f27c7610b97Neil Fuller * you may not use this file except in compliance with the License.
63652b361896defff06be1f37c5200f27c7610b97Neil Fuller * You may obtain a copy of the License at
73652b361896defff06be1f37c5200f27c7610b97Neil Fuller *
83652b361896defff06be1f37c5200f27c7610b97Neil Fuller *      http://www.apache.org/licenses/LICENSE-2.0
93652b361896defff06be1f37c5200f27c7610b97Neil Fuller *
103652b361896defff06be1f37c5200f27c7610b97Neil Fuller * Unless required by applicable law or agreed to in writing, software
113652b361896defff06be1f37c5200f27c7610b97Neil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
123652b361896defff06be1f37c5200f27c7610b97Neil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133652b361896defff06be1f37c5200f27c7610b97Neil Fuller * See the License for the specific language governing permissions and
143652b361896defff06be1f37c5200f27c7610b97Neil Fuller * limitations under the License.
153652b361896defff06be1f37c5200f27c7610b97Neil Fuller */
163652b361896defff06be1f37c5200f27c7610b97Neil Fullerpackage com.android.timezone.distro;
173652b361896defff06be1f37c5200f27c7610b97Neil Fuller
183652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport junit.framework.TestCase;
193652b361896defff06be1f37c5200f27c7610b97Neil Fuller
203652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport android.system.Os;
213652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport android.system.OsConstants;
223652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport android.system.StructStat;
233652b361896defff06be1f37c5200f27c7610b97Neil Fuller
243652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.io.File;
253652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.io.FileNotFoundException;
263652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.io.FileOutputStream;
273652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.io.IOException;
283652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.nio.charset.StandardCharsets;
293652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.util.ArrayList;
303652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.util.Arrays;
313652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.util.Collections;
323652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport java.util.List;
333652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport libcore.io.IoUtils;
343652b361896defff06be1f37c5200f27c7610b97Neil Fullerimport libcore.io.Libcore;
353652b361896defff06be1f37c5200f27c7610b97Neil Fuller
363652b361896defff06be1f37c5200f27c7610b97Neil Fuller/**
373652b361896defff06be1f37c5200f27c7610b97Neil Fuller * Tests for {@link FileUtils}.
383652b361896defff06be1f37c5200f27c7610b97Neil Fuller */
393652b361896defff06be1f37c5200f27c7610b97Neil Fullerpublic class FileUtilsTest extends TestCase {
403652b361896defff06be1f37c5200f27c7610b97Neil Fuller
413652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private List<File> testFiles = new ArrayList<>();
423652b361896defff06be1f37c5200f27c7610b97Neil Fuller
433652b361896defff06be1f37c5200f27c7610b97Neil Fuller    @Override
443652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void tearDown() throws Exception {
453652b361896defff06be1f37c5200f27c7610b97Neil Fuller        // Delete in reverse order
463652b361896defff06be1f37c5200f27c7610b97Neil Fuller        Collections.reverse(testFiles);
473652b361896defff06be1f37c5200f27c7610b97Neil Fuller        for (File tempFile : testFiles) {
483652b361896defff06be1f37c5200f27c7610b97Neil Fuller            tempFile.delete();
493652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
503652b361896defff06be1f37c5200f27c7610b97Neil Fuller        super.tearDown();
513652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
523652b361896defff06be1f37c5200f27c7610b97Neil Fuller
533652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testDeleteRecursive() throws Exception {
543652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
553652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file1 = createRegularFile(dir, "file1");
563652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file2 = createRegularFile(dir, "file2");
573652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File symLink1 = createSymlink(file1, dir, "symLink1");
583652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File subDir = createDir(dir, "subDir");
593652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file3 = createRegularFile(subDir, "subFile1");
603652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file4 = createRegularFile(subDir, "subFile2");
613652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File symLink2 = createSymlink(file1, dir, "symLink2");
623652b361896defff06be1f37c5200f27c7610b97Neil Fuller
633652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File otherDir = createTempDir();
643652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File otherFile = createRegularFile(otherDir, "kept");
653652b361896defff06be1f37c5200f27c7610b97Neil Fuller
663652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File linkToOtherDir = createSymlink(otherDir, subDir, "linkToOtherDir");
673652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File linkToOtherFile = createSymlink(otherFile, subDir, "linkToOtherFile");
683652b361896defff06be1f37c5200f27c7610b97Neil Fuller
693652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File[] filesToDelete = { dir, file1, file2, symLink1, subDir, file3, file4, symLink2,
703652b361896defff06be1f37c5200f27c7610b97Neil Fuller                linkToOtherDir, linkToOtherFile };
713652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File[] filesToKeep = { otherDir, otherFile };
723652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFilesExist(filesToDelete);
733652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFilesExist(filesToKeep);
743652b361896defff06be1f37c5200f27c7610b97Neil Fuller
753652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.deleteRecursive(dir);
763652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFilesDoNotExist(filesToDelete);
773652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFilesExist(filesToKeep);
783652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
793652b361896defff06be1f37c5200f27c7610b97Neil Fuller
803652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testIsSymlink() throws Exception {
813652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
823652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File subDir = createDir(dir, "subDir");
833652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File fileInSubDir = createRegularFile(subDir, "fileInSubDir");
843652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File normalFile = createRegularFile(dir, "normalFile");
853652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File symlinkToDir = createSymlink(subDir, dir, "symlinkToDir");
863652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File symlinkToFile = createSymlink(fileInSubDir, dir, "symlinkToFile");
873652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File symlinkToFileInSubDir = createSymlink(fileInSubDir, dir, "symlinkToFileInSubDir");
883652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File normalFileViaSymlink = new File(symlinkToDir, "normalFile");
893652b361896defff06be1f37c5200f27c7610b97Neil Fuller
903652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(FileUtils.isSymlink(dir));
913652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(FileUtils.isSymlink(subDir));
923652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(FileUtils.isSymlink(fileInSubDir));
933652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(FileUtils.isSymlink(normalFile));
943652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(FileUtils.isSymlink(symlinkToDir));
953652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(FileUtils.isSymlink(symlinkToFile));
963652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(FileUtils.isSymlink(symlinkToFileInSubDir));
973652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(FileUtils.isSymlink(normalFileViaSymlink));
983652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
993652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1003652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testCreateSubFile() throws Exception {
1013652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir1 = createTempDir().getCanonicalFile();
1023652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1033652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File actualSubFile = FileUtils.createSubFile(dir1, "file");
1043652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(new File(dir1, "file"), actualSubFile);
1053652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1063652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File existingSubFile = createRegularFile(dir1, "file");
1073652b361896defff06be1f37c5200f27c7610b97Neil Fuller        actualSubFile = FileUtils.createSubFile(dir1, "file");
1083652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(existingSubFile, actualSubFile);
1093652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1103652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File existingSubDir = createDir(dir1, "subdir");
1113652b361896defff06be1f37c5200f27c7610b97Neil Fuller        actualSubFile = FileUtils.createSubFile(dir1, "subdir");
1123652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(existingSubDir, actualSubFile);
1133652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1143652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertCreateSubFileThrows(dir1, "../file");
1153652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertCreateSubFileThrows(dir1, "../../file");
1163652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertCreateSubFileThrows(dir1, "../otherdir/file");
1173652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1183652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir2 = createTempDir().getCanonicalFile();
1193652b361896defff06be1f37c5200f27c7610b97Neil Fuller        createSymlink(dir2, dir1, "symlinkToDir2");
1203652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertCreateSubFileThrows(dir1, "symlinkToDir2");
1213652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1223652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir");
1233652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1243652b361896defff06be1f37c5200f27c7610b97Neil Fuller        createRegularFile(dir1, "symlinkToDir2/fileInSymlinkedDir");
1253652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir");
1263652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
1273652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1283652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testEnsureDirectoryExists() throws Exception {
1293652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
1303652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1313652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File exists = new File(dir, "exists");
1323652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(exists.mkdir());
1333652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(exists.setReadable(true /* readable */, true /* ownerOnly */));
1343652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(exists.setExecutable(true /* readable */, true /* ownerOnly */));
1353652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.ensureDirectoriesExist(exists, true /* makeWorldReadable */);
1363652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertDirExistsAndIsAccessible(exists, false /* requireWorldReadable */);
1373652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1383652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File subDir = new File(dir, "subDir");
1393652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(subDir.exists());
1403652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.ensureDirectoriesExist(subDir, true /* makeWorldReadable */);
1413652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertDirExistsAndIsAccessible(subDir, true /* requireWorldReadable */);
1423652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1433652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File one = new File(dir, "one");
1443652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File two = new File(one, "two");
1453652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File three = new File(two, "three");
1463652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.ensureDirectoriesExist(three, true /* makeWorldReadable */);
1473652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertDirExistsAndIsAccessible(one, true /* requireWorldReadable */);
1483652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertDirExistsAndIsAccessible(two, true /* requireWorldReadable */);
1493652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertDirExistsAndIsAccessible(three, true /* requireWorldReadable */);
1503652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
1513652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1523652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testEnsureDirectoriesExist_noPermissions() throws Exception {
1533652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
1543652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertDirExistsAndIsAccessible(dir, false /* requireWorldReadable */);
1553652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1563652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File unreadableSubDir = new File(dir, "unreadableSubDir");
1573652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(unreadableSubDir.mkdir());
1583652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(unreadableSubDir.setReadable(false /* readable */, true /* ownerOnly */));
1593652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(unreadableSubDir.setExecutable(false /* readable */, true /* ownerOnly */));
1603652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1613652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File toCreate = new File(unreadableSubDir, "toCreate");
1623652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try {
1633652b361896defff06be1f37c5200f27c7610b97Neil Fuller            FileUtils.ensureDirectoriesExist(toCreate, true /* makeWorldReadable */);
1643652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fail();
1653652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } catch (IOException expected) {
1663652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
1673652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertDirExistsAndIsAccessible(dir, false /* requireWorldReadable */);
1683652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(unreadableSubDir.canRead() && unreadableSubDir.canExecute());
1693652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(toCreate.exists());
1703652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
1713652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1723652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testEnsureFileDoesNotExist() throws Exception {
1733652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
1743652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1753652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.ensureFileDoesNotExist(new File(dir, "doesNotExist"));
1763652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1773652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File exists1 = createRegularFile(dir, "exists1");
1783652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(exists1.exists());
1793652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.ensureFileDoesNotExist(exists1);
1803652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(exists1.exists());
1813652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1823652b361896defff06be1f37c5200f27c7610b97Neil Fuller        exists1 = createRegularFile(dir, "exists1");
1833652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File symlink = createSymlink(exists1, dir, "symlinkToFile");
1843652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(symlink.exists());
1853652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.ensureFileDoesNotExist(symlink);
1863652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(symlink.exists());
1873652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(exists1.exists());
1883652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1893652b361896defff06be1f37c5200f27c7610b97Neil Fuller        // Only files and symlinks supported. We do not delete directories.
1903652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File emptyDir = createTempDir();
1913652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try {
1923652b361896defff06be1f37c5200f27c7610b97Neil Fuller            FileUtils.ensureFileDoesNotExist(emptyDir);
1933652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fail();
1943652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } catch (IOException expected) {
1953652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
1963652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(emptyDir.exists());
1973652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
1983652b361896defff06be1f37c5200f27c7610b97Neil Fuller
1993652b361896defff06be1f37c5200f27c7610b97Neil Fuller    // This test does not pass when run as root because root can do anything even if the permissions
2003652b361896defff06be1f37c5200f27c7610b97Neil Fuller    // don't allow it.
2013652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testEnsureFileDoesNotExist_noPermission() throws Exception {
2023652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
2033652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2043652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File protectedDir = createDir(dir, "protected");
2053652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File undeletable = createRegularFile(protectedDir, "undeletable");
2063652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(protectedDir.setWritable(false));
2073652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(undeletable.exists());
2083652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try {
2093652b361896defff06be1f37c5200f27c7610b97Neil Fuller            FileUtils.ensureFileDoesNotExist(undeletable);
2103652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fail();
2113652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } catch (IOException expected) {
2123652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } finally {
2133652b361896defff06be1f37c5200f27c7610b97Neil Fuller            assertTrue(protectedDir.setWritable(true)); // Reset for clean-up
2143652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
2153652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(undeletable.exists());
2163652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
2173652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2183652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testCheckFilesExist() throws Exception {
2193652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
2203652b361896defff06be1f37c5200f27c7610b97Neil Fuller        createRegularFile(dir, "exists1");
2213652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File subDir = createDir(dir, "subDir");
2223652b361896defff06be1f37c5200f27c7610b97Neil Fuller        createRegularFile(subDir, "exists2");
2233652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(FileUtils.filesExist(dir, "exists1", "subDir/exists2"));
2243652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(FileUtils.filesExist(dir, "doesNotExist"));
2253652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(FileUtils.filesExist(dir, "subDir/doesNotExist"));
2263652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
2273652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2283652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testReadBytes() throws Exception {
2293652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
2303652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2313652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try {
2323652b361896defff06be1f37c5200f27c7610b97Neil Fuller            FileUtils.readBytes(new File(dir, "doesNotExist"), 0);
2333652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fail();
2343652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } catch (IllegalArgumentException expected) {
2353652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
2363652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2373652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try {
2383652b361896defff06be1f37c5200f27c7610b97Neil Fuller            FileUtils.readBytes(new File(dir, "doesNotExist"), 10);
2393652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fail();
2403652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } catch (FileNotFoundException expected) {
2413652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
2423652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2433652b361896defff06be1f37c5200f27c7610b97Neil Fuller        byte[] contents = "One\nTwo\nThree\n".getBytes(StandardCharsets.US_ASCII);
2443652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file = createFile(contents);
2453652b361896defff06be1f37c5200f27c7610b97Neil Fuller        byte[] oneByte = FileUtils.readBytes(file, 1);
2463652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(1, oneByte.length);
2473652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(contents[0], oneByte[0]);
2483652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2493652b361896defff06be1f37c5200f27c7610b97Neil Fuller        byte[] allBytes = FileUtils.readBytes(file, contents.length);
2503652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(Arrays.equals(contents, allBytes));
2513652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2523652b361896defff06be1f37c5200f27c7610b97Neil Fuller        byte[] exhaustedFileRead = FileUtils.readBytes(file, contents.length + 1);
2533652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(Arrays.equals(contents, exhaustedFileRead));
2543652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
2553652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2563652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testCreateEmptyFile() throws Exception {
2573652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
2583652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file = new File(dir, "one");
2593652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertFalse(file.exists());
2603652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.createEmptyFile(file);
2613652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(file.exists());
2623652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(0, file.length());
2633652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
2643652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2653652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testCreateEmptyFile_isDir() throws Exception {
2663652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
2673652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(dir.exists());
2683652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(dir.isDirectory());
2693652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2703652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try {
2713652b361896defff06be1f37c5200f27c7610b97Neil Fuller            FileUtils.createEmptyFile(dir);
2723652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } catch (FileNotFoundException expected) {
2733652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
2743652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(dir.exists());
2753652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(dir.isDirectory());
2763652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
2773652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2783652b361896defff06be1f37c5200f27c7610b97Neil Fuller    public void testCreateEmptyFile_truncatesExisting() throws Exception {
2793652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = createTempDir();
2803652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file = new File(dir, "one");
2813652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2823652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try (FileOutputStream fos = new FileOutputStream(file)) {
2833652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fos.write(new byte[1000]);
2843652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
2853652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(file.exists());
2863652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(1000, file.length());
2873652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2883652b361896defff06be1f37c5200f27c7610b97Neil Fuller        FileUtils.createEmptyFile(file);
2893652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(file.exists());
2903652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertEquals(0, file.length());
2913652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
2923652b361896defff06be1f37c5200f27c7610b97Neil Fuller
2933652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private File createFile(byte[] contents) throws IOException {
2943652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file = File.createTempFile(getClass().getSimpleName(), ".txt");
2953652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try (FileOutputStream fos = new FileOutputStream(file)) {
2963652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fos.write(contents);
2973652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
2983652b361896defff06be1f37c5200f27c7610b97Neil Fuller        return file;
2993652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3003652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3013652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private File createSymlink(File file, File symlinkDir, String symlinkName) throws Exception {
3023652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(file.exists());
3033652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3043652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File symlink = new File(symlinkDir, symlinkName);
3053652b361896defff06be1f37c5200f27c7610b97Neil Fuller        Os.symlink(file.getAbsolutePath(), symlink.getAbsolutePath());
3063652b361896defff06be1f37c5200f27c7610b97Neil Fuller        testFiles.add(symlink);
3073652b361896defff06be1f37c5200f27c7610b97Neil Fuller        return symlink;
3083652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3093652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3103652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private static void assertCreateSubFileThrows(File parentDir, String name) {
3113652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try {
3123652b361896defff06be1f37c5200f27c7610b97Neil Fuller            FileUtils.createSubFile(parentDir, name);
3133652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fail();
3143652b361896defff06be1f37c5200f27c7610b97Neil Fuller        } catch (IOException expected) {
3153652b361896defff06be1f37c5200f27c7610b97Neil Fuller            assertTrue(expected.getMessage().contains("must exist beneath"));
3163652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
3173652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3183652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3193652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private static void assertFilesDoNotExist(File... files) {
3203652b361896defff06be1f37c5200f27c7610b97Neil Fuller        for (File f : files) {
3213652b361896defff06be1f37c5200f27c7610b97Neil Fuller            assertFalse(f + " unexpectedly exists", f.exists());
3223652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
3233652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3243652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3253652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private static void assertFilesExist(File... files) {
3263652b361896defff06be1f37c5200f27c7610b97Neil Fuller        for (File f : files) {
3273652b361896defff06be1f37c5200f27c7610b97Neil Fuller            assertTrue(f + " expected to exist", f.exists());
3283652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
3293652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3303652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3313652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private static void assertDirExistsAndIsAccessible(File dir, boolean requireWorldReadable)
3323652b361896defff06be1f37c5200f27c7610b97Neil Fuller            throws Exception {
3333652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(dir.exists() && dir.isDirectory() && dir.canRead() && dir.canExecute());
3343652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3353652b361896defff06be1f37c5200f27c7610b97Neil Fuller        String path = dir.getCanonicalPath();
3363652b361896defff06be1f37c5200f27c7610b97Neil Fuller        StructStat sb = Libcore.os.stat(path);
3373652b361896defff06be1f37c5200f27c7610b97Neil Fuller        int mask = OsConstants.S_IXUSR | OsConstants.S_IRUSR;
3383652b361896defff06be1f37c5200f27c7610b97Neil Fuller        if (requireWorldReadable) {
3393652b361896defff06be1f37c5200f27c7610b97Neil Fuller            mask = mask | OsConstants.S_IXGRP | OsConstants.S_IRGRP
3403652b361896defff06be1f37c5200f27c7610b97Neil Fuller                    | OsConstants.S_IXOTH | OsConstants.S_IROTH;
3413652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
3423652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue("Permission mask required: " + Integer.toOctalString(mask),
3433652b361896defff06be1f37c5200f27c7610b97Neil Fuller                (sb.st_mode & mask) == mask);
3443652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3453652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3463652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private File createTempDir() {
3473652b361896defff06be1f37c5200f27c7610b97Neil Fuller        final String tempPrefix = getClass().getSimpleName();
3483652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File tempDir = IoUtils.createTemporaryDirectory(tempPrefix);
3493652b361896defff06be1f37c5200f27c7610b97Neil Fuller        testFiles.add(tempDir);
3503652b361896defff06be1f37c5200f27c7610b97Neil Fuller        return tempDir;
3513652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3523652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3533652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private File createDir(File parentDir, String name) {
3543652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File dir = new File(parentDir, name);
3553652b361896defff06be1f37c5200f27c7610b97Neil Fuller        assertTrue(dir.mkdir());
3563652b361896defff06be1f37c5200f27c7610b97Neil Fuller        testFiles.add(dir);
3573652b361896defff06be1f37c5200f27c7610b97Neil Fuller        return dir;
3583652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3593652b361896defff06be1f37c5200f27c7610b97Neil Fuller
3603652b361896defff06be1f37c5200f27c7610b97Neil Fuller    private File createRegularFile(File dir, String name) throws Exception {
3613652b361896defff06be1f37c5200f27c7610b97Neil Fuller        File file = new File(dir, name);
3623652b361896defff06be1f37c5200f27c7610b97Neil Fuller        try (FileOutputStream fos = new FileOutputStream(file)) {
3633652b361896defff06be1f37c5200f27c7610b97Neil Fuller            fos.write("Hello".getBytes());
3643652b361896defff06be1f37c5200f27c7610b97Neil Fuller        }
3653652b361896defff06be1f37c5200f27c7610b97Neil Fuller        testFiles.add(file);
3663652b361896defff06be1f37c5200f27c7610b97Neil Fuller        return file;
3673652b361896defff06be1f37c5200f27c7610b97Neil Fuller    }
3683652b361896defff06be1f37c5200f27c7610b97Neil Fuller}
369