191c98d778c80e53a7f458264233375f982dcae14Neil Fuller/*
291c98d778c80e53a7f458264233375f982dcae14Neil Fuller * Copyright (C) 2015 The Android Open Source Project
391c98d778c80e53a7f458264233375f982dcae14Neil Fuller *
491c98d778c80e53a7f458264233375f982dcae14Neil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
591c98d778c80e53a7f458264233375f982dcae14Neil Fuller * you may not use this file except in compliance with the License.
691c98d778c80e53a7f458264233375f982dcae14Neil Fuller * You may obtain a copy of the License at
791c98d778c80e53a7f458264233375f982dcae14Neil Fuller *
891c98d778c80e53a7f458264233375f982dcae14Neil Fuller *      http://www.apache.org/licenses/LICENSE-2.0
991c98d778c80e53a7f458264233375f982dcae14Neil Fuller *
1091c98d778c80e53a7f458264233375f982dcae14Neil Fuller * Unless required by applicable law or agreed to in writing, software
1191c98d778c80e53a7f458264233375f982dcae14Neil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
1291c98d778c80e53a7f458264233375f982dcae14Neil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1391c98d778c80e53a7f458264233375f982dcae14Neil Fuller * See the License for the specific language governing permissions and
1491c98d778c80e53a7f458264233375f982dcae14Neil Fuller * limitations under the License.
1591c98d778c80e53a7f458264233375f982dcae14Neil Fuller */
1691c98d778c80e53a7f458264233375f982dcae14Neil Fullerpackage libcore.tzdata.update;
1791c98d778c80e53a7f458264233375f982dcae14Neil Fuller
1891c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport junit.framework.TestCase;
1991c98d778c80e53a7f458264233375f982dcae14Neil Fuller
2091c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport android.system.Os;
2191c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport android.system.OsConstants;
2291c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport android.system.StructStat;
2391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
2491c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.io.BufferedWriter;
2591c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.io.File;
2691c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.io.FileOutputStream;
2791c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.io.IOException;
2891c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.io.OutputStreamWriter;
2991c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.nio.charset.StandardCharsets;
3091c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.util.ArrayList;
3191c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.util.Arrays;
3291c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.util.Collections;
3391c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport java.util.List;
3491c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport libcore.io.IoUtils;
3591c98d778c80e53a7f458264233375f982dcae14Neil Fullerimport libcore.io.Libcore;
3691c98d778c80e53a7f458264233375f982dcae14Neil Fuller
3791c98d778c80e53a7f458264233375f982dcae14Neil Fuller/**
3891c98d778c80e53a7f458264233375f982dcae14Neil Fuller * Tests for {@link FileUtils}.
3991c98d778c80e53a7f458264233375f982dcae14Neil Fuller */
4091c98d778c80e53a7f458264233375f982dcae14Neil Fullerpublic class FileUtilsTest extends TestCase {
4191c98d778c80e53a7f458264233375f982dcae14Neil Fuller
4291c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private List<File> testFiles = new ArrayList<>();
4391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
4491c98d778c80e53a7f458264233375f982dcae14Neil Fuller    @Override
4591c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void tearDown() throws Exception {
4691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        // Delete in reverse order
4791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        Collections.reverse(testFiles);
4891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        for (File tempFile : testFiles) {
4991c98d778c80e53a7f458264233375f982dcae14Neil Fuller            tempFile.delete();
5091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
5191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        super.tearDown();
5291c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
5391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
5491c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testCalculateChecksum() throws Exception {
5591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        final String content = "Content";
5691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file1 = createTextFile(content);
5791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file2 = createTextFile(content);
5891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file3 = createTextFile(content + "!");
5991c98d778c80e53a7f458264233375f982dcae14Neil Fuller
6091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        long file1CheckSum = FileUtils.calculateChecksum(file1);
6191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        long file2CheckSum = FileUtils.calculateChecksum(file2);
6291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        long file3Checksum = FileUtils.calculateChecksum(file3);
6391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
6491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertEquals(file1CheckSum, file2CheckSum);
6591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(file1CheckSum != file3Checksum);
6691c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
6791c98d778c80e53a7f458264233375f982dcae14Neil Fuller
6891c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testDeleteRecursive() throws Exception {
6991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = createTempDir();
7091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file1 = createRegularFile(dir, "file1");
7191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file2 = createRegularFile(dir, "file2");
7291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File symLink1 = createSymlink(file1, dir, "symLink1");
7391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File subDir = createDir(dir, "subDir");
7491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file3 = createRegularFile(subDir, "subFile1");
7591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file4 = createRegularFile(subDir, "subFile2");
7691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File symLink2 = createSymlink(file1, dir, "symLink2");
7791c98d778c80e53a7f458264233375f982dcae14Neil Fuller
7891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File otherDir = createTempDir();
7991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File otherFile = createRegularFile(otherDir, "kept");
8091c98d778c80e53a7f458264233375f982dcae14Neil Fuller
8191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File linkToOtherDir = createSymlink(otherDir, subDir, "linkToOtherDir");
8291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File linkToOtherFile = createSymlink(otherFile, subDir, "linkToOtherFile");
8391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
8491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File[] filesToDelete = { dir, file1, file2, symLink1, subDir, file3, file4, symLink2,
8591c98d778c80e53a7f458264233375f982dcae14Neil Fuller                linkToOtherDir, linkToOtherFile };
8691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File[] filesToKeep = { otherDir, otherFile };
8791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFilesExist(filesToDelete);
8891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFilesExist(filesToKeep);
8991c98d778c80e53a7f458264233375f982dcae14Neil Fuller
9091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        FileUtils.deleteRecursive(dir);
9191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFilesDoNotExist(filesToDelete);
9291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFilesExist(filesToKeep);
9391c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
9491c98d778c80e53a7f458264233375f982dcae14Neil Fuller
9591c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testIsSymlink() throws Exception {
9691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = createTempDir();
9791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File subDir = createDir(dir, "subDir");
9891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File fileInSubDir = createRegularFile(subDir, "fileInSubDir");
9991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File normalFile = createRegularFile(dir, "normalFile");
10091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File symlinkToDir = createSymlink(subDir, dir, "symlinkToDir");
10191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File symlinkToFile = createSymlink(fileInSubDir, dir, "symlinkToFile");
10291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File symlinkToFileInSubDir = createSymlink(fileInSubDir, dir, "symlinkToFileInSubDir");
10391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File normalFileViaSymlink = new File(symlinkToDir, "normalFile");
10491c98d778c80e53a7f458264233375f982dcae14Neil Fuller
10591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(FileUtils.isSymlink(dir));
10691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(FileUtils.isSymlink(subDir));
10791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(FileUtils.isSymlink(fileInSubDir));
10891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(FileUtils.isSymlink(normalFile));
10991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(FileUtils.isSymlink(symlinkToDir));
11091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(FileUtils.isSymlink(symlinkToFile));
11191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(FileUtils.isSymlink(symlinkToFileInSubDir));
11291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(FileUtils.isSymlink(normalFileViaSymlink));
11391c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
11491c98d778c80e53a7f458264233375f982dcae14Neil Fuller
11591c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testCreateSubFile() throws Exception {
116e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        File dir1 = createTempDir().getCanonicalFile();
117e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller
118e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        File actualSubFile = FileUtils.createSubFile(dir1, "file");
119e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        assertEquals(new File(dir1, "file"), actualSubFile);
120e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller
121e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        File existingSubFile = createRegularFile(dir1, "file");
122e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        actualSubFile = FileUtils.createSubFile(dir1, "file");
123e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        assertEquals(existingSubFile, actualSubFile);
124e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller
125e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        File existingSubDir = createDir(dir1, "subdir");
126e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        actualSubFile = FileUtils.createSubFile(dir1, "subdir");
127e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        assertEquals(existingSubDir, actualSubFile);
12891c98d778c80e53a7f458264233375f982dcae14Neil Fuller
12991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertCreateSubFileThrows(dir1, "../file");
13091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertCreateSubFileThrows(dir1, "../../file");
13191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertCreateSubFileThrows(dir1, "../otherdir/file");
13291c98d778c80e53a7f458264233375f982dcae14Neil Fuller
133e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        File dir2 = createTempDir().getCanonicalFile();
134e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        createSymlink(dir2, dir1, "symlinkToDir2");
135e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        assertCreateSubFileThrows(dir1, "symlinkToDir2");
13691c98d778c80e53a7f458264233375f982dcae14Neil Fuller
137e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir");
13891c98d778c80e53a7f458264233375f982dcae14Neil Fuller
139e9a8e16980a5733852a829c48ed38497cff610b1Neil Fuller        createRegularFile(dir1, "symlinkToDir2/fileInSymlinkedDir");
14091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir");
14191c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
14291c98d778c80e53a7f458264233375f982dcae14Neil Fuller
14391c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testEnsureDirectoryExists() throws Exception {
14491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = createTempDir();
14591c98d778c80e53a7f458264233375f982dcae14Neil Fuller
14691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File exists = new File(dir, "exists");
14791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(exists.mkdir());
14891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(exists.setReadable(true /* readable */, true /* ownerOnly */));
14991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(exists.setExecutable(true /* readable */, true /* ownerOnly */));
15091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        FileUtils.ensureDirectoriesExist(exists, true /* makeWorldReadable */);
15191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertDirExistsAndIsAccessible(exists, false /* requireWorldReadable */);
15291c98d778c80e53a7f458264233375f982dcae14Neil Fuller
15391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File subDir = new File(dir, "subDir");
15491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(subDir.exists());
15591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        FileUtils.ensureDirectoriesExist(subDir, true /* makeWorldReadable */);
15691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertDirExistsAndIsAccessible(subDir, true /* requireWorldReadable */);
15791c98d778c80e53a7f458264233375f982dcae14Neil Fuller
15891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File one = new File(dir, "one");
15991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File two = new File(one, "two");
16091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File three = new File(two, "three");
16191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        FileUtils.ensureDirectoriesExist(three, true /* makeWorldReadable */);
16291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertDirExistsAndIsAccessible(one, true /* requireWorldReadable */);
16391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertDirExistsAndIsAccessible(two, true /* requireWorldReadable */);
16491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertDirExistsAndIsAccessible(three, true /* requireWorldReadable */);
16591c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
16691c98d778c80e53a7f458264233375f982dcae14Neil Fuller
16791c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testEnsureDirectoriesExist_noPermissions() throws Exception {
16891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = createTempDir();
16991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertDirExistsAndIsAccessible(dir, false /* requireWorldReadable */);
17091c98d778c80e53a7f458264233375f982dcae14Neil Fuller
17191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File unreadableSubDir = new File(dir, "unreadableSubDir");
17291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(unreadableSubDir.mkdir());
17391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(unreadableSubDir.setReadable(false /* readable */, true /* ownerOnly */));
17491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(unreadableSubDir.setExecutable(false /* readable */, true /* ownerOnly */));
17591c98d778c80e53a7f458264233375f982dcae14Neil Fuller
17691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File toCreate = new File(unreadableSubDir, "toCreate");
17791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        try {
17891c98d778c80e53a7f458264233375f982dcae14Neil Fuller            FileUtils.ensureDirectoriesExist(toCreate, true /* makeWorldReadable */);
17991c98d778c80e53a7f458264233375f982dcae14Neil Fuller            fail();
18091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        } catch (IOException expected) {
18191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
18291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertDirExistsAndIsAccessible(dir, false /* requireWorldReadable */);
18391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(unreadableSubDir.canRead() && unreadableSubDir.canExecute());
18491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(toCreate.exists());
18591c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
18691c98d778c80e53a7f458264233375f982dcae14Neil Fuller
18791c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testEnsureFileDoesNotExist() throws Exception {
18891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = createTempDir();
18991c98d778c80e53a7f458264233375f982dcae14Neil Fuller
19091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        FileUtils.ensureFileDoesNotExist(new File(dir, "doesNotExist"));
19191c98d778c80e53a7f458264233375f982dcae14Neil Fuller
19291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File exists1 = createRegularFile(dir, "exists1");
19391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(exists1.exists());
19491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        FileUtils.ensureFileDoesNotExist(exists1);
19591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(exists1.exists());
19691c98d778c80e53a7f458264233375f982dcae14Neil Fuller
19791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        exists1 = createRegularFile(dir, "exists1");
19891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File symlink = createSymlink(exists1, dir, "symlinkToFile");
19991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(symlink.exists());
20091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        FileUtils.ensureFileDoesNotExist(symlink);
20191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(symlink.exists());
20291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(exists1.exists());
20391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
20491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        // Only files and symlinks supported. We do not delete directories.
20591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File emptyDir = createTempDir();
20691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        try {
20791c98d778c80e53a7f458264233375f982dcae14Neil Fuller            FileUtils.ensureFileDoesNotExist(emptyDir);
20891c98d778c80e53a7f458264233375f982dcae14Neil Fuller            fail();
20991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        } catch (IOException expected) {
21091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
21191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(emptyDir.exists());
21291c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
21391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
21491c98d778c80e53a7f458264233375f982dcae14Neil Fuller    // This test does not pass when run as root because root can do anything even if the permissions
21591c98d778c80e53a7f458264233375f982dcae14Neil Fuller    // don't allow it.
21691c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testEnsureFileDoesNotExist_noPermission() throws Exception {
21791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = createTempDir();
21891c98d778c80e53a7f458264233375f982dcae14Neil Fuller
21991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File protectedDir = createDir(dir, "protected");
22091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File undeletable = createRegularFile(protectedDir, "undeletable");
22191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(protectedDir.setWritable(false));
22291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(undeletable.exists());
22391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        try {
22491c98d778c80e53a7f458264233375f982dcae14Neil Fuller            FileUtils.ensureFileDoesNotExist(undeletable);
22591c98d778c80e53a7f458264233375f982dcae14Neil Fuller            fail();
22691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        } catch (IOException expected) {
22791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        } finally {
22891c98d778c80e53a7f458264233375f982dcae14Neil Fuller            assertTrue(protectedDir.setWritable(true)); // Reset for clean-up
22991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
23091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(undeletable.exists());
23191c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
23291c98d778c80e53a7f458264233375f982dcae14Neil Fuller
23391c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testCheckFilesExist() throws Exception {
23491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = createTempDir();
23591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        createRegularFile(dir, "exists1");
23691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File subDir = createDir(dir, "subDir");
23791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        createRegularFile(subDir, "exists2");
23891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(FileUtils.filesExist(dir, "exists1", "subDir/exists2"));
23991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(FileUtils.filesExist(dir, "doesNotExist"));
24091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertFalse(FileUtils.filesExist(dir, "subDir/doesNotExist"));
24191c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
24291c98d778c80e53a7f458264233375f982dcae14Neil Fuller
24391c98d778c80e53a7f458264233375f982dcae14Neil Fuller    public void testReadLines() throws Exception {
24491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file = createTextFile("One\nTwo\nThree\n");
24591c98d778c80e53a7f458264233375f982dcae14Neil Fuller
24691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        List<String> lines = FileUtils.readLines(file);
24791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertEquals(3, lines.size());
24891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertEquals(lines, Arrays.asList("One", "Two", "Three"));
24991c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
25091c98d778c80e53a7f458264233375f982dcae14Neil Fuller
25191c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private File createTextFile(String contents) throws IOException {
25291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file = File.createTempFile(getClass().getSimpleName(), ".txt");
25391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        try (FileOutputStream fos = new FileOutputStream(file)) {
25491c98d778c80e53a7f458264233375f982dcae14Neil Fuller            BufferedWriter writer = new BufferedWriter(
25591c98d778c80e53a7f458264233375f982dcae14Neil Fuller                    new OutputStreamWriter(fos, StandardCharsets.UTF_8));
25691c98d778c80e53a7f458264233375f982dcae14Neil Fuller            writer.write(contents);
25791c98d778c80e53a7f458264233375f982dcae14Neil Fuller            writer.close();
25891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
25991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        return file;
26091c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
26191c98d778c80e53a7f458264233375f982dcae14Neil Fuller
26291c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private File createSymlink(File file, File symlinkDir, String symlinkName) throws Exception {
26391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(file.exists());
26491c98d778c80e53a7f458264233375f982dcae14Neil Fuller
26591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File symlink = new File(symlinkDir, symlinkName);
26691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        Os.symlink(file.getAbsolutePath(), symlink.getAbsolutePath());
26791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        testFiles.add(symlink);
26891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        return symlink;
26991c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
27091c98d778c80e53a7f458264233375f982dcae14Neil Fuller
27191c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private static void assertCreateSubFileThrows(File parentDir, String name) {
27291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        try {
27391c98d778c80e53a7f458264233375f982dcae14Neil Fuller            FileUtils.createSubFile(parentDir, name);
27491c98d778c80e53a7f458264233375f982dcae14Neil Fuller            fail();
27591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        } catch (IOException expected) {
27691c98d778c80e53a7f458264233375f982dcae14Neil Fuller            assertTrue(expected.getMessage().contains("must exist beneath"));
27791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
27891c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
27991c98d778c80e53a7f458264233375f982dcae14Neil Fuller
28091c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private static void assertFilesDoNotExist(File... files) {
28191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        for (File f : files) {
28291c98d778c80e53a7f458264233375f982dcae14Neil Fuller            assertFalse(f + " unexpectedly exists", f.exists());
28391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
28491c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
28591c98d778c80e53a7f458264233375f982dcae14Neil Fuller
28691c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private static void assertFilesExist(File... files) {
28791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        for (File f : files) {
28891c98d778c80e53a7f458264233375f982dcae14Neil Fuller            assertTrue(f + " expected to exist", f.exists());
28991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
29091c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
29191c98d778c80e53a7f458264233375f982dcae14Neil Fuller
29291c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private static void assertDirExistsAndIsAccessible(File dir, boolean requireWorldReadable)
29391c98d778c80e53a7f458264233375f982dcae14Neil Fuller            throws Exception {
29491c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(dir.exists() && dir.isDirectory() && dir.canRead() && dir.canExecute());
29591c98d778c80e53a7f458264233375f982dcae14Neil Fuller
29691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        String path = dir.getCanonicalPath();
29791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        StructStat sb = Libcore.os.stat(path);
29891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        int mask = OsConstants.S_IXUSR | OsConstants.S_IRUSR;
29991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        if (requireWorldReadable) {
30091c98d778c80e53a7f458264233375f982dcae14Neil Fuller            mask = mask | OsConstants.S_IXGRP | OsConstants.S_IRGRP
30191c98d778c80e53a7f458264233375f982dcae14Neil Fuller                    | OsConstants.S_IXOTH | OsConstants.S_IROTH;
30291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
30391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue("Permission mask required: " + Integer.toOctalString(mask),
30491c98d778c80e53a7f458264233375f982dcae14Neil Fuller                (sb.st_mode & mask) == mask);
30591c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
30691c98d778c80e53a7f458264233375f982dcae14Neil Fuller
30791c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private File createTempDir() {
30891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        final String tempPrefix = getClass().getSimpleName();
30991c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File tempDir = IoUtils.createTemporaryDirectory(tempPrefix);
31091c98d778c80e53a7f458264233375f982dcae14Neil Fuller        testFiles.add(tempDir);
31191c98d778c80e53a7f458264233375f982dcae14Neil Fuller        return tempDir;
31291c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
31391c98d778c80e53a7f458264233375f982dcae14Neil Fuller
31491c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private File createDir(File parentDir, String name) {
31591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File dir = new File(parentDir, name);
31691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        assertTrue(dir.mkdir());
31791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        testFiles.add(dir);
31891c98d778c80e53a7f458264233375f982dcae14Neil Fuller        return dir;
31991c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
32091c98d778c80e53a7f458264233375f982dcae14Neil Fuller
32191c98d778c80e53a7f458264233375f982dcae14Neil Fuller    private File createRegularFile(File dir, String name) throws Exception {
32291c98d778c80e53a7f458264233375f982dcae14Neil Fuller        File file = new File(dir, name);
32391c98d778c80e53a7f458264233375f982dcae14Neil Fuller        try (FileOutputStream fos = new FileOutputStream(file)) {
32491c98d778c80e53a7f458264233375f982dcae14Neil Fuller            fos.write("Hello".getBytes());
32591c98d778c80e53a7f458264233375f982dcae14Neil Fuller        }
32691c98d778c80e53a7f458264233375f982dcae14Neil Fuller        testFiles.add(file);
32791c98d778c80e53a7f458264233375f982dcae14Neil Fuller        return file;
32891c98d778c80e53a7f458264233375f982dcae14Neil Fuller    }
32991c98d778c80e53a7f458264233375f982dcae14Neil Fuller}
330