| 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 "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | |
| 8 #include <windows.h> | |
| 9 #include <shellapi.h> | |
| 10 #include <shlobj.h> | |
| 11 #include <tchar.h> | |
| 12 #include <winioctl.h> | |
| 13 #endif | |
| 14 | |
| 15 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
| 16 #include <errno.h> | 8 #include <errno.h> |
| 17 #include <fcntl.h> | 9 #include <fcntl.h> |
| 18 #include <unistd.h> | 10 #include <unistd.h> |
| 19 #endif | 11 #endif |
| 20 | 12 |
| 21 #include <algorithm> | 13 #include <algorithm> |
| 22 #include <fstream> | 14 #include <fstream> |
| 23 #include <set> | 15 #include <set> |
| 24 #include <vector> | 16 #include <vector> |
| 25 | 17 |
| 26 #include "base/base_paths.h" | 18 #include "base/base_paths.h" |
| 27 #include "base/files/file_enumerator.h" | 19 #include "base/files/file_enumerator.h" |
| 28 #include "base/files/file_path.h" | 20 #include "base/files/file_path.h" |
| 29 #include "base/files/file_util.h" | 21 #include "base/files/file_util.h" |
| 30 #include "base/files/scoped_file.h" | 22 #include "base/files/scoped_file.h" |
| 31 #include "base/files/scoped_temp_dir.h" | 23 #include "base/files/scoped_temp_dir.h" |
| 32 #include "base/path_service.h" | 24 #include "base/path_service.h" |
| 33 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
| 34 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
| 35 #include "base/test/test_file_util.h" | 27 #include "base/test/test_file_util.h" |
| 36 #include "base/threading/platform_thread.h" | 28 #include "base/threading/platform_thread.h" |
| 37 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
| 38 #include "testing/platform_test.h" | 30 #include "testing/platform_test.h" |
| 39 | 31 |
| 40 #if defined(OS_WIN) | |
| 41 #include "base/win/scoped_handle.h" | |
| 42 #include "base/win/windows_version.h" | |
| 43 #endif | |
| 44 | |
| 45 #if defined(OS_ANDROID) | 32 #if defined(OS_ANDROID) |
| 46 #include "base/android/content_uri_utils.h" | 33 #include "base/android/content_uri_utils.h" |
| 47 #endif | 34 #endif |
| 48 | 35 |
| 49 // This macro helps avoid wrapped lines in the test structs. | 36 // This macro helps avoid wrapped lines in the test structs. |
| 50 #define FPL(x) FILE_PATH_LITERAL(x) | 37 #define FPL(x) FILE_PATH_LITERAL(x) |
| 51 | 38 |
| 52 namespace base { | 39 namespace base { |
| 53 | 40 |
| 54 namespace { | 41 namespace { |
| 55 | 42 |
| 56 // To test that NormalizeFilePath() deals with NTFS reparse points correctly, | 43 // To test that NormalizeFilePath() deals with NTFS reparse points correctly, |
| 57 // we need functions to create and delete reparse points. | 44 // we need functions to create and delete reparse points. |
| 58 #if defined(OS_WIN) | |
| 59 typedef struct _REPARSE_DATA_BUFFER { | |
| 60 ULONG ReparseTag; | |
| 61 USHORT ReparseDataLength; | |
| 62 USHORT Reserved; | |
| 63 union { | |
| 64 struct { | |
| 65 USHORT SubstituteNameOffset; | |
| 66 USHORT SubstituteNameLength; | |
| 67 USHORT PrintNameOffset; | |
| 68 USHORT PrintNameLength; | |
| 69 ULONG Flags; | |
| 70 WCHAR PathBuffer[1]; | |
| 71 } SymbolicLinkReparseBuffer; | |
| 72 struct { | |
| 73 USHORT SubstituteNameOffset; | |
| 74 USHORT SubstituteNameLength; | |
| 75 USHORT PrintNameOffset; | |
| 76 USHORT PrintNameLength; | |
| 77 WCHAR PathBuffer[1]; | |
| 78 } MountPointReparseBuffer; | |
| 79 struct { | |
| 80 UCHAR DataBuffer[1]; | |
| 81 } GenericReparseBuffer; | |
| 82 }; | |
| 83 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; | |
| 84 | |
| 85 // Sets a reparse point. |source| will now point to |target|. Returns true if | |
| 86 // the call succeeds, false otherwise. | |
| 87 bool SetReparsePoint(HANDLE source, const FilePath& target_path) { | |
| 88 std::wstring kPathPrefix = L"\\??\\"; | |
| 89 std::wstring target_str; | |
| 90 // The juction will not work if the target path does not start with \??\ . | |
| 91 if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size())) | |
| 92 target_str += kPathPrefix; | |
| 93 target_str += target_path.value(); | |
| 94 const wchar_t* target = target_str.c_str(); | |
| 95 USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]); | |
| 96 char buffer[2000] = {0}; | |
| 97 DWORD returned; | |
| 98 | |
| 99 REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer); | |
| 100 | |
| 101 data->ReparseTag = 0xa0000003; | |
| 102 memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2); | |
| 103 | |
| 104 data->MountPointReparseBuffer.SubstituteNameLength = size_target; | |
| 105 data->MountPointReparseBuffer.PrintNameOffset = size_target + 2; | |
| 106 data->ReparseDataLength = size_target + 4 + 8; | |
| 107 | |
| 108 int data_size = data->ReparseDataLength + 8; | |
| 109 | |
| 110 if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size, | |
| 111 NULL, 0, &returned, NULL)) { | |
| 112 return false; | |
| 113 } | |
| 114 return true; | |
| 115 } | |
| 116 | |
| 117 // Delete the reparse point referenced by |source|. Returns true if the call | |
| 118 // succeeds, false otherwise. | |
| 119 bool DeleteReparsePoint(HANDLE source) { | |
| 120 DWORD returned; | |
| 121 REPARSE_DATA_BUFFER data = {0}; | |
| 122 data.ReparseTag = 0xa0000003; | |
| 123 if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0, | |
| 124 &returned, NULL)) { | |
| 125 return false; | |
| 126 } | |
| 127 return true; | |
| 128 } | |
| 129 | |
| 130 // Manages a reparse point for a test. | |
| 131 class ReparsePoint { | |
| 132 public: | |
| 133 // Creates a reparse point from |source| (an empty directory) to |target|. | |
| 134 ReparsePoint(const FilePath& source, const FilePath& target) { | |
| 135 dir_.Set( | |
| 136 ::CreateFile(source.value().c_str(), | |
| 137 FILE_ALL_ACCESS, | |
| 138 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | |
| 139 NULL, | |
| 140 OPEN_EXISTING, | |
| 141 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. | |
| 142 NULL)); | |
| 143 created_ = dir_.IsValid() && SetReparsePoint(dir_.Get(), target); | |
| 144 } | |
| 145 | |
| 146 ~ReparsePoint() { | |
| 147 if (created_) | |
| 148 DeleteReparsePoint(dir_.Get()); | |
| 149 } | |
| 150 | |
| 151 bool IsValid() { return created_; } | |
| 152 | |
| 153 private: | |
| 154 win::ScopedHandle dir_; | |
| 155 bool created_; | |
| 156 DISALLOW_COPY_AND_ASSIGN(ReparsePoint); | |
| 157 }; | |
| 158 | |
| 159 #endif | |
| 160 | |
| 161 #if defined(OS_POSIX) | 45 #if defined(OS_POSIX) |
| 162 // Provide a simple way to change the permissions bits on |path| in tests. | 46 // Provide a simple way to change the permissions bits on |path| in tests. |
| 163 // ASSERT failures will return, but not stop the test. Caller should wrap | 47 // ASSERT failures will return, but not stop the test. Caller should wrap |
| 164 // calls to this function in ASSERT_NO_FATAL_FAILURE(). | 48 // calls to this function in ASSERT_NO_FATAL_FAILURE(). |
| 165 void ChangePosixFilePermissions(const FilePath& path, | 49 void ChangePosixFilePermissions(const FilePath& path, |
| 166 int mode_bits_to_set, | 50 int mode_bits_to_set, |
| 167 int mode_bits_to_clear) { | 51 int mode_bits_to_clear) { |
| 168 ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear) | 52 ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear) |
| 169 << "Can't set and clear the same bits."; | 53 << "Can't set and clear the same bits."; |
| 170 | 54 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 std::wstring ReadTextFile(const FilePath& filename) { | 121 std::wstring ReadTextFile(const FilePath& filename) { |
| 238 wchar_t contents[64]; | 122 wchar_t contents[64]; |
| 239 std::wifstream file; | 123 std::wifstream file; |
| 240 file.open(filename.value().c_str()); | 124 file.open(filename.value().c_str()); |
| 241 EXPECT_TRUE(file.is_open()); | 125 EXPECT_TRUE(file.is_open()); |
| 242 file.getline(contents, arraysize(contents)); | 126 file.getline(contents, arraysize(contents)); |
| 243 file.close(); | 127 file.close(); |
| 244 return std::wstring(contents); | 128 return std::wstring(contents); |
| 245 } | 129 } |
| 246 | 130 |
| 247 #if defined(OS_WIN) | |
| 248 uint64 FileTimeAsUint64(const FILETIME& ft) { | |
| 249 ULARGE_INTEGER u; | |
| 250 u.LowPart = ft.dwLowDateTime; | |
| 251 u.HighPart = ft.dwHighDateTime; | |
| 252 return u.QuadPart; | |
| 253 } | |
| 254 #endif | |
| 255 | |
| 256 TEST_F(FileUtilTest, FileAndDirectorySize) { | 131 TEST_F(FileUtilTest, FileAndDirectorySize) { |
| 257 // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize | 132 // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize |
| 258 // should return 53 bytes. | 133 // should return 53 bytes. |
| 259 FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt")); | 134 FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt")); |
| 260 CreateTextFile(file_01, L"12345678901234567890"); | 135 CreateTextFile(file_01, L"12345678901234567890"); |
| 261 int64 size_f1 = 0; | 136 int64 size_f1 = 0; |
| 262 ASSERT_TRUE(GetFileSize(file_01, &size_f1)); | 137 ASSERT_TRUE(GetFileSize(file_01, &size_f1)); |
| 263 EXPECT_EQ(20ll, size_f1); | 138 EXPECT_EQ(20ll, size_f1); |
| 264 | 139 |
| 265 FilePath subdir_path = temp_dir_.path().Append(FPL("Level2")); | 140 FilePath subdir_path = temp_dir_.path().Append(FPL("Level2")); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 ASSERT_TRUE(PathExists(file_b_path)); | 177 ASSERT_TRUE(PathExists(file_b_path)); |
| 303 ASSERT_TRUE(NormalizeFilePath(file_b_path, &normalized_file_b_path)); | 178 ASSERT_TRUE(NormalizeFilePath(file_b_path, &normalized_file_b_path)); |
| 304 | 179 |
| 305 // Beacuse this test created |dir_path|, we know it is not a link | 180 // Beacuse this test created |dir_path|, we know it is not a link |
| 306 // or junction. So, the real path of the directory holding file a | 181 // or junction. So, the real path of the directory holding file a |
| 307 // must be the parent of the path holding file b. | 182 // must be the parent of the path holding file b. |
| 308 ASSERT_TRUE(normalized_file_a_path.DirName() | 183 ASSERT_TRUE(normalized_file_a_path.DirName() |
| 309 .IsParent(normalized_file_b_path.DirName())); | 184 .IsParent(normalized_file_b_path.DirName())); |
| 310 } | 185 } |
| 311 | 186 |
| 312 #if defined(OS_WIN) | |
| 313 | |
| 314 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) { | |
| 315 // Build the following directory structure: | |
| 316 // | |
| 317 // temp_dir | |
| 318 // |-> base_a | |
| 319 // | |-> sub_a | |
| 320 // | |-> file.txt | |
| 321 // | |-> long_name___... (Very long name.) | |
| 322 // | |-> sub_long | |
| 323 // | |-> deep.txt | |
| 324 // |-> base_b | |
| 325 // |-> to_sub_a (reparse point to temp_dir\base_a\sub_a) | |
| 326 // |-> to_base_b (reparse point to temp_dir\base_b) | |
| 327 // |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long) | |
| 328 | |
| 329 FilePath base_a = temp_dir_.path().Append(FPL("base_a")); | |
| 330 #if defined(OS_WIN) | |
| 331 // TEMP can have a lower case drive letter. | |
| 332 string16 temp_base_a = base_a.value(); | |
| 333 ASSERT_FALSE(temp_base_a.empty()); | |
| 334 *temp_base_a.begin() = ToUpperASCII(*temp_base_a.begin()); | |
| 335 base_a = FilePath(temp_base_a); | |
| 336 #endif | |
| 337 ASSERT_TRUE(CreateDirectory(base_a)); | |
| 338 | |
| 339 FilePath sub_a = base_a.Append(FPL("sub_a")); | |
| 340 ASSERT_TRUE(CreateDirectory(sub_a)); | |
| 341 | |
| 342 FilePath file_txt = sub_a.Append(FPL("file.txt")); | |
| 343 CreateTextFile(file_txt, bogus_content); | |
| 344 | |
| 345 // Want a directory whose name is long enough to make the path to the file | |
| 346 // inside just under MAX_PATH chars. This will be used to test that when | |
| 347 // a junction expands to a path over MAX_PATH chars in length, | |
| 348 // NormalizeFilePath() fails without crashing. | |
| 349 FilePath sub_long_rel(FPL("sub_long")); | |
| 350 FilePath deep_txt(FPL("deep.txt")); | |
| 351 | |
| 352 int target_length = MAX_PATH; | |
| 353 target_length -= (sub_a.value().length() + 1); // +1 for the sepperator '\'. | |
| 354 target_length -= (sub_long_rel.Append(deep_txt).value().length() + 1); | |
| 355 // Without making the path a bit shorter, CreateDirectory() fails. | |
| 356 // the resulting path is still long enough to hit the failing case in | |
| 357 // NormalizePath(). | |
| 358 const int kCreateDirLimit = 4; | |
| 359 target_length -= kCreateDirLimit; | |
| 360 FilePath::StringType long_name_str = FPL("long_name_"); | |
| 361 long_name_str.resize(target_length, '_'); | |
| 362 | |
| 363 FilePath long_name = sub_a.Append(FilePath(long_name_str)); | |
| 364 FilePath deep_file = long_name.Append(sub_long_rel).Append(deep_txt); | |
| 365 ASSERT_EQ(MAX_PATH - kCreateDirLimit, deep_file.value().length()); | |
| 366 | |
| 367 FilePath sub_long = deep_file.DirName(); | |
| 368 ASSERT_TRUE(CreateDirectory(sub_long)); | |
| 369 CreateTextFile(deep_file, bogus_content); | |
| 370 | |
| 371 FilePath base_b = temp_dir_.path().Append(FPL("base_b")); | |
| 372 ASSERT_TRUE(CreateDirectory(base_b)); | |
| 373 | |
| 374 FilePath to_sub_a = base_b.Append(FPL("to_sub_a")); | |
| 375 ASSERT_TRUE(CreateDirectory(to_sub_a)); | |
| 376 FilePath normalized_path; | |
| 377 { | |
| 378 ReparsePoint reparse_to_sub_a(to_sub_a, sub_a); | |
| 379 ASSERT_TRUE(reparse_to_sub_a.IsValid()); | |
| 380 | |
| 381 FilePath to_base_b = base_b.Append(FPL("to_base_b")); | |
| 382 ASSERT_TRUE(CreateDirectory(to_base_b)); | |
| 383 ReparsePoint reparse_to_base_b(to_base_b, base_b); | |
| 384 ASSERT_TRUE(reparse_to_base_b.IsValid()); | |
| 385 | |
| 386 FilePath to_sub_long = base_b.Append(FPL("to_sub_long")); | |
| 387 ASSERT_TRUE(CreateDirectory(to_sub_long)); | |
| 388 ReparsePoint reparse_to_sub_long(to_sub_long, sub_long); | |
| 389 ASSERT_TRUE(reparse_to_sub_long.IsValid()); | |
| 390 | |
| 391 // Normalize a junction free path: base_a\sub_a\file.txt . | |
| 392 ASSERT_TRUE(NormalizeFilePath(file_txt, &normalized_path)); | |
| 393 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); | |
| 394 | |
| 395 // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude | |
| 396 // the junction to_sub_a. | |
| 397 ASSERT_TRUE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), | |
| 398 &normalized_path)); | |
| 399 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); | |
| 400 | |
| 401 // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be | |
| 402 // normalized to exclude junctions to_base_b and to_sub_a . | |
| 403 ASSERT_TRUE(NormalizeFilePath(base_b.Append(FPL("to_base_b")) | |
| 404 .Append(FPL("to_base_b")) | |
| 405 .Append(FPL("to_sub_a")) | |
| 406 .Append(FPL("file.txt")), | |
| 407 &normalized_path)); | |
| 408 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); | |
| 409 | |
| 410 // A long enough path will cause NormalizeFilePath() to fail. Make a long | |
| 411 // path using to_base_b many times, and check that paths long enough to fail | |
| 412 // do not cause a crash. | |
| 413 FilePath long_path = base_b; | |
| 414 const int kLengthLimit = MAX_PATH + 200; | |
| 415 while (long_path.value().length() <= kLengthLimit) { | |
| 416 long_path = long_path.Append(FPL("to_base_b")); | |
| 417 } | |
| 418 long_path = long_path.Append(FPL("to_sub_a")) | |
| 419 .Append(FPL("file.txt")); | |
| 420 | |
| 421 ASSERT_FALSE(NormalizeFilePath(long_path, &normalized_path)); | |
| 422 | |
| 423 // Normalizing the junction to deep.txt should fail, because the expanded | |
| 424 // path to deep.txt is longer than MAX_PATH. | |
| 425 ASSERT_FALSE(NormalizeFilePath(to_sub_long.Append(deep_txt), | |
| 426 &normalized_path)); | |
| 427 | |
| 428 // Delete the reparse points, and see that NormalizeFilePath() fails | |
| 429 // to traverse them. | |
| 430 } | |
| 431 | |
| 432 ASSERT_FALSE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), | |
| 433 &normalized_path)); | |
| 434 } | |
| 435 | |
| 436 TEST_F(FileUtilTest, DevicePathToDriveLetter) { | |
| 437 // Get a drive letter. | |
| 438 std::wstring real_drive_letter = temp_dir_.path().value().substr(0, 2); | |
| 439 StringToUpperASCII(&real_drive_letter); | |
| 440 if (!isalpha(real_drive_letter[0]) || ':' != real_drive_letter[1]) { | |
| 441 LOG(ERROR) << "Can't get a drive letter to test with."; | |
| 442 return; | |
| 443 } | |
| 444 | |
| 445 // Get the NT style path to that drive. | |
| 446 wchar_t device_path[MAX_PATH] = {'\0'}; | |
| 447 ASSERT_TRUE( | |
| 448 ::QueryDosDevice(real_drive_letter.c_str(), device_path, MAX_PATH)); | |
| 449 FilePath actual_device_path(device_path); | |
| 450 FilePath win32_path; | |
| 451 | |
| 452 // Run DevicePathToDriveLetterPath() on the NT style path we got from | |
| 453 // QueryDosDevice(). Expect the drive letter we started with. | |
| 454 ASSERT_TRUE(DevicePathToDriveLetterPath(actual_device_path, &win32_path)); | |
| 455 ASSERT_EQ(real_drive_letter, win32_path.value()); | |
| 456 | |
| 457 // Add some directories to the path. Expect those extra path componenets | |
| 458 // to be preserved. | |
| 459 FilePath kRelativePath(FPL("dir1\\dir2\\file.txt")); | |
| 460 ASSERT_TRUE(DevicePathToDriveLetterPath( | |
| 461 actual_device_path.Append(kRelativePath), | |
| 462 &win32_path)); | |
| 463 EXPECT_EQ(FilePath(real_drive_letter + L"\\").Append(kRelativePath).value(), | |
| 464 win32_path.value()); | |
| 465 | |
| 466 // Deform the real path so that it is invalid by removing the last four | |
| 467 // characters. The way windows names devices that are hard disks | |
| 468 // (\Device\HardDiskVolume${NUMBER}) guarantees that the string is longer | |
| 469 // than three characters. The only way the truncated string could be a | |
| 470 // real drive is if more than 10^3 disks are mounted: | |
| 471 // \Device\HardDiskVolume10000 would be truncated to \Device\HardDiskVolume1 | |
| 472 // Check that DevicePathToDriveLetterPath fails. | |
| 473 int path_length = actual_device_path.value().length(); | |
| 474 int new_length = path_length - 4; | |
| 475 ASSERT_LT(0, new_length); | |
| 476 FilePath prefix_of_real_device_path( | |
| 477 actual_device_path.value().substr(0, new_length)); | |
| 478 ASSERT_FALSE(DevicePathToDriveLetterPath(prefix_of_real_device_path, | |
| 479 &win32_path)); | |
| 480 | |
| 481 ASSERT_FALSE(DevicePathToDriveLetterPath( | |
| 482 prefix_of_real_device_path.Append(kRelativePath), | |
| 483 &win32_path)); | |
| 484 | |
| 485 // Deform the real path so that it is invalid by adding some characters. For | |
| 486 // example, if C: maps to \Device\HardDiskVolume8, then we simulate a | |
| 487 // request for the drive letter whose native path is | |
| 488 // \Device\HardDiskVolume812345 . We assume such a device does not exist, | |
| 489 // because drives are numbered in order and mounting 112345 hard disks will | |
| 490 // never happen. | |
| 491 const FilePath::StringType kExtraChars = FPL("12345"); | |
| 492 | |
| 493 FilePath real_device_path_plus_numbers( | |
| 494 actual_device_path.value() + kExtraChars); | |
| 495 | |
| 496 ASSERT_FALSE(DevicePathToDriveLetterPath( | |
| 497 real_device_path_plus_numbers, | |
| 498 &win32_path)); | |
| 499 | |
| 500 ASSERT_FALSE(DevicePathToDriveLetterPath( | |
| 501 real_device_path_plus_numbers.Append(kRelativePath), | |
| 502 &win32_path)); | |
| 503 } | |
| 504 | |
| 505 TEST_F(FileUtilTest, CreateTemporaryFileInDirLongPathTest) { | |
| 506 // Test that CreateTemporaryFileInDir() creates a path and returns a long path | |
| 507 // if it is available. This test requires that: | |
| 508 // - the filesystem at |temp_dir_| supports long filenames. | |
| 509 // - the account has FILE_LIST_DIRECTORY permission for all ancestor | |
| 510 // directories of |temp_dir_|. | |
| 511 const FilePath::CharType kLongDirName[] = FPL("A long path"); | |
| 512 const FilePath::CharType kTestSubDirName[] = FPL("test"); | |
| 513 FilePath long_test_dir = temp_dir_.path().Append(kLongDirName); | |
| 514 ASSERT_TRUE(CreateDirectory(long_test_dir)); | |
| 515 | |
| 516 // kLongDirName is not a 8.3 component. So GetShortName() should give us a | |
| 517 // different short name. | |
| 518 WCHAR path_buffer[MAX_PATH]; | |
| 519 DWORD path_buffer_length = GetShortPathName(long_test_dir.value().c_str(), | |
| 520 path_buffer, MAX_PATH); | |
| 521 ASSERT_LT(path_buffer_length, DWORD(MAX_PATH)); | |
| 522 ASSERT_NE(DWORD(0), path_buffer_length); | |
| 523 FilePath short_test_dir(path_buffer); | |
| 524 ASSERT_STRNE(kLongDirName, short_test_dir.BaseName().value().c_str()); | |
| 525 | |
| 526 FilePath temp_file; | |
| 527 ASSERT_TRUE(CreateTemporaryFileInDir(short_test_dir, &temp_file)); | |
| 528 EXPECT_STREQ(kLongDirName, temp_file.DirName().BaseName().value().c_str()); | |
| 529 EXPECT_TRUE(PathExists(temp_file)); | |
| 530 | |
| 531 // Create a subdirectory of |long_test_dir| and make |long_test_dir| | |
| 532 // unreadable. We should still be able to create a temp file in the | |
| 533 // subdirectory, but we won't be able to determine the long path for it. This | |
| 534 // mimics the environment that some users run where their user profiles reside | |
| 535 // in a location where the don't have full access to the higher level | |
| 536 // directories. (Note that this assumption is true for NTFS, but not for some | |
| 537 // network file systems. E.g. AFS). | |
| 538 FilePath access_test_dir = long_test_dir.Append(kTestSubDirName); | |
| 539 ASSERT_TRUE(CreateDirectory(access_test_dir)); | |
| 540 FilePermissionRestorer long_test_dir_restorer(long_test_dir); | |
| 541 ASSERT_TRUE(MakeFileUnreadable(long_test_dir)); | |
| 542 | |
| 543 // Use the short form of the directory to create a temporary filename. | |
| 544 ASSERT_TRUE(CreateTemporaryFileInDir( | |
| 545 short_test_dir.Append(kTestSubDirName), &temp_file)); | |
| 546 EXPECT_TRUE(PathExists(temp_file)); | |
| 547 EXPECT_TRUE(short_test_dir.IsParent(temp_file.DirName())); | |
| 548 | |
| 549 // Check that the long path can't be determined for |temp_file|. | |
| 550 path_buffer_length = GetLongPathName(temp_file.value().c_str(), | |
| 551 path_buffer, MAX_PATH); | |
| 552 EXPECT_EQ(DWORD(0), path_buffer_length); | |
| 553 } | |
| 554 | |
| 555 #endif // defined(OS_WIN) | |
| 556 | |
| 557 #if defined(OS_POSIX) | 187 #if defined(OS_POSIX) |
| 558 | 188 |
| 559 TEST_F(FileUtilTest, CreateAndReadSymlinks) { | 189 TEST_F(FileUtilTest, CreateAndReadSymlinks) { |
| 560 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); | 190 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); |
| 561 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); | 191 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); |
| 562 CreateTextFile(link_to, bogus_content); | 192 CreateTextFile(link_to, bogus_content); |
| 563 | 193 |
| 564 ASSERT_TRUE(CreateSymbolicLink(link_to, link_from)) | 194 ASSERT_TRUE(CreateSymbolicLink(link_to, link_from)) |
| 565 << "Failed to create file symlink."; | 195 << "Failed to create file symlink."; |
| 566 | 196 |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 EXPECT_TRUE(c2.HasFile(file_name)); | 469 EXPECT_TRUE(c2.HasFile(file_name)); |
| 840 EXPECT_EQ(1, c2.size()); | 470 EXPECT_EQ(1, c2.size()); |
| 841 | 471 |
| 842 // Delete the file. | 472 // Delete the file. |
| 843 EXPECT_TRUE(DeleteFile(subdir_path, true)); | 473 EXPECT_TRUE(DeleteFile(subdir_path, true)); |
| 844 EXPECT_FALSE(PathExists(subdir_path)); | 474 EXPECT_FALSE(PathExists(subdir_path)); |
| 845 } | 475 } |
| 846 | 476 |
| 847 #endif // defined(OS_POSIX) | 477 #endif // defined(OS_POSIX) |
| 848 | 478 |
| 849 #if defined(OS_WIN) | |
| 850 // Tests that the Delete function works for wild cards, especially | |
| 851 // with the recursion flag. Also coincidentally tests PathExists. | |
| 852 // TODO(erikkay): see if anyone's actually using this feature of the API | |
| 853 TEST_F(FileUtilTest, DeleteWildCard) { | |
| 854 // Create a file and a directory | |
| 855 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteWildCard.txt")); | |
| 856 CreateTextFile(file_name, bogus_content); | |
| 857 ASSERT_TRUE(PathExists(file_name)); | |
| 858 | |
| 859 FilePath subdir_path = temp_dir_.path().Append(FPL("DeleteWildCardDir")); | |
| 860 CreateDirectory(subdir_path); | |
| 861 ASSERT_TRUE(PathExists(subdir_path)); | |
| 862 | |
| 863 // Create the wildcard path | |
| 864 FilePath directory_contents = temp_dir_.path(); | |
| 865 directory_contents = directory_contents.Append(FPL("*")); | |
| 866 | |
| 867 // Delete non-recursively and check that only the file is deleted | |
| 868 EXPECT_TRUE(DeleteFile(directory_contents, false)); | |
| 869 EXPECT_FALSE(PathExists(file_name)); | |
| 870 EXPECT_TRUE(PathExists(subdir_path)); | |
| 871 | |
| 872 // Delete recursively and make sure all contents are deleted | |
| 873 EXPECT_TRUE(DeleteFile(directory_contents, true)); | |
| 874 EXPECT_FALSE(PathExists(file_name)); | |
| 875 EXPECT_FALSE(PathExists(subdir_path)); | |
| 876 } | |
| 877 | |
| 878 // TODO(erikkay): see if anyone's actually using this feature of the API | |
| 879 TEST_F(FileUtilTest, DeleteNonExistantWildCard) { | |
| 880 // Create a file and a directory | |
| 881 FilePath subdir_path = | |
| 882 temp_dir_.path().Append(FPL("DeleteNonExistantWildCard")); | |
| 883 CreateDirectory(subdir_path); | |
| 884 ASSERT_TRUE(PathExists(subdir_path)); | |
| 885 | |
| 886 // Create the wildcard path | |
| 887 FilePath directory_contents = subdir_path; | |
| 888 directory_contents = directory_contents.Append(FPL("*")); | |
| 889 | |
| 890 // Delete non-recursively and check nothing got deleted | |
| 891 EXPECT_TRUE(DeleteFile(directory_contents, false)); | |
| 892 EXPECT_TRUE(PathExists(subdir_path)); | |
| 893 | |
| 894 // Delete recursively and check nothing got deleted | |
| 895 EXPECT_TRUE(DeleteFile(directory_contents, true)); | |
| 896 EXPECT_TRUE(PathExists(subdir_path)); | |
| 897 } | |
| 898 #endif | |
| 899 | |
| 900 // Tests non-recursive Delete() for a directory. | 479 // Tests non-recursive Delete() for a directory. |
| 901 TEST_F(FileUtilTest, DeleteDirNonRecursive) { | 480 TEST_F(FileUtilTest, DeleteDirNonRecursive) { |
| 902 // Create a subdirectory and put a file and two directories inside. | 481 // Create a subdirectory and put a file and two directories inside. |
| 903 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive")); | 482 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive")); |
| 904 CreateDirectory(test_subdir); | 483 CreateDirectory(test_subdir); |
| 905 ASSERT_TRUE(PathExists(test_subdir)); | 484 ASSERT_TRUE(PathExists(test_subdir)); |
| 906 | 485 |
| 907 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); | 486 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); |
| 908 CreateTextFile(file_name, bogus_content); | 487 CreateTextFile(file_name, bogus_content); |
| 909 ASSERT_TRUE(PathExists(file_name)); | 488 ASSERT_TRUE(PathExists(file_name)); |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); | 942 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); |
| 1364 ASSERT_TRUE(PathExists(file_name_from)); | 943 ASSERT_TRUE(PathExists(file_name_from)); |
| 1365 | 944 |
| 1366 // Copy the directory recursively. | 945 // Copy the directory recursively. |
| 1367 FilePath dir_name_to = | 946 FilePath dir_name_to = |
| 1368 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); | 947 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); |
| 1369 FilePath file_name_to = | 948 FilePath file_name_to = |
| 1370 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); | 949 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); |
| 1371 | 950 |
| 1372 // Create from path with trailing separators. | 951 // Create from path with trailing separators. |
| 1373 #if defined(OS_WIN) | 952 #if defined (OS_POSIX) |
| 1374 FilePath from_path = | |
| 1375 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir\\\\\\")); | |
| 1376 #elif defined (OS_POSIX) | |
| 1377 FilePath from_path = | 953 FilePath from_path = |
| 1378 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///")); | 954 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///")); |
| 1379 #endif | 955 #endif |
| 1380 | 956 |
| 1381 EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true)); | 957 EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true)); |
| 1382 | 958 |
| 1383 // Check everything has been copied. | 959 // Check everything has been copied. |
| 1384 EXPECT_TRUE(PathExists(dir_name_from)); | 960 EXPECT_TRUE(PathExists(dir_name_from)); |
| 1385 EXPECT_TRUE(PathExists(file_name_from)); | 961 EXPECT_TRUE(PathExists(file_name_from)); |
| 1386 EXPECT_TRUE(PathExists(dir_name_to)); | 962 EXPECT_TRUE(PathExists(dir_name_to)); |
| 1387 EXPECT_TRUE(PathExists(file_name_to)); | 963 EXPECT_TRUE(PathExists(file_name_to)); |
| 1388 } | 964 } |
| 1389 | 965 |
| 1390 // Sets the source file to read-only. | 966 // Sets the source file to read-only. |
| 1391 void SetReadOnly(const FilePath& path, bool read_only) { | 967 void SetReadOnly(const FilePath& path, bool read_only) { |
| 1392 #if defined(OS_WIN) | |
| 1393 // On Windows, it involves setting/removing the 'readonly' bit. | |
| 1394 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
| 1395 ASSERT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
| 1396 ASSERT_TRUE(SetFileAttributes( | |
| 1397 path.value().c_str(), | |
| 1398 read_only ? (attrs | FILE_ATTRIBUTE_READONLY) : | |
| 1399 (attrs & ~FILE_ATTRIBUTE_READONLY))); | |
| 1400 | |
| 1401 DWORD expected = read_only ? | |
| 1402 ((attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)) | | |
| 1403 FILE_ATTRIBUTE_READONLY) : | |
| 1404 (attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)); | |
| 1405 | |
| 1406 // Ignore FILE_ATTRIBUTE_NOT_CONTENT_INDEXED if present. | |
| 1407 attrs = GetFileAttributes(path.value().c_str()) & | |
| 1408 ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; | |
| 1409 ASSERT_EQ(expected, attrs); | |
| 1410 #else | |
| 1411 // On all other platforms, it involves removing/setting the write bit. | |
| 1412 mode_t mode = read_only ? S_IRUSR : (S_IRUSR | S_IWUSR); | 968 mode_t mode = read_only ? S_IRUSR : (S_IRUSR | S_IWUSR); |
| 1413 EXPECT_TRUE(SetPosixFilePermissions( | 969 EXPECT_TRUE(SetPosixFilePermissions( |
| 1414 path, DirectoryExists(path) ? (mode | S_IXUSR) : mode)); | 970 path, DirectoryExists(path) ? (mode | S_IXUSR) : mode)); |
| 1415 #endif | |
| 1416 } | 971 } |
| 1417 | 972 |
| 1418 bool IsReadOnly(const FilePath& path) { | 973 bool IsReadOnly(const FilePath& path) { |
| 1419 #if defined(OS_WIN) | |
| 1420 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
| 1421 EXPECT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
| 1422 return attrs & FILE_ATTRIBUTE_READONLY; | |
| 1423 #else | |
| 1424 int mode = 0; | 974 int mode = 0; |
| 1425 EXPECT_TRUE(GetPosixFilePermissions(path, &mode)); | 975 EXPECT_TRUE(GetPosixFilePermissions(path, &mode)); |
| 1426 return !(mode & S_IWUSR); | 976 return !(mode & S_IWUSR); |
| 1427 #endif | |
| 1428 } | 977 } |
| 1429 | 978 |
| 1430 TEST_F(FileUtilTest, CopyDirectoryACL) { | 979 TEST_F(FileUtilTest, CopyDirectoryACL) { |
| 1431 // Create source directories. | 980 // Create source directories. |
| 1432 FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src")); | 981 FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src")); |
| 1433 FilePath src_subdir = src.Append(FILE_PATH_LITERAL("subdir")); | 982 FilePath src_subdir = src.Append(FILE_PATH_LITERAL("subdir")); |
| 1434 CreateDirectory(src_subdir); | 983 CreateDirectory(src_subdir); |
| 1435 ASSERT_TRUE(PathExists(src_subdir)); | 984 ASSERT_TRUE(PathExists(src_subdir)); |
| 1436 | 985 |
| 1437 // Create a file under the directory. | 986 // Create a file under the directory. |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1604 EXPECT_FALSE(TextContentsEqual(original_file, shortened_file)); | 1153 EXPECT_FALSE(TextContentsEqual(original_file, shortened_file)); |
| 1605 EXPECT_FALSE(TextContentsEqual(original_file, different_file)); | 1154 EXPECT_FALSE(TextContentsEqual(original_file, different_file)); |
| 1606 EXPECT_FALSE(TextContentsEqual(original_file, different_first_file)); | 1155 EXPECT_FALSE(TextContentsEqual(original_file, different_first_file)); |
| 1607 EXPECT_FALSE(TextContentsEqual(original_file, different_last_file)); | 1156 EXPECT_FALSE(TextContentsEqual(original_file, different_last_file)); |
| 1608 EXPECT_FALSE(TextContentsEqual(first1_file, first2_file)); | 1157 EXPECT_FALSE(TextContentsEqual(first1_file, first2_file)); |
| 1609 EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file)); | 1158 EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file)); |
| 1610 EXPECT_FALSE(TextContentsEqual(original_file, empty1_file)); | 1159 EXPECT_FALSE(TextContentsEqual(original_file, empty1_file)); |
| 1611 EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file)); | 1160 EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file)); |
| 1612 } | 1161 } |
| 1613 | 1162 |
| 1614 // We don't need equivalent functionality outside of Windows. | |
| 1615 #if defined(OS_WIN) | |
| 1616 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) { | |
| 1617 // Create a directory | |
| 1618 FilePath dir_name_from = | |
| 1619 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir")); | |
| 1620 CreateDirectory(dir_name_from); | |
| 1621 ASSERT_TRUE(PathExists(dir_name_from)); | |
| 1622 | |
| 1623 // Create a file under the directory | |
| 1624 FilePath file_name_from = | |
| 1625 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); | |
| 1626 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); | |
| 1627 ASSERT_TRUE(PathExists(file_name_from)); | |
| 1628 | |
| 1629 // Move the directory by using CopyAndDeleteDirectory | |
| 1630 FilePath dir_name_to = temp_dir_.path().Append( | |
| 1631 FILE_PATH_LITERAL("CopyAndDelete_To_Subdir")); | |
| 1632 FilePath file_name_to = | |
| 1633 dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); | |
| 1634 | |
| 1635 ASSERT_FALSE(PathExists(dir_name_to)); | |
| 1636 | |
| 1637 EXPECT_TRUE(internal::CopyAndDeleteDirectory(dir_name_from, | |
| 1638 dir_name_to)); | |
| 1639 | |
| 1640 // Check everything has been moved. | |
| 1641 EXPECT_FALSE(PathExists(dir_name_from)); | |
| 1642 EXPECT_FALSE(PathExists(file_name_from)); | |
| 1643 EXPECT_TRUE(PathExists(dir_name_to)); | |
| 1644 EXPECT_TRUE(PathExists(file_name_to)); | |
| 1645 } | |
| 1646 | |
| 1647 TEST_F(FileUtilTest, GetTempDirTest) { | |
| 1648 static const TCHAR* kTmpKey = _T("TMP"); | |
| 1649 static const TCHAR* kTmpValues[] = { | |
| 1650 _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\") | |
| 1651 }; | |
| 1652 // Save the original $TMP. | |
| 1653 size_t original_tmp_size; | |
| 1654 TCHAR* original_tmp; | |
| 1655 ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey)); | |
| 1656 // original_tmp may be NULL. | |
| 1657 | |
| 1658 for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) { | |
| 1659 FilePath path; | |
| 1660 ::_tputenv_s(kTmpKey, kTmpValues[i]); | |
| 1661 GetTempDir(&path); | |
| 1662 EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] << | |
| 1663 " result=" << path.value(); | |
| 1664 } | |
| 1665 | |
| 1666 // Restore the original $TMP. | |
| 1667 if (original_tmp) { | |
| 1668 ::_tputenv_s(kTmpKey, original_tmp); | |
| 1669 free(original_tmp); | |
| 1670 } else { | |
| 1671 ::_tputenv_s(kTmpKey, _T("")); | |
| 1672 } | |
| 1673 } | |
| 1674 #endif // OS_WIN | |
| 1675 | |
| 1676 TEST_F(FileUtilTest, CreateTemporaryFileTest) { | 1163 TEST_F(FileUtilTest, CreateTemporaryFileTest) { |
| 1677 FilePath temp_files[3]; | 1164 FilePath temp_files[3]; |
| 1678 for (int i = 0; i < 3; i++) { | 1165 for (int i = 0; i < 3; i++) { |
| 1679 ASSERT_TRUE(CreateTemporaryFile(&(temp_files[i]))); | 1166 ASSERT_TRUE(CreateTemporaryFile(&(temp_files[i]))); |
| 1680 EXPECT_TRUE(PathExists(temp_files[i])); | 1167 EXPECT_TRUE(PathExists(temp_files[i])); |
| 1681 EXPECT_FALSE(DirectoryExists(temp_files[i])); | 1168 EXPECT_FALSE(DirectoryExists(temp_files[i])); |
| 1682 } | 1169 } |
| 1683 for (int i = 0; i < 3; i++) | 1170 for (int i = 0; i < 3; i++) |
| 1684 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]); | 1171 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]); |
| 1685 for (int i = 0; i < 3; i++) | 1172 for (int i = 0; i < 3; i++) |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1758 // So here we just test that it returns something "reasonable". | 1245 // So here we just test that it returns something "reasonable". |
| 1759 FilePath home = GetHomeDir(); | 1246 FilePath home = GetHomeDir(); |
| 1760 ASSERT_FALSE(home.empty()); | 1247 ASSERT_FALSE(home.empty()); |
| 1761 ASSERT_TRUE(home.IsAbsolute()); | 1248 ASSERT_TRUE(home.IsAbsolute()); |
| 1762 #endif | 1249 #endif |
| 1763 } | 1250 } |
| 1764 | 1251 |
| 1765 TEST_F(FileUtilTest, CreateDirectoryTest) { | 1252 TEST_F(FileUtilTest, CreateDirectoryTest) { |
| 1766 FilePath test_root = | 1253 FilePath test_root = |
| 1767 temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test")); | 1254 temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test")); |
| 1768 #if defined(OS_WIN) | 1255 #if defined(OS_POSIX) |
| 1769 FilePath test_path = | |
| 1770 test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\")); | |
| 1771 #elif defined(OS_POSIX) | |
| 1772 FilePath test_path = | 1256 FilePath test_path = |
| 1773 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/")); | 1257 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/")); |
| 1774 #endif | 1258 #endif |
| 1775 | 1259 |
| 1776 EXPECT_FALSE(PathExists(test_path)); | 1260 EXPECT_FALSE(PathExists(test_path)); |
| 1777 EXPECT_TRUE(CreateDirectory(test_path)); | 1261 EXPECT_TRUE(CreateDirectory(test_path)); |
| 1778 EXPECT_TRUE(PathExists(test_path)); | 1262 EXPECT_TRUE(PathExists(test_path)); |
| 1779 // CreateDirectory returns true if the DirectoryExists returns true. | 1263 // CreateDirectory returns true if the DirectoryExists returns true. |
| 1780 EXPECT_TRUE(CreateDirectory(test_path)); | 1264 EXPECT_TRUE(CreateDirectory(test_path)); |
| 1781 | 1265 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1798 while (top_level != top_level.DirName()) { | 1282 while (top_level != top_level.DirName()) { |
| 1799 top_level = top_level.DirName(); | 1283 top_level = top_level.DirName(); |
| 1800 } | 1284 } |
| 1801 ASSERT_TRUE(DirectoryExists(top_level)); | 1285 ASSERT_TRUE(DirectoryExists(top_level)); |
| 1802 | 1286 |
| 1803 // Given these assumptions hold, it should be safe to | 1287 // Given these assumptions hold, it should be safe to |
| 1804 // test that "creating" these directories succeeds. | 1288 // test that "creating" these directories succeeds. |
| 1805 EXPECT_TRUE(CreateDirectory( | 1289 EXPECT_TRUE(CreateDirectory( |
| 1806 FilePath(FilePath::kCurrentDirectory))); | 1290 FilePath(FilePath::kCurrentDirectory))); |
| 1807 EXPECT_TRUE(CreateDirectory(top_level)); | 1291 EXPECT_TRUE(CreateDirectory(top_level)); |
| 1808 | |
| 1809 #if defined(OS_WIN) | |
| 1810 FilePath invalid_drive(FILE_PATH_LITERAL("o:\\")); | |
| 1811 FilePath invalid_path = | |
| 1812 invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir")); | |
| 1813 if (!PathExists(invalid_drive)) { | |
| 1814 EXPECT_FALSE(CreateDirectory(invalid_path)); | |
| 1815 } | |
| 1816 #endif | |
| 1817 } | 1292 } |
| 1818 | 1293 |
| 1819 TEST_F(FileUtilTest, DetectDirectoryTest) { | 1294 TEST_F(FileUtilTest, DetectDirectoryTest) { |
| 1820 // Check a directory | 1295 // Check a directory |
| 1821 FilePath test_root = | 1296 FilePath test_root = |
| 1822 temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test")); | 1297 temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test")); |
| 1823 EXPECT_FALSE(PathExists(test_root)); | 1298 EXPECT_FALSE(PathExists(test_root)); |
| 1824 EXPECT_TRUE(CreateDirectory(test_root)); | 1299 EXPECT_TRUE(CreateDirectory(test_root)); |
| 1825 EXPECT_TRUE(PathExists(test_root)); | 1300 EXPECT_TRUE(PathExists(test_root)); |
| 1826 EXPECT_TRUE(DirectoryExists(test_root)); | 1301 EXPECT_TRUE(DirectoryExists(test_root)); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1928 // Enumerate with a pattern. | 1403 // Enumerate with a pattern. |
| 1929 FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*")); | 1404 FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*")); |
| 1930 FindResultCollector c5(&f5); | 1405 FindResultCollector c5(&f5); |
| 1931 EXPECT_TRUE(c5.HasFile(dir1)); | 1406 EXPECT_TRUE(c5.HasFile(dir1)); |
| 1932 EXPECT_TRUE(c5.HasFile(dir2)); | 1407 EXPECT_TRUE(c5.HasFile(dir2)); |
| 1933 EXPECT_TRUE(c5.HasFile(dir2file)); | 1408 EXPECT_TRUE(c5.HasFile(dir2file)); |
| 1934 EXPECT_TRUE(c5.HasFile(dir2inner)); | 1409 EXPECT_TRUE(c5.HasFile(dir2inner)); |
| 1935 EXPECT_TRUE(c5.HasFile(dir2innerfile)); | 1410 EXPECT_TRUE(c5.HasFile(dir2innerfile)); |
| 1936 EXPECT_EQ(5, c5.size()); | 1411 EXPECT_EQ(5, c5.size()); |
| 1937 | 1412 |
| 1938 #if defined(OS_WIN) | |
| 1939 { | |
| 1940 // Make dir1 point to dir2. | |
| 1941 ReparsePoint reparse_point(dir1, dir2); | |
| 1942 EXPECT_TRUE(reparse_point.IsValid()); | |
| 1943 | |
| 1944 if ((win::GetVersion() >= win::VERSION_VISTA)) { | |
| 1945 // There can be a delay for the enumeration code to see the change on | |
| 1946 // the file system so skip this test for XP. | |
| 1947 // Enumerate the reparse point. | |
| 1948 FileEnumerator f6(dir1, true, FILES_AND_DIRECTORIES); | |
| 1949 FindResultCollector c6(&f6); | |
| 1950 FilePath inner2 = dir1.Append(FPL("inner")); | |
| 1951 EXPECT_TRUE(c6.HasFile(inner2)); | |
| 1952 EXPECT_TRUE(c6.HasFile(inner2.Append(FPL("innerfile.txt")))); | |
| 1953 EXPECT_TRUE(c6.HasFile(dir1.Append(FPL("dir2file.txt")))); | |
| 1954 EXPECT_EQ(3, c6.size()); | |
| 1955 } | |
| 1956 | |
| 1957 // No changes for non recursive operation. | |
| 1958 FileEnumerator f7(temp_dir_.path(), false, FILES_AND_DIRECTORIES); | |
| 1959 FindResultCollector c7(&f7); | |
| 1960 EXPECT_TRUE(c7.HasFile(dir2)); | |
| 1961 EXPECT_TRUE(c7.HasFile(dir2)); | |
| 1962 EXPECT_TRUE(c7.HasFile(file1)); | |
| 1963 EXPECT_TRUE(c7.HasFile(file2_abs)); | |
| 1964 EXPECT_EQ(4, c7.size()); | |
| 1965 | |
| 1966 // Should not enumerate inside dir1 when using recursion. | |
| 1967 FileEnumerator f8(temp_dir_.path(), true, FILES_AND_DIRECTORIES); | |
| 1968 FindResultCollector c8(&f8); | |
| 1969 EXPECT_TRUE(c8.HasFile(dir1)); | |
| 1970 EXPECT_TRUE(c8.HasFile(dir2)); | |
| 1971 EXPECT_TRUE(c8.HasFile(file1)); | |
| 1972 EXPECT_TRUE(c8.HasFile(file2_abs)); | |
| 1973 EXPECT_TRUE(c8.HasFile(dir2file)); | |
| 1974 EXPECT_TRUE(c8.HasFile(dir2inner)); | |
| 1975 EXPECT_TRUE(c8.HasFile(dir2innerfile)); | |
| 1976 EXPECT_EQ(7, c8.size()); | |
| 1977 } | |
| 1978 #endif | |
| 1979 | |
| 1980 // Make sure the destructor closes the find handle while in the middle of a | 1413 // Make sure the destructor closes the find handle while in the middle of a |
| 1981 // query to allow TearDown to delete the directory. | 1414 // query to allow TearDown to delete the directory. |
| 1982 FileEnumerator f9(temp_dir_.path(), true, FILES_AND_DIRECTORIES); | 1415 FileEnumerator f9(temp_dir_.path(), true, FILES_AND_DIRECTORIES); |
| 1983 EXPECT_FALSE(f9.Next().value().empty()); // Should have found something | 1416 EXPECT_FALSE(f9.Next().value().empty()); // Should have found something |
| 1984 // (we don't care what). | 1417 // (we don't care what). |
| 1985 } | 1418 } |
| 1986 | 1419 |
| 1987 TEST_F(FileUtilTest, AppendToFile) { | 1420 TEST_F(FileUtilTest, AppendToFile) { |
| 1988 FilePath data_dir = | 1421 FilePath data_dir = |
| 1989 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); | 1422 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2527 // Trying to close it should crash. This is important for security. | 1960 // Trying to close it should crash. This is important for security. |
| 2528 EXPECT_DEATH(CloseWithScopedFD(fds[1]), ""); | 1961 EXPECT_DEATH(CloseWithScopedFD(fds[1]), ""); |
| 2529 #endif | 1962 #endif |
| 2530 } | 1963 } |
| 2531 | 1964 |
| 2532 #endif // defined(OS_POSIX) | 1965 #endif // defined(OS_POSIX) |
| 2533 | 1966 |
| 2534 } // namespace | 1967 } // namespace |
| 2535 | 1968 |
| 2536 } // namespace base | 1969 } // namespace base |
| OLD | NEW |