1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.os; 18 19import static android.text.format.DateUtils.DAY_IN_MILLIS; 20import static android.text.format.DateUtils.HOUR_IN_MILLIS; 21import static android.text.format.DateUtils.WEEK_IN_MILLIS; 22 23import android.content.Context; 24import android.test.AndroidTestCase; 25import android.test.suitebuilder.annotation.MediumTest; 26 27import com.google.android.collect.Sets; 28 29import java.io.ByteArrayInputStream; 30import java.io.File; 31import java.io.FileOutputStream; 32import java.io.FileWriter; 33import java.util.Arrays; 34import java.util.HashSet; 35 36import libcore.io.IoUtils; 37 38@MediumTest 39public class FileUtilsTest extends AndroidTestCase { 40 private static final String TEST_DATA = 41 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 42 43 private File mDir; 44 private File mTestFile; 45 private File mCopyFile; 46 47 @Override 48 protected void setUp() throws Exception { 49 super.setUp(); 50 mDir = getContext().getDir("testing", Context.MODE_PRIVATE); 51 mTestFile = new File(mDir, "test.file"); 52 mCopyFile = new File(mDir, "copy.file"); 53 } 54 55 @Override 56 protected void tearDown() throws Exception { 57 IoUtils.deleteContents(mDir); 58 } 59 60 // TODO: test setPermissions(), getPermissions() 61 62 public void testCopyFile() throws Exception { 63 stageFile(mTestFile, TEST_DATA); 64 assertFalse(mCopyFile.exists()); 65 FileUtils.copyFile(mTestFile, mCopyFile); 66 assertTrue(mCopyFile.exists()); 67 assertEquals(TEST_DATA, FileUtils.readTextFile(mCopyFile, 0, null)); 68 } 69 70 public void testCopyToFile() throws Exception { 71 final String s = "Foo Bar"; 72 assertFalse(mCopyFile.exists()); 73 FileUtils.copyToFile(new ByteArrayInputStream(s.getBytes()), mCopyFile); 74 assertTrue(mCopyFile.exists()); 75 assertEquals(s, FileUtils.readTextFile(mCopyFile, 0, null)); 76 } 77 78 public void testIsFilenameSafe() throws Exception { 79 assertTrue(FileUtils.isFilenameSafe(new File("foobar"))); 80 assertTrue(FileUtils.isFilenameSafe(new File("a_b-c=d.e/0,1+23"))); 81 assertFalse(FileUtils.isFilenameSafe(new File("foo*bar"))); 82 assertFalse(FileUtils.isFilenameSafe(new File("foo\nbar"))); 83 } 84 85 public void testReadTextFile() throws Exception { 86 stageFile(mTestFile, TEST_DATA); 87 88 assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, 0, null)); 89 90 assertEquals("ABCDE", FileUtils.readTextFile(mTestFile, 5, null)); 91 assertEquals("ABCDE<>", FileUtils.readTextFile(mTestFile, 5, "<>")); 92 assertEquals(TEST_DATA.substring(0, 51) + "<>", 93 FileUtils.readTextFile(mTestFile, 51, "<>")); 94 assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, 52, "<>")); 95 assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, 100, "<>")); 96 97 assertEquals("vwxyz", FileUtils.readTextFile(mTestFile, -5, null)); 98 assertEquals("<>vwxyz", FileUtils.readTextFile(mTestFile, -5, "<>")); 99 assertEquals("<>" + TEST_DATA.substring(1, 52), 100 FileUtils.readTextFile(mTestFile, -51, "<>")); 101 assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, -52, "<>")); 102 assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, -100, "<>")); 103 } 104 105 public void testReadTextFileWithZeroLengthFile() throws Exception { 106 stageFile(mTestFile, TEST_DATA); 107 new FileOutputStream(mTestFile).close(); // Zero out the file 108 assertEquals("", FileUtils.readTextFile(mTestFile, 0, null)); 109 assertEquals("", FileUtils.readTextFile(mTestFile, 1, "<>")); 110 assertEquals("", FileUtils.readTextFile(mTestFile, 10, "<>")); 111 assertEquals("", FileUtils.readTextFile(mTestFile, -1, "<>")); 112 assertEquals("", FileUtils.readTextFile(mTestFile, -10, "<>")); 113 } 114 115 public void testDeleteOlderEmptyDir() throws Exception { 116 FileUtils.deleteOlderFiles(mDir, 10, WEEK_IN_MILLIS); 117 assertDirContents(); 118 } 119 120 public void testDeleteOlderTypical() throws Exception { 121 touch("file1", HOUR_IN_MILLIS); 122 touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 123 touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 124 touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 125 touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 126 FileUtils.deleteOlderFiles(mDir, 3, DAY_IN_MILLIS); 127 assertDirContents("file1", "file2", "file3"); 128 } 129 130 public void testDeleteOlderInFuture() throws Exception { 131 touch("file1", -HOUR_IN_MILLIS); 132 touch("file2", HOUR_IN_MILLIS); 133 touch("file3", WEEK_IN_MILLIS); 134 FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS); 135 assertDirContents("file1", "file2"); 136 137 touch("file1", -HOUR_IN_MILLIS); 138 touch("file2", HOUR_IN_MILLIS); 139 touch("file3", WEEK_IN_MILLIS); 140 FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS); 141 assertDirContents("file1", "file2"); 142 } 143 144 public void testDeleteOlderOnlyAge() throws Exception { 145 touch("file1", HOUR_IN_MILLIS); 146 touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 147 touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 148 touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 149 touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 150 FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS); 151 assertDirContents("file1"); 152 } 153 154 public void testDeleteOlderOnlyCount() throws Exception { 155 touch("file1", HOUR_IN_MILLIS); 156 touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 157 touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 158 touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 159 touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS); 160 FileUtils.deleteOlderFiles(mDir, 2, 0); 161 assertDirContents("file1", "file2"); 162 } 163 164 private void touch(String name, long age) throws Exception { 165 final File file = new File(mDir, name); 166 file.createNewFile(); 167 file.setLastModified(System.currentTimeMillis() - age); 168 } 169 170 private void stageFile(File file, String data) throws Exception { 171 FileWriter writer = new FileWriter(file); 172 try { 173 writer.write(data, 0, data.length()); 174 } finally { 175 writer.close(); 176 } 177 } 178 179 private void assertDirContents(String... expected) { 180 final HashSet<String> expectedSet = Sets.newHashSet(expected); 181 String[] actual = mDir.list(); 182 if (actual == null) actual = new String[0]; 183 184 assertEquals( 185 "Expected " + Arrays.toString(expected) + " but actual " + Arrays.toString(actual), 186 expected.length, actual.length); 187 for (String actualFile : actual) { 188 assertTrue("Unexpected actual file " + actualFile, expectedSet.contains(actualFile)); 189 } 190 } 191} 192