Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <fstream> | 9 #include <fstream> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 | 185 |
| 186 // file_util winds up using autoreleased objects on the Mac, so this needs | 186 // file_util winds up using autoreleased objects on the Mac, so this needs |
| 187 // to be a PlatformTest | 187 // to be a PlatformTest |
| 188 class FileUtilTest : public PlatformTest { | 188 class FileUtilTest : public PlatformTest { |
| 189 protected: | 189 protected: |
| 190 void SetUp() override { | 190 void SetUp() override { |
| 191 PlatformTest::SetUp(); | 191 PlatformTest::SetUp(); |
| 192 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 192 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 193 } | 193 } |
| 194 | 194 |
| 195 // Sets the file to read-only. | |
| 196 static void SetReadOnly(const FilePath& path, bool read_only) { | |
| 197 #if defined(OS_WIN) | |
| 198 // On Windows, it involves setting/removing the 'readonly' bit. | |
| 199 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
| 200 ASSERT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
|
Nico
2017/01/10 18:31:55
I thought ASSERT doesn't do the right thing in hel
grt (UTC plus 2)
2017/01/12 15:07:03
Indeed! I've added ASSERT_NO_FATAL_FAILURE where r
| |
| 201 ASSERT_TRUE(SetFileAttributes( | |
| 202 path.value().c_str(), read_only ? (attrs | FILE_ATTRIBUTE_READONLY) | |
| 203 : (attrs & ~FILE_ATTRIBUTE_READONLY))); | |
| 204 | |
| 205 DWORD expected = | |
| 206 read_only | |
| 207 ? ((attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)) | | |
| 208 FILE_ATTRIBUTE_READONLY) | |
| 209 : (attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)); | |
| 210 | |
| 211 // Ignore FILE_ATTRIBUTE_NOT_CONTENT_INDEXED if present. | |
| 212 attrs = GetFileAttributes(path.value().c_str()) & | |
| 213 ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; | |
| 214 ASSERT_EQ(expected, attrs); | |
| 215 #else | |
| 216 // On all other platforms, it involves removing/setting the write bit. | |
| 217 mode_t mode = read_only ? S_IRUSR : (S_IRUSR | S_IWUSR); | |
| 218 EXPECT_TRUE(SetPosixFilePermissions( | |
| 219 path, DirectoryExists(path) ? (mode | S_IXUSR) : mode)); | |
| 220 #endif | |
| 221 } | |
| 222 | |
| 223 static bool IsReadOnly(const FilePath& path) { | |
| 224 #if defined(OS_WIN) | |
| 225 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
| 226 EXPECT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
| 227 return attrs & FILE_ATTRIBUTE_READONLY; | |
| 228 #else | |
| 229 int mode = 0; | |
| 230 EXPECT_TRUE(GetPosixFilePermissions(path, &mode)); | |
| 231 return !(mode & S_IWUSR); | |
| 232 #endif | |
| 233 } | |
| 234 | |
| 195 ScopedTempDir temp_dir_; | 235 ScopedTempDir temp_dir_; |
| 196 }; | 236 }; |
| 197 | 237 |
| 198 // Collects all the results from the given file enumerator, and provides an | 238 // Collects all the results from the given file enumerator, and provides an |
| 199 // interface to query whether a given file is present. | 239 // interface to query whether a given file is present. |
| 200 class FindResultCollector { | 240 class FindResultCollector { |
| 201 public: | 241 public: |
| 202 explicit FindResultCollector(FileEnumerator* enumerator) { | 242 explicit FindResultCollector(FileEnumerator* enumerator) { |
| 203 FilePath cur_file; | 243 FilePath cur_file; |
| 204 while (!(cur_file = enumerator->Next()).value().empty()) { | 244 while (!(cur_file = enumerator->Next()).value().empty()) { |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 // Test recursive case, create a new file | 700 // Test recursive case, create a new file |
| 661 file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 2.txt")); | 701 file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 2.txt")); |
| 662 CreateTextFile(file_name, bogus_content); | 702 CreateTextFile(file_name, bogus_content); |
| 663 ASSERT_TRUE(PathExists(file_name)); | 703 ASSERT_TRUE(PathExists(file_name)); |
| 664 | 704 |
| 665 // Make sure it's deleted | 705 // Make sure it's deleted |
| 666 EXPECT_TRUE(DeleteFile(file_name, true)); | 706 EXPECT_TRUE(DeleteFile(file_name, true)); |
| 667 EXPECT_FALSE(PathExists(file_name)); | 707 EXPECT_FALSE(PathExists(file_name)); |
| 668 } | 708 } |
| 669 | 709 |
| 710 TEST_F(FileUtilTest, DeleteReadOnlyFile) { | |
| 711 // Create a read-only file | |
|
Nico
2017/01/10 18:31:55
nit: style guide says comments should be sentences
grt (UTC plus 2)
2017/01/12 15:07:03
Done.
| |
| 712 FilePath file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 1.txt")); | |
| 713 CreateTextFile(file_name, bogus_content); | |
| 714 ASSERT_TRUE(PathExists(file_name)); | |
| 715 SetReadOnly(file_name, true); | |
| 716 ASSERT_TRUE(IsReadOnly(file_name)); | |
| 717 | |
| 718 // Make sure it's deleted | |
| 719 EXPECT_TRUE(DeleteFile(file_name, false)); | |
| 720 EXPECT_FALSE(PathExists(file_name)); | |
| 721 | |
| 722 // Test recursive case, create a new file | |
| 723 file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 2.txt")); | |
| 724 CreateTextFile(file_name, bogus_content); | |
| 725 ASSERT_TRUE(PathExists(file_name)); | |
| 726 SetReadOnly(file_name, true); | |
| 727 ASSERT_TRUE(IsReadOnly(file_name)); | |
| 728 | |
| 729 // Make sure it's deleted | |
| 730 EXPECT_TRUE(DeleteFile(file_name, true)); | |
| 731 EXPECT_FALSE(PathExists(file_name)); | |
| 732 } | |
| 733 | |
| 670 #if defined(OS_POSIX) | 734 #if defined(OS_POSIX) |
| 671 TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) { | 735 TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) { |
| 672 // Create a file. | 736 // Create a file. |
| 673 FilePath file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 2.txt")); | 737 FilePath file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 2.txt")); |
| 674 CreateTextFile(file_name, bogus_content); | 738 CreateTextFile(file_name, bogus_content); |
| 675 ASSERT_TRUE(PathExists(file_name)); | 739 ASSERT_TRUE(PathExists(file_name)); |
| 676 | 740 |
| 677 // Create a symlink to the file. | 741 // Create a symlink to the file. |
| 678 FilePath file_link = temp_dir_.GetPath().Append("file_link_2"); | 742 FilePath file_link = temp_dir_.GetPath().Append("file_link_2"); |
| 679 ASSERT_TRUE(CreateSymbolicLink(file_name, file_link)) | 743 ASSERT_TRUE(CreateSymbolicLink(file_name, file_link)) |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 875 ASSERT_TRUE(SetPosixFilePermissions(dir1.Append(kExeFileName), | 939 ASSERT_TRUE(SetPosixFilePermissions(dir1.Append(kExeFileName), |
| 876 FILE_PERMISSION_EXECUTE_BY_USER)); | 940 FILE_PERMISSION_EXECUTE_BY_USER)); |
| 877 | 941 |
| 878 EXPECT_TRUE(ExecutableExistsInPath(env.get(), kExeFileName)); | 942 EXPECT_TRUE(ExecutableExistsInPath(env.get(), kExeFileName)); |
| 879 EXPECT_FALSE(ExecutableExistsInPath(env.get(), kRegularFileName)); | 943 EXPECT_FALSE(ExecutableExistsInPath(env.get(), kRegularFileName)); |
| 880 EXPECT_FALSE(ExecutableExistsInPath(env.get(), kDneFileName)); | 944 EXPECT_FALSE(ExecutableExistsInPath(env.get(), kDneFileName)); |
| 881 } | 945 } |
| 882 | 946 |
| 883 #endif // defined(OS_POSIX) | 947 #endif // defined(OS_POSIX) |
| 884 | 948 |
| 885 #if defined(OS_WIN) | |
| 886 // Tests that the Delete function works for wild cards, especially | |
| 887 // with the recursion flag. Also coincidentally tests PathExists. | |
| 888 // TODO(erikkay): see if anyone's actually using this feature of the API | |
| 889 TEST_F(FileUtilTest, DeleteWildCard) { | |
| 890 // Create a file and a directory | |
| 891 FilePath file_name = | |
| 892 temp_dir_.GetPath().Append(FPL("Test DeleteWildCard.txt")); | |
| 893 CreateTextFile(file_name, bogus_content); | |
| 894 ASSERT_TRUE(PathExists(file_name)); | |
| 895 | |
| 896 FilePath subdir_path = temp_dir_.GetPath().Append(FPL("DeleteWildCardDir")); | |
| 897 CreateDirectory(subdir_path); | |
| 898 ASSERT_TRUE(PathExists(subdir_path)); | |
| 899 | |
| 900 // Create the wildcard path | |
| 901 FilePath directory_contents = temp_dir_.GetPath(); | |
| 902 directory_contents = directory_contents.Append(FPL("*")); | |
| 903 | |
| 904 // Delete non-recursively and check that only the file is deleted | |
| 905 EXPECT_TRUE(DeleteFile(directory_contents, false)); | |
| 906 EXPECT_FALSE(PathExists(file_name)); | |
| 907 EXPECT_TRUE(PathExists(subdir_path)); | |
| 908 | |
| 909 // Delete recursively and make sure all contents are deleted | |
| 910 EXPECT_TRUE(DeleteFile(directory_contents, true)); | |
| 911 EXPECT_FALSE(PathExists(file_name)); | |
| 912 EXPECT_FALSE(PathExists(subdir_path)); | |
| 913 } | |
| 914 | |
| 915 // TODO(erikkay): see if anyone's actually using this feature of the API | |
| 916 TEST_F(FileUtilTest, DeleteNonExistantWildCard) { | |
| 917 // Create a file and a directory | |
| 918 FilePath subdir_path = | |
| 919 temp_dir_.GetPath().Append(FPL("DeleteNonExistantWildCard")); | |
| 920 CreateDirectory(subdir_path); | |
| 921 ASSERT_TRUE(PathExists(subdir_path)); | |
| 922 | |
| 923 // Create the wildcard path | |
| 924 FilePath directory_contents = subdir_path; | |
| 925 directory_contents = directory_contents.Append(FPL("*")); | |
| 926 | |
| 927 // Delete non-recursively and check nothing got deleted | |
| 928 EXPECT_TRUE(DeleteFile(directory_contents, false)); | |
| 929 EXPECT_TRUE(PathExists(subdir_path)); | |
| 930 | |
| 931 // Delete recursively and check nothing got deleted | |
| 932 EXPECT_TRUE(DeleteFile(directory_contents, true)); | |
| 933 EXPECT_TRUE(PathExists(subdir_path)); | |
| 934 } | |
| 935 #endif | |
| 936 | |
| 937 // Tests non-recursive Delete() for a directory. | 949 // Tests non-recursive Delete() for a directory. |
| 938 TEST_F(FileUtilTest, DeleteDirNonRecursive) { | 950 TEST_F(FileUtilTest, DeleteDirNonRecursive) { |
| 939 // Create a subdirectory and put a file and two directories inside. | 951 // Create a subdirectory and put a file and two directories inside. |
| 940 FilePath test_subdir = | 952 FilePath test_subdir = |
| 941 temp_dir_.GetPath().Append(FPL("DeleteDirNonRecursive")); | 953 temp_dir_.GetPath().Append(FPL("DeleteDirNonRecursive")); |
| 942 CreateDirectory(test_subdir); | 954 CreateDirectory(test_subdir); |
| 943 ASSERT_TRUE(PathExists(test_subdir)); | 955 ASSERT_TRUE(PathExists(test_subdir)); |
| 944 | 956 |
| 945 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); | 957 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); |
| 946 CreateTextFile(file_name, bogus_content); | 958 CreateTextFile(file_name, bogus_content); |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1418 | 1430 |
| 1419 EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true)); | 1431 EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true)); |
| 1420 | 1432 |
| 1421 // Check everything has been copied. | 1433 // Check everything has been copied. |
| 1422 EXPECT_TRUE(PathExists(dir_name_from)); | 1434 EXPECT_TRUE(PathExists(dir_name_from)); |
| 1423 EXPECT_TRUE(PathExists(file_name_from)); | 1435 EXPECT_TRUE(PathExists(file_name_from)); |
| 1424 EXPECT_TRUE(PathExists(dir_name_to)); | 1436 EXPECT_TRUE(PathExists(dir_name_to)); |
| 1425 EXPECT_TRUE(PathExists(file_name_to)); | 1437 EXPECT_TRUE(PathExists(file_name_to)); |
| 1426 } | 1438 } |
| 1427 | 1439 |
| 1428 // Sets the source file to read-only. | |
| 1429 void SetReadOnly(const FilePath& path, bool read_only) { | |
| 1430 #if defined(OS_WIN) | |
| 1431 // On Windows, it involves setting/removing the 'readonly' bit. | |
| 1432 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
| 1433 ASSERT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
| 1434 ASSERT_TRUE(SetFileAttributes( | |
| 1435 path.value().c_str(), | |
| 1436 read_only ? (attrs | FILE_ATTRIBUTE_READONLY) : | |
| 1437 (attrs & ~FILE_ATTRIBUTE_READONLY))); | |
| 1438 | |
| 1439 DWORD expected = read_only ? | |
| 1440 ((attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)) | | |
| 1441 FILE_ATTRIBUTE_READONLY) : | |
| 1442 (attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)); | |
| 1443 | |
| 1444 // Ignore FILE_ATTRIBUTE_NOT_CONTENT_INDEXED if present. | |
| 1445 attrs = GetFileAttributes(path.value().c_str()) & | |
| 1446 ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; | |
| 1447 ASSERT_EQ(expected, attrs); | |
| 1448 #else | |
| 1449 // On all other platforms, it involves removing/setting the write bit. | |
| 1450 mode_t mode = read_only ? S_IRUSR : (S_IRUSR | S_IWUSR); | |
| 1451 EXPECT_TRUE(SetPosixFilePermissions( | |
| 1452 path, DirectoryExists(path) ? (mode | S_IXUSR) : mode)); | |
| 1453 #endif | |
| 1454 } | |
| 1455 | |
| 1456 bool IsReadOnly(const FilePath& path) { | |
| 1457 #if defined(OS_WIN) | |
| 1458 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
| 1459 EXPECT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
| 1460 return attrs & FILE_ATTRIBUTE_READONLY; | |
| 1461 #else | |
| 1462 int mode = 0; | |
| 1463 EXPECT_TRUE(GetPosixFilePermissions(path, &mode)); | |
| 1464 return !(mode & S_IWUSR); | |
| 1465 #endif | |
| 1466 } | |
| 1467 | |
| 1468 TEST_F(FileUtilTest, CopyDirectoryACL) { | 1440 TEST_F(FileUtilTest, CopyDirectoryACL) { |
| 1469 // Create source directories. | 1441 // Create source directories. |
| 1470 FilePath src = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("src")); | 1442 FilePath src = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("src")); |
| 1471 FilePath src_subdir = src.Append(FILE_PATH_LITERAL("subdir")); | 1443 FilePath src_subdir = src.Append(FILE_PATH_LITERAL("subdir")); |
| 1472 CreateDirectory(src_subdir); | 1444 CreateDirectory(src_subdir); |
| 1473 ASSERT_TRUE(PathExists(src_subdir)); | 1445 ASSERT_TRUE(PathExists(src_subdir)); |
| 1474 | 1446 |
| 1475 // Create a file under the directory. | 1447 // Create a file under the directory. |
| 1476 FilePath src_file = src.Append(FILE_PATH_LITERAL("src.txt")); | 1448 FilePath src_file = src.Append(FILE_PATH_LITERAL("src.txt")); |
| 1477 CreateTextFile(src_file, L"Gooooooooooooooooooooogle"); | 1449 CreateTextFile(src_file, L"Gooooooooooooooooooooogle"); |
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2568 // Trying to close it should crash. This is important for security. | 2540 // Trying to close it should crash. This is important for security. |
| 2569 EXPECT_DEATH(CloseWithScopedFD(fds[1]), ""); | 2541 EXPECT_DEATH(CloseWithScopedFD(fds[1]), ""); |
| 2570 #endif | 2542 #endif |
| 2571 } | 2543 } |
| 2572 | 2544 |
| 2573 #endif // defined(OS_POSIX) | 2545 #endif // defined(OS_POSIX) |
| 2574 | 2546 |
| 2575 } // namespace | 2547 } // namespace |
| 2576 | 2548 |
| 2577 } // namespace base | 2549 } // namespace base |
| OLD | NEW |