The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
Neal Nguyen | 1a44d5d | 2010-01-13 10:42:43 -0800 | [diff] [blame] | 17 | package android.os; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 18 | |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 19 | import static android.text.format.DateUtils.DAY_IN_MILLIS; |
| 20 | import static android.text.format.DateUtils.HOUR_IN_MILLIS; |
| 21 | import static android.text.format.DateUtils.WEEK_IN_MILLIS; |
| 22 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 23 | import android.content.Context; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 24 | import android.test.AndroidTestCase; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 25 | import android.test.suitebuilder.annotation.MediumTest; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 26 | |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 27 | import com.google.android.collect.Sets; |
| 28 | |
Jeff Sharkey | 4ca728c | 2014-01-10 16:27:19 -0800 | [diff] [blame] | 29 | import libcore.io.IoUtils; |
| 30 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 31 | import java.io.ByteArrayInputStream; |
| 32 | import java.io.File; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 33 | import java.io.FileOutputStream; |
Kenny Root | 98e15e7 | 2012-08-16 11:38:04 -0700 | [diff] [blame] | 34 | import java.io.FileWriter; |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 35 | import java.util.Arrays; |
| 36 | import java.util.HashSet; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 37 | |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 38 | @MediumTest |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 39 | public class FileUtilsTest extends AndroidTestCase { |
| 40 | private static final String TEST_DATA = |
| 41 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
| 42 | |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 43 | private File mDir; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 44 | private File mTestFile; |
| 45 | private File mCopyFile; |
| 46 | |
| 47 | @Override |
| 48 | protected void setUp() throws Exception { |
| 49 | super.setUp(); |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 50 | mDir = getContext().getDir("testing", Context.MODE_PRIVATE); |
| 51 | mTestFile = new File(mDir, "test.file"); |
| 52 | mCopyFile = new File(mDir, "copy.file"); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | @Override |
| 56 | protected void tearDown() throws Exception { |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 57 | IoUtils.deleteContents(mDir); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 58 | } |
| 59 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 60 | // TODO: test setPermissions(), getPermissions() |
| 61 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 62 | public void testCopyFile() throws Exception { |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 63 | stageFile(mTestFile, TEST_DATA); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 64 | assertFalse(mCopyFile.exists()); |
| 65 | FileUtils.copyFile(mTestFile, mCopyFile); |
| 66 | assertTrue(mCopyFile.exists()); |
| 67 | assertEquals(TEST_DATA, FileUtils.readTextFile(mCopyFile, 0, null)); |
| 68 | } |
| 69 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 70 | public void testCopyToFile() throws Exception { |
| 71 | final String s = "Foo Bar"; |
| 72 | assertFalse(mCopyFile.exists()); |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 73 | FileUtils.copyToFile(new ByteArrayInputStream(s.getBytes()), mCopyFile); |
| 74 | assertTrue(mCopyFile.exists()); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 75 | assertEquals(s, FileUtils.readTextFile(mCopyFile, 0, null)); |
| 76 | } |
| 77 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 85 | public void testReadTextFile() throws Exception { |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 86 | stageFile(mTestFile, TEST_DATA); |
| 87 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 105 | public void testReadTextFileWithZeroLengthFile() throws Exception { |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 106 | stageFile(mTestFile, TEST_DATA); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | } |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 114 | |
Jeff Sharkey | 4ca728c | 2014-01-10 16:27:19 -0800 | [diff] [blame] | 115 | public void testContains() throws Exception { |
| 116 | assertTrue(FileUtils.contains(new File("/"), new File("/moo.txt"))); |
| 117 | assertTrue(FileUtils.contains(new File("/"), new File("/"))); |
| 118 | |
| 119 | assertTrue(FileUtils.contains(new File("/sdcard"), new File("/sdcard"))); |
| 120 | assertTrue(FileUtils.contains(new File("/sdcard/"), new File("/sdcard/"))); |
| 121 | |
| 122 | assertTrue(FileUtils.contains(new File("/sdcard"), new File("/sdcard/moo.txt"))); |
| 123 | assertTrue(FileUtils.contains(new File("/sdcard/"), new File("/sdcard/moo.txt"))); |
| 124 | |
| 125 | assertFalse(FileUtils.contains(new File("/sdcard"), new File("/moo.txt"))); |
| 126 | assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/moo.txt"))); |
| 127 | |
| 128 | assertFalse(FileUtils.contains(new File("/sdcard"), new File("/sdcard.txt"))); |
| 129 | assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/sdcard.txt"))); |
| 130 | } |
| 131 | |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 132 | public void testDeleteOlderEmptyDir() throws Exception { |
| 133 | FileUtils.deleteOlderFiles(mDir, 10, WEEK_IN_MILLIS); |
| 134 | assertDirContents(); |
| 135 | } |
| 136 | |
| 137 | public void testDeleteOlderTypical() throws Exception { |
| 138 | touch("file1", HOUR_IN_MILLIS); |
| 139 | touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 140 | touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 141 | touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 142 | touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
Jeff Sharkey | ebf8ad5 | 2014-01-30 15:01:22 -0800 | [diff] [blame] | 143 | assertTrue(FileUtils.deleteOlderFiles(mDir, 3, DAY_IN_MILLIS)); |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 144 | assertDirContents("file1", "file2", "file3"); |
| 145 | } |
| 146 | |
| 147 | public void testDeleteOlderInFuture() throws Exception { |
| 148 | touch("file1", -HOUR_IN_MILLIS); |
| 149 | touch("file2", HOUR_IN_MILLIS); |
| 150 | touch("file3", WEEK_IN_MILLIS); |
Jeff Sharkey | ebf8ad5 | 2014-01-30 15:01:22 -0800 | [diff] [blame] | 151 | assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS)); |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 152 | assertDirContents("file1", "file2"); |
| 153 | |
| 154 | touch("file1", -HOUR_IN_MILLIS); |
| 155 | touch("file2", HOUR_IN_MILLIS); |
| 156 | touch("file3", WEEK_IN_MILLIS); |
Jeff Sharkey | ebf8ad5 | 2014-01-30 15:01:22 -0800 | [diff] [blame] | 157 | assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS)); |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 158 | assertDirContents("file1", "file2"); |
| 159 | } |
| 160 | |
| 161 | public void testDeleteOlderOnlyAge() throws Exception { |
| 162 | touch("file1", HOUR_IN_MILLIS); |
| 163 | touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 164 | touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 165 | touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 166 | touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
Jeff Sharkey | ebf8ad5 | 2014-01-30 15:01:22 -0800 | [diff] [blame] | 167 | assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS)); |
| 168 | assertFalse(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS)); |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 169 | assertDirContents("file1"); |
| 170 | } |
| 171 | |
| 172 | public void testDeleteOlderOnlyCount() throws Exception { |
| 173 | touch("file1", HOUR_IN_MILLIS); |
| 174 | touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 175 | touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 176 | touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
| 177 | touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS); |
Jeff Sharkey | ebf8ad5 | 2014-01-30 15:01:22 -0800 | [diff] [blame] | 178 | assertTrue(FileUtils.deleteOlderFiles(mDir, 2, 0)); |
| 179 | assertFalse(FileUtils.deleteOlderFiles(mDir, 2, 0)); |
Jeff Sharkey | d952690 | 2013-03-14 14:11:57 -0700 | [diff] [blame] | 180 | assertDirContents("file1", "file2"); |
| 181 | } |
| 182 | |
| 183 | private void touch(String name, long age) throws Exception { |
| 184 | final File file = new File(mDir, name); |
| 185 | file.createNewFile(); |
| 186 | file.setLastModified(System.currentTimeMillis() - age); |
| 187 | } |
| 188 | |
| 189 | private void stageFile(File file, String data) throws Exception { |
| 190 | FileWriter writer = new FileWriter(file); |
| 191 | try { |
| 192 | writer.write(data, 0, data.length()); |
| 193 | } finally { |
| 194 | writer.close(); |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | private void assertDirContents(String... expected) { |
| 199 | final HashSet<String> expectedSet = Sets.newHashSet(expected); |
| 200 | String[] actual = mDir.list(); |
| 201 | if (actual == null) actual = new String[0]; |
| 202 | |
| 203 | assertEquals( |
| 204 | "Expected " + Arrays.toString(expected) + " but actual " + Arrays.toString(actual), |
| 205 | expected.length, actual.length); |
| 206 | for (String actualFile : actual) { |
| 207 | assertTrue("Unexpected actual file " + actualFile, expectedSet.contains(actualFile)); |
| 208 | } |
| 209 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 210 | } |