1 /* 2 * Copyright (C) 2010 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 package com.android.tradefed.util; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assert.fail; 22 23 import com.android.tradefed.log.LogUtil.CLog; 24 import com.android.tradefed.result.LogDataType; 25 26 import org.junit.Before; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.junit.runners.JUnit4; 30 31 import java.io.ByteArrayInputStream; 32 import java.io.File; 33 import java.io.IOException; 34 import java.io.InputStream; 35 import java.nio.file.attribute.PosixFilePermission; 36 import java.util.Set; 37 38 /** Unit tests for {@link FileUtil} */ 39 @RunWith(JUnit4.class) 40 public class FileUtilTest { 41 42 @Before 43 public void setUp() throws Exception { 44 FileUtil.setChmodBinary("chmod"); 45 } 46 47 /** test {@link FileUtil#getExtension(String)} */ 48 @Test 49 public void testGetExtension() { 50 assertEquals("", FileUtil.getExtension("filewithoutext")); 51 assertEquals(".txt", FileUtil.getExtension("file.txt")); 52 assertEquals(".txt", FileUtil.getExtension("foo.file.txt")); 53 } 54 55 /** test {@link FileUtil#chmodGroupRW(File)} on a system that supports 'chmod' */ 56 @Test 57 public void testChmodGroupRW() throws IOException { 58 File testFile = null; 59 try { 60 if (!FileUtil.chmodExists()) { 61 CLog.d("Chmod not available, skipping the test"); 62 return; 63 } 64 testFile = FileUtil.createTempFile("testChmodRW", ".txt"); 65 assertTrue(FileUtil.chmodGroupRW(testFile)); 66 assertTrue(testFile.canRead()); 67 assertTrue(testFile.canWrite()); 68 assertFalse(testFile.canExecute()); 69 } finally { 70 FileUtil.deleteFile(testFile); 71 } 72 } 73 74 /** 75 * test {@link FileUtil#chmodGroupRW(File)} on a system that does not supports 'chmod'. File 76 * permission should still be set with the fallback. 77 */ 78 @Test 79 public void testChmodGroupRW_noChmod() throws IOException { 80 File testFile = null; 81 FileUtil.setChmodBinary("fake_not_existing_chmod"); 82 try { 83 testFile = FileUtil.createTempFile("testChmodRW", ".txt"); 84 assertTrue(FileUtil.chmodGroupRW(testFile)); 85 assertTrue(testFile.canRead()); 86 assertTrue(testFile.canWrite()); 87 assertFalse(testFile.canExecute()); 88 } finally { 89 FileUtil.deleteFile(testFile); 90 } 91 } 92 93 /** test {@link FileUtil#chmodGroupRWX(File)} on a system that supports 'chmod' */ 94 @Test 95 public void testChmodGroupRWX() throws IOException { 96 File testFile = null; 97 try { 98 if (!FileUtil.chmodExists()) { 99 CLog.d("Chmod not available, skipping the test"); 100 return; 101 } 102 testFile = FileUtil.createTempFile("testChmodRWX", ".txt"); 103 assertTrue(FileUtil.chmodGroupRWX(testFile)); 104 assertTrue(testFile.canRead()); 105 assertTrue(testFile.canWrite()); 106 assertTrue(testFile.canExecute()); 107 } finally { 108 FileUtil.deleteFile(testFile); 109 } 110 } 111 112 /** 113 * test {@link FileUtil#chmodGroupRWX(File)} on a system that does not supports 'chmod'. File 114 * permission should still be set with the fallback. 115 */ 116 @Test 117 public void testChmodGroupRWX_noChmod() throws IOException { 118 File testFile = null; 119 FileUtil.setChmodBinary("fake_not_existing_chmod"); 120 try { 121 testFile = FileUtil.createTempFile("testChmodRWX", ".txt"); 122 assertTrue(FileUtil.chmodGroupRWX(testFile)); 123 assertTrue(testFile.canRead()); 124 assertTrue(testFile.canWrite()); 125 assertTrue(testFile.canExecute()); 126 } finally { 127 FileUtil.deleteFile(testFile); 128 } 129 } 130 131 /** 132 * test {@link FileUtil#createTempFile(String, String)} with a very long file name. FileSystem 133 * should not throw any exception. 134 */ 135 @Test 136 public void testCreateTempFile_filenameTooLong() throws IOException { 137 File testFile = null; 138 try { 139 final String prefix = "logcat-android.support.v7.widget.GridLayoutManagerWrapContent" 140 + "WithAspectRatioTest_testAllChildrenWrapContentInOtherDirection_" 141 + "WrapContentConfig_unlimitedWidth=true_ unlimitedHeight=true_padding=" 142 + "Rect(0_0-0_0)_Config_mSpanCount=3_ mOrientation=v_mItemCount=1000_" 143 + "mReverseLayout=false_ 8__"; 144 testFile = FileUtil.createTempFile(prefix, ".gz"); 145 assertTrue(testFile.getName().length() <= FileUtil.FILESYSTEM_FILENAME_MAX_LENGTH); 146 } finally { 147 FileUtil.deleteFile(testFile); 148 } 149 } 150 151 /** 152 * test {@link FileUtil#createTempFile(String, String)} with a very long file name. FileSystem 153 * should not throw any exception. If both suffix is smaller than overflow length, it will be 154 * completely truncated, and prefix will truncate the remaining. 155 */ 156 @Test 157 public void testCreateTempFile_filenameTooLongEdge() throws IOException { 158 File testFile = null; 159 try { 160 final String prefix = "logcat-android.support.v7.widget.GridLayoutManagerWrapContent" 161 + "WithAspectRatioTest_testAllChildrenWrapContentInOtherDirection_" 162 + "WrapContentConfig_unlimitedWidth=true_ unlimitedHeight=true_padding=" 163 + "Rect(0_0-0_0)_Config_mSpanCount=3_ mOrientation"; 164 final String suffix = "logcat-android.support.v7.widget.GridLayoutManagerWrapContent" 165 + "WithAspectRatioTest_testAllChildrenWrapContentInOtherDirection_" 166 + "WrapContentConfig_unlimitedWidth=true_ unlimitedHeight=true_padding=" 167 + "Rect(0_0-0_0)_Config_mSpanCount=3_ mOrientat"; 168 testFile = FileUtil.createTempFile(prefix, suffix); 169 assertTrue(testFile.getName().length() <= FileUtil.FILESYSTEM_FILENAME_MAX_LENGTH); 170 } finally { 171 FileUtil.deleteFile(testFile); 172 } 173 } 174 175 /** 176 * Test {@link FileUtil#writeToFile(InputStream, File, boolean)} succeeds overwriting an 177 * existent file. 178 */ 179 @Test 180 public void testWriteToFile_overwrites_exists() throws IOException { 181 File testFile = null; 182 try { 183 testFile = File.createTempFile("doesnotmatter", ".txt"); 184 FileUtil.writeToFile(new ByteArrayInputStream("write1".getBytes()), testFile, false); 185 assertEquals(FileUtil.readStringFromFile(testFile), "write1"); 186 FileUtil.writeToFile(new ByteArrayInputStream("write2".getBytes()), testFile, false); 187 assertEquals(FileUtil.readStringFromFile(testFile), "write2"); 188 } finally { 189 FileUtil.deleteFile(testFile); 190 } 191 } 192 193 /** 194 * Test {@link FileUtil#writeToFile(InputStream, File, boolean)} succeeds appending to an 195 * existent file. 196 */ 197 @Test 198 public void testWriteToFile_appends_exists() throws IOException { 199 File testFile = null; 200 try { 201 testFile = File.createTempFile("doesnotmatter", ".txt"); 202 FileUtil.writeToFile(new ByteArrayInputStream("write1".getBytes()), testFile, true); 203 FileUtil.writeToFile(new ByteArrayInputStream("write2".getBytes()), testFile, true); 204 assertEquals(FileUtil.readStringFromFile(testFile), "write1write2"); 205 } finally { 206 FileUtil.deleteFile(testFile); 207 } 208 } 209 210 /** 211 * Test {@link FileUtil#writeToFile(InputStream, File, boolean)} succeeds writing to an 212 * uncreated file. 213 */ 214 @Test 215 public void testWriteToFile_overwrites_doesNotExist() throws IOException { 216 File testFile = null; 217 try { 218 testFile = FileUtil.createTempFile("fileutiltest", ".test"); 219 FileUtil.deleteFile(testFile); 220 FileUtil.writeToFile(new ByteArrayInputStream("write1".getBytes()), testFile, false); 221 assertEquals("write1", FileUtil.readStringFromFile(testFile)); 222 } finally { 223 FileUtil.deleteFile(testFile); 224 } 225 } 226 227 /** 228 * Test {@link FileUtil#writeToFile(InputStream, File, boolean)} succeeds appending to an 229 * uncreated file. 230 */ 231 @Test 232 public void testWriteToFile_appends_doesNotExist() throws IOException { 233 File testFile = null; 234 try { 235 testFile = FileUtil.createTempFile("fileutiltest", ".test"); 236 FileUtil.deleteFile(testFile); 237 FileUtil.writeToFile(new ByteArrayInputStream("write1".getBytes()), testFile, true); 238 assertEquals("write1", FileUtil.readStringFromFile(testFile)); 239 } finally { 240 FileUtil.deleteFile(testFile); 241 } 242 } 243 244 /** Test {@link FileUtil#writeToFile(InputStream, File)} succeeds overwriting to a file. */ 245 @Test 246 public void testWriteToFile_stream_overwrites() throws IOException { 247 File testFile = null; 248 try { 249 testFile = File.createTempFile("doesnotmatter", ".txt"); 250 FileUtil.writeToFile(new ByteArrayInputStream("write1".getBytes()), testFile); 251 assertEquals(FileUtil.readStringFromFile(testFile), "write1"); 252 FileUtil.writeToFile(new ByteArrayInputStream("write2".getBytes()), testFile); 253 assertEquals(FileUtil.readStringFromFile(testFile), "write2"); 254 } finally { 255 FileUtil.deleteFile(testFile); 256 } 257 } 258 259 /** Test {@link FileUtil#writeToFile(String, File, boolean)} succeeds overwriting to a file. */ 260 @Test 261 public void testWriteToFile_string_overwrites() throws IOException { 262 File testFile = null; 263 try { 264 testFile = File.createTempFile("doesnotmatter", ".txt"); 265 FileUtil.writeToFile("write1", testFile, false); 266 assertEquals(FileUtil.readStringFromFile(testFile), "write1"); 267 FileUtil.writeToFile("write2", testFile, false); 268 assertEquals(FileUtil.readStringFromFile(testFile), "write2"); 269 } finally { 270 FileUtil.deleteFile(testFile); 271 } 272 } 273 274 /** Test {@link FileUtil#writeToFile(String, File, boolean)} succeeds appending to a file. */ 275 @Test 276 public void testWriteToFile_string_appends() throws IOException { 277 File testFile = null; 278 try { 279 testFile = File.createTempFile("doesnotmatter", ".txt"); 280 FileUtil.writeToFile("write1", testFile, true); 281 FileUtil.writeToFile("write2", testFile, true); 282 assertEquals(FileUtil.readStringFromFile(testFile), "write1write2"); 283 } finally { 284 FileUtil.deleteFile(testFile); 285 } 286 } 287 288 /** Test {@link FileUtil#writeToFile(String, File)} succeeds overwriting to a file. */ 289 @Test 290 public void testWriteToFile_string_defaultOverwrites() throws IOException { 291 File testFile = null; 292 try { 293 testFile = File.createTempFile("doesnotmatter", ".txt"); 294 FileUtil.writeToFile("write1", testFile); 295 assertEquals(FileUtil.readStringFromFile(testFile), "write1"); 296 FileUtil.writeToFile("write2", testFile); 297 assertEquals(FileUtil.readStringFromFile(testFile), "write2"); 298 } finally { 299 FileUtil.deleteFile(testFile); 300 } 301 } 302 303 /** Test {@link FileUtil#unixModeToPosix(int)} returns expected results; */ 304 @Test 305 public void testUnixModeToPosix() { 306 Set<PosixFilePermission> perms = null; 307 // can't test all 8 * 8 * 8, so just a select few 308 perms = FileUtil.unixModeToPosix(0777); 309 assertTrue("failed unix mode conversion: 0777", 310 perms.remove(PosixFilePermission.OWNER_READ) && 311 perms.remove(PosixFilePermission.OWNER_WRITE) && 312 perms.remove(PosixFilePermission.OWNER_EXECUTE) && 313 perms.remove(PosixFilePermission.GROUP_READ) && 314 perms.remove(PosixFilePermission.GROUP_WRITE) && 315 perms.remove(PosixFilePermission.GROUP_EXECUTE) && 316 perms.remove(PosixFilePermission.OTHERS_READ) && 317 perms.remove(PosixFilePermission.OTHERS_WRITE) && 318 perms.remove(PosixFilePermission.OTHERS_EXECUTE) && 319 perms.isEmpty()); 320 perms = FileUtil.unixModeToPosix(0644); 321 assertTrue("failed unix mode conversion: 0644", 322 perms.remove(PosixFilePermission.OWNER_READ) && 323 perms.remove(PosixFilePermission.OWNER_WRITE) && 324 perms.remove(PosixFilePermission.GROUP_READ) && 325 perms.remove(PosixFilePermission.OTHERS_READ) && 326 perms.isEmpty()); 327 perms = FileUtil.unixModeToPosix(0755); 328 assertTrue("failed unix mode conversion: 0755", 329 perms.remove(PosixFilePermission.OWNER_READ) && 330 perms.remove(PosixFilePermission.OWNER_WRITE) && 331 perms.remove(PosixFilePermission.OWNER_EXECUTE) && 332 perms.remove(PosixFilePermission.GROUP_READ) && 333 perms.remove(PosixFilePermission.GROUP_EXECUTE) && 334 perms.remove(PosixFilePermission.OTHERS_READ) && 335 perms.remove(PosixFilePermission.OTHERS_EXECUTE) && 336 perms.isEmpty()); 337 } 338 339 /** Test {@link FileUtil#findFiles(File, String)} can find files successfully. */ 340 @Test 341 public void testFindFilesSuccess() throws IOException { 342 File tmpDir = FileUtil.createTempDir("find_files_test"); 343 try { 344 File matchFile1 = FileUtil.createTempFile("test", ".config", tmpDir); 345 File subDir = new File(tmpDir, "subfolder"); 346 subDir.mkdirs(); 347 File matchFile2 = FileUtil.createTempFile("test", ".config", subDir); 348 FileUtil.createTempFile("test", ".xml", subDir); 349 Set<String> matchFiles = FileUtil.findFiles(tmpDir, ".*.config"); 350 assertTrue(matchFiles.contains(matchFile1.getAbsolutePath())); 351 assertTrue(matchFiles.contains(matchFile2.getAbsolutePath())); 352 assertEquals(matchFiles.size(), 2); 353 } finally { 354 FileUtil.recursiveDelete(tmpDir); 355 } 356 } 357 358 /** 359 * Test that using {@link FileUtil#findFiles(File, String)} works when one of the directory is a 360 * symlink. 361 */ 362 @Test 363 public void testFindFilesSuccess_symlink() throws IOException { 364 File tmpDir = FileUtil.createTempDir("find_files_test"); 365 File subDir = FileUtil.createTempDir("subfolder"); 366 try { 367 File matchFile1 = FileUtil.createTempFile("test", ".config", tmpDir); 368 File matchFile2 = FileUtil.createTempFile("test", ".config", subDir); 369 File destLink = new File(tmpDir, "subFolder"); 370 FileUtil.symlinkFile(subDir, destLink); 371 FileUtil.createTempFile("test", ".xml", subDir); 372 Set<String> matchFiles = FileUtil.findFiles(tmpDir, ".*.config"); 373 assertTrue(matchFiles.contains(matchFile1.getAbsolutePath())); 374 // The file is returned under the directory of the symlink not the original location. 375 assertTrue( 376 matchFiles.contains( 377 new File(destLink, matchFile2.getName()).getAbsolutePath())); 378 assertEquals(matchFiles.size(), 2); 379 } finally { 380 FileUtil.recursiveDelete(tmpDir); 381 FileUtil.recursiveDelete(subDir); 382 } 383 } 384 385 /** 386 * Test {@link FileUtil#findFiles(File, String)} returns empty set if no file matches filter. 387 */ 388 @Test 389 public void testFindFilesFail() throws IOException { 390 File tmpDir = FileUtil.createTempDir("find_files_test"); 391 try { 392 FileUtil.createTempFile("test", ".config", tmpDir); 393 File subDir = new File(tmpDir, "subfolder"); 394 subDir.mkdirs(); 395 FileUtil.createTempFile("test", ".config", subDir); 396 Set<String> matchFiles = FileUtil.findFiles(tmpDir, ".*.config_x"); 397 assertEquals(matchFiles.size(), 0); 398 } finally { 399 FileUtil.recursiveDelete(tmpDir); 400 } 401 } 402 403 @Test 404 public void testGetContentType_text() throws Exception { 405 assertEquals(LogDataType.TEXT.getContentType(), 406 FileUtil.getContentType("path/to/file.txt")); 407 } 408 409 @Test 410 public void testGetContentType_html() throws Exception { 411 assertEquals(LogDataType.HTML.getContentType(), 412 FileUtil.getContentType("path/to/file.html")); 413 } 414 415 @Test 416 public void testGetContentType_png() throws Exception { 417 assertEquals(LogDataType.PNG.getContentType(), 418 FileUtil.getContentType("path/to/file.png")); 419 } 420 421 /** Test {@link FileUtil#findFile(File, String)} when finding a file. */ 422 @Test 423 public void testFindFile() throws IOException { 424 File tmpDir = FileUtil.createTempDir("find_file_test"); 425 try { 426 File subDir = FileUtil.createTempDir("sub_find_file_test", tmpDir); 427 File subFile = FileUtil.createTempFile("find_file_file", ".txt", subDir); 428 File res = FileUtil.findFile(tmpDir, subFile.getName()); 429 assertEquals(subFile.getAbsolutePath(), res.getAbsolutePath()); 430 } finally { 431 FileUtil.recursiveDelete(tmpDir); 432 } 433 } 434 435 /** 436 * Test {@link FileUtil#findFile(File, String)} when finding a file that has the same name as 437 * its directory, the File should be be returned in that case. 438 */ 439 @Test 440 public void testFindFile_sameDirName() throws IOException { 441 File tmpDir = FileUtil.createTempDir("find_file_test"); 442 try { 443 File subDir = FileUtil.createTempDir("find_file_file", tmpDir); 444 File subFile = FileUtil.createTempFile("find_file_file", "", subDir); 445 File res = FileUtil.findFile(tmpDir, subFile.getName()); 446 assertEquals(subFile.getAbsolutePath(), res.getAbsolutePath()); 447 } finally { 448 FileUtil.recursiveDelete(tmpDir); 449 } 450 } 451 452 /** 453 * Test {@link FileUtil#findFile(File, String)} when searching a File, if a directory match the 454 * name, and not child file does, then return the directory matching the file. 455 */ 456 @Test 457 public void testFindFile_directory() throws IOException { 458 File tmpDir = FileUtil.createTempDir("find_file_test"); 459 try { 460 File subDir = FileUtil.createTempDir("find_file_file", tmpDir); 461 FileUtil.createTempFile("sub_file_file", ".txt", subDir); 462 File res = FileUtil.findFile(tmpDir, subDir.getName()); 463 assertEquals(subDir.getAbsolutePath(), res.getAbsolutePath()); 464 } finally { 465 FileUtil.recursiveDelete(tmpDir); 466 } 467 } 468 469 /** 470 * Test {@link FileUtil#findDirsUnder(File, File)} when root dir is not a directory, it should 471 * throw an exception. 472 */ 473 @Test 474 public void testFindDirsUnder_exception() throws IOException { 475 File illegalRoot = FileUtil.createTempFile("find_under", ".txt"); 476 try { 477 FileUtil.findDirsUnder(illegalRoot, null); 478 fail("Should have thrown an exception."); 479 } catch (IllegalArgumentException expected) { 480 // expected 481 } finally { 482 FileUtil.recursiveDelete(illegalRoot); 483 } 484 } 485 } 486