1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "build/build_config.h" 6 7 #if defined(OS_WIN) 8 #include <windows.h> 9 #include <winioctl.h> 10 #include <shellapi.h> 11 #include <shlobj.h> 12 #include <tchar.h> 13 #endif 14 15 #include <fstream> 16 #include <set> 17 18 #include "base/base_paths.h" 19 #include "base/file_path.h" 20 #include "base/file_util.h" 21 #include "base/memory/scoped_temp_dir.h" 22 #include "base/path_service.h" 23 #include "base/threading/platform_thread.h" 24 #include "base/time.h" 25 #include "base/utf_string_conversions.h" 26 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/platform_test.h" 28 29 #if defined(OS_WIN) 30 #include "base/win/scoped_handle.h" 31 #endif 32 33 // This macro helps avoid wrapped lines in the test structs. 34 #define FPL(x) FILE_PATH_LITERAL(x) 35 36 namespace { 37 38 // To test that file_util::Normalize FilePath() deals with NTFS reparse points 39 // correctly, we need functions to create and delete reparse points. 40 #if defined(OS_WIN) 41 typedef struct _REPARSE_DATA_BUFFER { 42 ULONG ReparseTag; 43 USHORT ReparseDataLength; 44 USHORT Reserved; 45 union { 46 struct { 47 USHORT SubstituteNameOffset; 48 USHORT SubstituteNameLength; 49 USHORT PrintNameOffset; 50 USHORT PrintNameLength; 51 ULONG Flags; 52 WCHAR PathBuffer[1]; 53 } SymbolicLinkReparseBuffer; 54 struct { 55 USHORT SubstituteNameOffset; 56 USHORT SubstituteNameLength; 57 USHORT PrintNameOffset; 58 USHORT PrintNameLength; 59 WCHAR PathBuffer[1]; 60 } MountPointReparseBuffer; 61 struct { 62 UCHAR DataBuffer[1]; 63 } GenericReparseBuffer; 64 }; 65 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 66 67 // Sets a reparse point. |source| will now point to |target|. Returns true if 68 // the call succeeds, false otherwise. 69 bool SetReparsePoint(HANDLE source, const FilePath& target_path) { 70 std::wstring kPathPrefix = L"\\??\\"; 71 std::wstring target_str; 72 // The juction will not work if the target path does not start with \??\ . 73 if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size())) 74 target_str += kPathPrefix; 75 target_str += target_path.value(); 76 const wchar_t* target = target_str.c_str(); 77 USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]); 78 char buffer[2000] = {0}; 79 DWORD returned; 80 81 REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer); 82 83 data->ReparseTag = 0xa0000003; 84 memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2); 85 86 data->MountPointReparseBuffer.SubstituteNameLength = size_target; 87 data->MountPointReparseBuffer.PrintNameOffset = size_target + 2; 88 data->ReparseDataLength = size_target + 4 + 8; 89 90 int data_size = data->ReparseDataLength + 8; 91 92 if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size, 93 NULL, 0, &returned, NULL)) { 94 return false; 95 } 96 return true; 97 } 98 99 // Delete the reparse point referenced by |source|. Returns true if the call 100 // succeeds, false otherwise. 101 bool DeleteReparsePoint(HANDLE source) { 102 DWORD returned; 103 REPARSE_DATA_BUFFER data = {0}; 104 data.ReparseTag = 0xa0000003; 105 if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0, 106 &returned, NULL)) { 107 return false; 108 } 109 return true; 110 } 111 #endif 112 113 const wchar_t bogus_content[] = L"I'm cannon fodder."; 114 115 const file_util::FileEnumerator::FILE_TYPE FILES_AND_DIRECTORIES = 116 static_cast<file_util::FileEnumerator::FILE_TYPE>( 117 file_util::FileEnumerator::FILES | 118 file_util::FileEnumerator::DIRECTORIES); 119 120 // file_util winds up using autoreleased objects on the Mac, so this needs 121 // to be a PlatformTest 122 class FileUtilTest : public PlatformTest { 123 protected: 124 virtual void SetUp() { 125 PlatformTest::SetUp(); 126 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 127 } 128 129 ScopedTempDir temp_dir_; 130 }; 131 132 // Collects all the results from the given file enumerator, and provides an 133 // interface to query whether a given file is present. 134 class FindResultCollector { 135 public: 136 explicit FindResultCollector(file_util::FileEnumerator& enumerator) { 137 FilePath cur_file; 138 while (!(cur_file = enumerator.Next()).value().empty()) { 139 FilePath::StringType path = cur_file.value(); 140 // The file should not be returned twice. 141 EXPECT_TRUE(files_.end() == files_.find(path)) 142 << "Same file returned twice"; 143 144 // Save for later. 145 files_.insert(path); 146 } 147 } 148 149 // Returns true if the enumerator found the file. 150 bool HasFile(const FilePath& file) const { 151 return files_.find(file.value()) != files_.end(); 152 } 153 154 int size() { 155 return static_cast<int>(files_.size()); 156 } 157 158 private: 159 std::set<FilePath::StringType> files_; 160 }; 161 162 // Simple function to dump some text into a new file. 163 void CreateTextFile(const FilePath& filename, 164 const std::wstring& contents) { 165 std::wofstream file; 166 file.open(filename.value().c_str()); 167 ASSERT_TRUE(file.is_open()); 168 file << contents; 169 file.close(); 170 } 171 172 // Simple function to take out some text from a file. 173 std::wstring ReadTextFile(const FilePath& filename) { 174 wchar_t contents[64]; 175 std::wifstream file; 176 file.open(filename.value().c_str()); 177 EXPECT_TRUE(file.is_open()); 178 file.getline(contents, arraysize(contents)); 179 file.close(); 180 return std::wstring(contents); 181 } 182 183 #if defined(OS_WIN) 184 uint64 FileTimeAsUint64(const FILETIME& ft) { 185 ULARGE_INTEGER u; 186 u.LowPart = ft.dwLowDateTime; 187 u.HighPart = ft.dwHighDateTime; 188 return u.QuadPart; 189 } 190 #endif 191 192 const struct append_case { 193 const wchar_t* path; 194 const wchar_t* ending; 195 const wchar_t* result; 196 } append_cases[] = { 197 #if defined(OS_WIN) 198 {L"c:\\colon\\backslash", L"path", L"c:\\colon\\backslash\\path"}, 199 {L"c:\\colon\\backslash\\", L"path", L"c:\\colon\\backslash\\path"}, 200 {L"c:\\colon\\backslash\\\\", L"path", L"c:\\colon\\backslash\\\\path"}, 201 {L"c:\\colon\\backslash\\", L"", L"c:\\colon\\backslash\\"}, 202 {L"c:\\colon\\backslash", L"", L"c:\\colon\\backslash\\"}, 203 {L"", L"path", L"\\path"}, 204 {L"", L"", L"\\"}, 205 #elif defined(OS_POSIX) 206 {L"/foo/bar", L"path", L"/foo/bar/path"}, 207 {L"/foo/bar/", L"path", L"/foo/bar/path"}, 208 {L"/foo/bar//", L"path", L"/foo/bar//path"}, 209 {L"/foo/bar/", L"", L"/foo/bar/"}, 210 {L"/foo/bar", L"", L"/foo/bar/"}, 211 {L"", L"path", L"/path"}, 212 {L"", L"", L"/"}, 213 #endif 214 }; 215 216 #if defined(OS_WIN) 217 // This function is deprecated, but still used on Windows. 218 TEST_F(FileUtilTest, AppendToPath) { 219 for (unsigned int i = 0; i < arraysize(append_cases); ++i) { 220 const append_case& value = append_cases[i]; 221 std::wstring result = value.path; 222 file_util::AppendToPath(&result, value.ending); 223 EXPECT_EQ(value.result, result); 224 } 225 226 #ifdef NDEBUG 227 file_util::AppendToPath(NULL, L"path"); // asserts in debug mode 228 #endif 229 } 230 #endif // defined(OS_WIN) 231 232 static const struct filename_case { 233 const wchar_t* path; 234 const wchar_t* filename; 235 } filename_cases[] = { 236 #if defined(OS_WIN) 237 {L"c:\\colon\\backslash", L"backslash"}, 238 {L"c:\\colon\\backslash\\", L""}, 239 {L"\\\\filename.exe", L"filename.exe"}, 240 {L"filename.exe", L"filename.exe"}, 241 {L"", L""}, 242 {L"\\\\\\", L""}, 243 {L"c:/colon/backslash", L"backslash"}, 244 {L"c:/colon/backslash/", L""}, 245 {L"//////", L""}, 246 {L"///filename.exe", L"filename.exe"}, 247 #elif defined(OS_POSIX) 248 {L"/foo/bar", L"bar"}, 249 {L"/foo/bar/", L""}, 250 {L"/filename.exe", L"filename.exe"}, 251 {L"filename.exe", L"filename.exe"}, 252 {L"", L""}, 253 {L"/", L""}, 254 #endif 255 }; 256 257 // Test finding the file type from a path name 258 static const struct extension_case { 259 const wchar_t* path; 260 const wchar_t* extension; 261 } extension_cases[] = { 262 #if defined(OS_WIN) 263 {L"C:\\colon\\backslash\\filename.extension", L"extension"}, 264 {L"C:\\colon\\backslash\\filename.", L""}, 265 {L"C:\\colon\\backslash\\filename", L""}, 266 {L"C:\\colon\\backslash\\", L""}, 267 {L"C:\\colon\\backslash.\\", L""}, 268 {L"C:\\colon\\backslash\filename.extension.extension2", L"extension2"}, 269 #elif defined(OS_POSIX) 270 {L"/foo/bar/filename.extension", L"extension"}, 271 {L"/foo/bar/filename.", L""}, 272 {L"/foo/bar/filename", L""}, 273 {L"/foo/bar/", L""}, 274 {L"/foo/bar./", L""}, 275 {L"/foo/bar/filename.extension.extension2", L"extension2"}, 276 {L".", L""}, 277 {L"..", L""}, 278 {L"./foo", L""}, 279 {L"./foo.extension", L"extension"}, 280 {L"/foo.extension1/bar.extension2", L"extension2"}, 281 #endif 282 }; 283 284 #if defined(OS_WIN) 285 // This function has been deprecated on non-Windows. 286 TEST_F(FileUtilTest, GetFileExtensionFromPath) { 287 for (unsigned int i = 0; i < arraysize(extension_cases); ++i) { 288 const extension_case& ext = extension_cases[i]; 289 const std::wstring fext = file_util::GetFileExtensionFromPath(ext.path); 290 EXPECT_EQ(ext.extension, fext); 291 } 292 } 293 #endif 294 295 // Test finding the directory component of a path 296 static const struct dir_case { 297 const wchar_t* full_path; 298 const wchar_t* directory; 299 } dir_cases[] = { 300 #if defined(OS_WIN) 301 {L"C:\\WINDOWS\\system32\\gdi32.dll", L"C:\\WINDOWS\\system32"}, 302 {L"C:\\WINDOWS\\system32\\not_exist_thx_1138", L"C:\\WINDOWS\\system32"}, 303 {L"C:\\WINDOWS\\system32\\", L"C:\\WINDOWS\\system32"}, 304 {L"C:\\WINDOWS\\system32\\\\", L"C:\\WINDOWS\\system32"}, 305 {L"C:\\WINDOWS\\system32", L"C:\\WINDOWS"}, 306 {L"C:\\WINDOWS\\system32.\\", L"C:\\WINDOWS\\system32."}, 307 {L"C:\\", L"C:\\"}, 308 #elif defined(OS_POSIX) 309 {L"/foo/bar/gdi32.dll", L"/foo/bar"}, 310 {L"/foo/bar/not_exist_thx_1138", L"/foo/bar"}, 311 {L"/foo/bar/", L"/foo/bar"}, 312 {L"/foo/bar//", L"/foo/bar"}, 313 {L"/foo/bar", L"/foo"}, 314 {L"/foo/bar./", L"/foo/bar."}, 315 {L"/", L"/"}, 316 {L".", L"."}, 317 {L"..", L"."}, // yes, ".." technically lives in "." 318 #endif 319 }; 320 321 // Flaky, http://crbug.com/46246 322 TEST_F(FileUtilTest, FLAKY_CountFilesCreatedAfter) { 323 // Create old file (that we don't want to count) 324 FilePath old_file_name = 325 temp_dir_.path().Append(FILE_PATH_LITERAL("Old File.txt")); 326 CreateTextFile(old_file_name, L"Just call me Mr. Creakybits"); 327 328 // Age to perfection 329 #if defined(OS_WIN) 330 base::PlatformThread::Sleep(100); 331 #elif defined(OS_POSIX) 332 // We need to wait at least one second here because the precision of 333 // file creation time is one second. 334 base::PlatformThread::Sleep(1500); 335 #endif 336 337 // Establish our cutoff time 338 base::Time now(base::Time::NowFromSystemTime()); 339 EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_.path(), now)); 340 341 // Create a new file (that we do want to count) 342 FilePath new_file_name = 343 temp_dir_.path().Append(FILE_PATH_LITERAL("New File.txt")); 344 CreateTextFile(new_file_name, L"Waaaaaaaaaaaaaah."); 345 346 // We should see only the new file. 347 EXPECT_EQ(1, file_util::CountFilesCreatedAfter(temp_dir_.path(), now)); 348 349 // Delete new file, we should see no files after cutoff now 350 EXPECT_TRUE(file_util::Delete(new_file_name, false)); 351 EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_.path(), now)); 352 } 353 354 TEST_F(FileUtilTest, FileAndDirectorySize) { 355 // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize 356 // should return 53 bytes. 357 FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt")); 358 CreateTextFile(file_01, L"12345678901234567890"); 359 int64 size_f1 = 0; 360 ASSERT_TRUE(file_util::GetFileSize(file_01, &size_f1)); 361 EXPECT_EQ(20ll, size_f1); 362 363 FilePath subdir_path = temp_dir_.path().Append(FPL("Level2")); 364 file_util::CreateDirectory(subdir_path); 365 366 FilePath file_02 = subdir_path.Append(FPL("The file 02.txt")); 367 CreateTextFile(file_02, L"123456789012345678901234567890"); 368 int64 size_f2 = 0; 369 ASSERT_TRUE(file_util::GetFileSize(file_02, &size_f2)); 370 EXPECT_EQ(30ll, size_f2); 371 372 FilePath subsubdir_path = subdir_path.Append(FPL("Level3")); 373 file_util::CreateDirectory(subsubdir_path); 374 375 FilePath file_03 = subsubdir_path.Append(FPL("The file 03.txt")); 376 CreateTextFile(file_03, L"123"); 377 378 int64 computed_size = file_util::ComputeDirectorySize(temp_dir_.path()); 379 EXPECT_EQ(size_f1 + size_f2 + 3, computed_size); 380 381 computed_size = 382 file_util::ComputeFilesSize(temp_dir_.path(), FPL("The file*")); 383 EXPECT_EQ(size_f1, computed_size); 384 385 computed_size = file_util::ComputeFilesSize(temp_dir_.path(), FPL("bla*")); 386 EXPECT_EQ(0, computed_size); 387 } 388 389 TEST_F(FileUtilTest, NormalizeFilePathBasic) { 390 // Create a directory under the test dir. Because we create it, 391 // we know it is not a link. 392 FilePath file_a_path = temp_dir_.path().Append(FPL("file_a")); 393 FilePath dir_path = temp_dir_.path().Append(FPL("dir")); 394 FilePath file_b_path = dir_path.Append(FPL("file_b")); 395 file_util::CreateDirectory(dir_path); 396 397 FilePath normalized_file_a_path, normalized_file_b_path; 398 ASSERT_FALSE(file_util::PathExists(file_a_path)); 399 ASSERT_FALSE(file_util::NormalizeFilePath(file_a_path, 400 &normalized_file_a_path)) 401 << "NormalizeFilePath() should fail on nonexistent paths."; 402 403 CreateTextFile(file_a_path, bogus_content); 404 ASSERT_TRUE(file_util::PathExists(file_a_path)); 405 ASSERT_TRUE(file_util::NormalizeFilePath(file_a_path, 406 &normalized_file_a_path)); 407 408 CreateTextFile(file_b_path, bogus_content); 409 ASSERT_TRUE(file_util::PathExists(file_b_path)); 410 ASSERT_TRUE(file_util::NormalizeFilePath(file_b_path, 411 &normalized_file_b_path)); 412 413 // Beacuse this test created |dir_path|, we know it is not a link 414 // or junction. So, the real path of the directory holding file a 415 // must be the parent of the path holding file b. 416 ASSERT_TRUE(normalized_file_a_path.DirName() 417 .IsParent(normalized_file_b_path.DirName())); 418 } 419 420 #if defined(OS_WIN) 421 422 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) { 423 // Build the following directory structure: 424 // 425 // temp_dir 426 // |-> base_a 427 // | |-> sub_a 428 // | |-> file.txt 429 // | |-> long_name___... (Very long name.) 430 // | |-> sub_long 431 // | |-> deep.txt 432 // |-> base_b 433 // |-> to_sub_a (reparse point to temp_dir\base_a\sub_a) 434 // |-> to_base_b (reparse point to temp_dir\base_b) 435 // |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long) 436 437 FilePath base_a = temp_dir_.path().Append(FPL("base_a")); 438 ASSERT_TRUE(file_util::CreateDirectory(base_a)); 439 440 FilePath sub_a = base_a.Append(FPL("sub_a")); 441 ASSERT_TRUE(file_util::CreateDirectory(sub_a)); 442 443 FilePath file_txt = sub_a.Append(FPL("file.txt")); 444 CreateTextFile(file_txt, bogus_content); 445 446 // Want a directory whose name is long enough to make the path to the file 447 // inside just under MAX_PATH chars. This will be used to test that when 448 // a junction expands to a path over MAX_PATH chars in length, 449 // NormalizeFilePath() fails without crashing. 450 FilePath sub_long_rel(FPL("sub_long")); 451 FilePath deep_txt(FPL("deep.txt")); 452 453 int target_length = MAX_PATH; 454 target_length -= (sub_a.value().length() + 1); // +1 for the sepperator '\'. 455 target_length -= (sub_long_rel.Append(deep_txt).value().length() + 1); 456 // Without making the path a bit shorter, CreateDirectory() fails. 457 // the resulting path is still long enough to hit the failing case in 458 // NormalizePath(). 459 const int kCreateDirLimit = 4; 460 target_length -= kCreateDirLimit; 461 FilePath::StringType long_name_str = FPL("long_name_"); 462 long_name_str.resize(target_length, '_'); 463 464 FilePath long_name = sub_a.Append(FilePath(long_name_str)); 465 FilePath deep_file = long_name.Append(sub_long_rel).Append(deep_txt); 466 ASSERT_EQ(MAX_PATH - kCreateDirLimit, deep_file.value().length()); 467 468 FilePath sub_long = deep_file.DirName(); 469 ASSERT_TRUE(file_util::CreateDirectory(sub_long)); 470 CreateTextFile(deep_file, bogus_content); 471 472 FilePath base_b = temp_dir_.path().Append(FPL("base_b")); 473 ASSERT_TRUE(file_util::CreateDirectory(base_b)); 474 475 FilePath to_sub_a = base_b.Append(FPL("to_sub_a")); 476 ASSERT_TRUE(file_util::CreateDirectory(to_sub_a)); 477 base::win::ScopedHandle reparse_to_sub_a( 478 ::CreateFile(to_sub_a.value().c_str(), 479 FILE_ALL_ACCESS, 480 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 481 NULL, 482 OPEN_EXISTING, 483 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. 484 NULL)); 485 ASSERT_TRUE(reparse_to_sub_a.IsValid()); 486 ASSERT_TRUE(SetReparsePoint(reparse_to_sub_a, sub_a)); 487 488 FilePath to_base_b = base_b.Append(FPL("to_base_b")); 489 ASSERT_TRUE(file_util::CreateDirectory(to_base_b)); 490 base::win::ScopedHandle reparse_to_base_b( 491 ::CreateFile(to_base_b.value().c_str(), 492 FILE_ALL_ACCESS, 493 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 494 NULL, 495 OPEN_EXISTING, 496 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. 497 NULL)); 498 ASSERT_TRUE(reparse_to_base_b.IsValid()); 499 ASSERT_TRUE(SetReparsePoint(reparse_to_base_b, base_b)); 500 501 FilePath to_sub_long = base_b.Append(FPL("to_sub_long")); 502 ASSERT_TRUE(file_util::CreateDirectory(to_sub_long)); 503 base::win::ScopedHandle reparse_to_sub_long( 504 ::CreateFile(to_sub_long.value().c_str(), 505 FILE_ALL_ACCESS, 506 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 507 NULL, 508 OPEN_EXISTING, 509 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. 510 NULL)); 511 ASSERT_TRUE(reparse_to_sub_long.IsValid()); 512 ASSERT_TRUE(SetReparsePoint(reparse_to_sub_long, sub_long)); 513 514 // Normalize a junction free path: base_a\sub_a\file.txt . 515 FilePath normalized_path; 516 ASSERT_TRUE(file_util::NormalizeFilePath(file_txt, &normalized_path)); 517 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); 518 519 // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude 520 // the junction to_sub_a. 521 ASSERT_TRUE(file_util::NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), 522 &normalized_path)); 523 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); 524 525 // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be 526 // normalized to exclude junctions to_base_b and to_sub_a . 527 ASSERT_TRUE(file_util::NormalizeFilePath(base_b.Append(FPL("to_base_b")) 528 .Append(FPL("to_base_b")) 529 .Append(FPL("to_sub_a")) 530 .Append(FPL("file.txt")), 531 &normalized_path)); 532 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); 533 534 // A long enough path will cause NormalizeFilePath() to fail. Make a long 535 // path using to_base_b many times, and check that paths long enough to fail 536 // do not cause a crash. 537 FilePath long_path = base_b; 538 const int kLengthLimit = MAX_PATH + 200; 539 while (long_path.value().length() <= kLengthLimit) { 540 long_path = long_path.Append(FPL("to_base_b")); 541 } 542 long_path = long_path.Append(FPL("to_sub_a")) 543 .Append(FPL("file.txt")); 544 545 ASSERT_FALSE(file_util::NormalizeFilePath(long_path, &normalized_path)); 546 547 // Normalizing the junction to deep.txt should fail, because the expanded 548 // path to deep.txt is longer than MAX_PATH. 549 ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_long.Append(deep_txt), 550 &normalized_path)); 551 552 // Delete the reparse points, and see that NormalizeFilePath() fails 553 // to traverse them. 554 ASSERT_TRUE(DeleteReparsePoint(reparse_to_sub_a)); 555 ASSERT_TRUE(DeleteReparsePoint(reparse_to_base_b)); 556 ASSERT_TRUE(DeleteReparsePoint(reparse_to_sub_long)); 557 558 ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), 559 &normalized_path)); 560 } 561 562 #endif // defined(OS_WIN) 563 564 #if defined(OS_POSIX) 565 566 TEST_F(FileUtilTest, CreateAndReadSymlinks) { 567 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); 568 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); 569 CreateTextFile(link_to, bogus_content); 570 571 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 572 << "Failed to create file symlink."; 573 574 // If we created the link properly, we should be able to read the 575 // contents through it. 576 std::wstring contents = ReadTextFile(link_from); 577 ASSERT_EQ(contents, bogus_content); 578 579 FilePath result; 580 ASSERT_TRUE(file_util::ReadSymbolicLink(link_from, &result)); 581 ASSERT_EQ(link_to.value(), result.value()); 582 583 // Link to a directory. 584 link_from = temp_dir_.path().Append(FPL("from_dir")); 585 link_to = temp_dir_.path().Append(FPL("to_dir")); 586 file_util::CreateDirectory(link_to); 587 588 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 589 << "Failed to create directory symlink."; 590 591 // Test failures. 592 ASSERT_FALSE(file_util::CreateSymbolicLink(link_to, link_to)); 593 ASSERT_FALSE(file_util::ReadSymbolicLink(link_to, &result)); 594 FilePath missing = temp_dir_.path().Append(FPL("missing")); 595 ASSERT_FALSE(file_util::ReadSymbolicLink(missing, &result)); 596 } 597 598 599 // The following test of NormalizeFilePath() require that we create a symlink. 600 // This can not be done on Windows before Vista. On Vista, creating a symlink 601 // requires privilege "SeCreateSymbolicLinkPrivilege". 602 // TODO(skerner): Investigate the possibility of giving base_unittests the 603 // privileges required to create a symlink. 604 TEST_F(FileUtilTest, NormalizeFilePathSymlinks) { 605 FilePath normalized_path; 606 607 // Link one file to another. 608 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); 609 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); 610 CreateTextFile(link_to, bogus_content); 611 612 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 613 << "Failed to create file symlink."; 614 615 // Check that NormalizeFilePath sees the link. 616 ASSERT_TRUE(file_util::NormalizeFilePath(link_from, &normalized_path)); 617 ASSERT_TRUE(link_to != link_from); 618 ASSERT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value()); 619 ASSERT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value()); 620 621 // Link to a directory. 622 link_from = temp_dir_.path().Append(FPL("from_dir")); 623 link_to = temp_dir_.path().Append(FPL("to_dir")); 624 file_util::CreateDirectory(link_to); 625 626 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 627 << "Failed to create directory symlink."; 628 629 ASSERT_FALSE(file_util::NormalizeFilePath(link_from, &normalized_path)) 630 << "Links to directories should return false."; 631 632 // Test that a loop in the links causes NormalizeFilePath() to return false. 633 link_from = temp_dir_.path().Append(FPL("link_a")); 634 link_to = temp_dir_.path().Append(FPL("link_b")); 635 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 636 << "Failed to create loop symlink a."; 637 ASSERT_TRUE(file_util::CreateSymbolicLink(link_from, link_to)) 638 << "Failed to create loop symlink b."; 639 640 // Infinite loop! 641 ASSERT_FALSE(file_util::NormalizeFilePath(link_from, &normalized_path)); 642 } 643 #endif // defined(OS_POSIX) 644 645 TEST_F(FileUtilTest, DeleteNonExistent) { 646 FilePath non_existent = temp_dir_.path().AppendASCII("bogus_file_dne.foobar"); 647 ASSERT_FALSE(file_util::PathExists(non_existent)); 648 649 EXPECT_TRUE(file_util::Delete(non_existent, false)); 650 ASSERT_FALSE(file_util::PathExists(non_existent)); 651 EXPECT_TRUE(file_util::Delete(non_existent, true)); 652 ASSERT_FALSE(file_util::PathExists(non_existent)); 653 } 654 655 TEST_F(FileUtilTest, DeleteFile) { 656 // Create a file 657 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 1.txt")); 658 CreateTextFile(file_name, bogus_content); 659 ASSERT_TRUE(file_util::PathExists(file_name)); 660 661 // Make sure it's deleted 662 EXPECT_TRUE(file_util::Delete(file_name, false)); 663 EXPECT_FALSE(file_util::PathExists(file_name)); 664 665 // Test recursive case, create a new file 666 file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt")); 667 CreateTextFile(file_name, bogus_content); 668 ASSERT_TRUE(file_util::PathExists(file_name)); 669 670 // Make sure it's deleted 671 EXPECT_TRUE(file_util::Delete(file_name, true)); 672 EXPECT_FALSE(file_util::PathExists(file_name)); 673 } 674 675 #if defined(OS_WIN) 676 // Tests that the Delete function works for wild cards, especially 677 // with the recursion flag. Also coincidentally tests PathExists. 678 // TODO(erikkay): see if anyone's actually using this feature of the API 679 TEST_F(FileUtilTest, DeleteWildCard) { 680 // Create a file and a directory 681 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteWildCard.txt")); 682 CreateTextFile(file_name, bogus_content); 683 ASSERT_TRUE(file_util::PathExists(file_name)); 684 685 FilePath subdir_path = temp_dir_.path().Append(FPL("DeleteWildCardDir")); 686 file_util::CreateDirectory(subdir_path); 687 ASSERT_TRUE(file_util::PathExists(subdir_path)); 688 689 // Create the wildcard path 690 FilePath directory_contents = temp_dir_.path(); 691 directory_contents = directory_contents.Append(FPL("*")); 692 693 // Delete non-recursively and check that only the file is deleted 694 EXPECT_TRUE(file_util::Delete(directory_contents, false)); 695 EXPECT_FALSE(file_util::PathExists(file_name)); 696 EXPECT_TRUE(file_util::PathExists(subdir_path)); 697 698 // Delete recursively and make sure all contents are deleted 699 EXPECT_TRUE(file_util::Delete(directory_contents, true)); 700 EXPECT_FALSE(file_util::PathExists(file_name)); 701 EXPECT_FALSE(file_util::PathExists(subdir_path)); 702 } 703 704 // TODO(erikkay): see if anyone's actually using this feature of the API 705 TEST_F(FileUtilTest, DeleteNonExistantWildCard) { 706 // Create a file and a directory 707 FilePath subdir_path = 708 temp_dir_.path().Append(FPL("DeleteNonExistantWildCard")); 709 file_util::CreateDirectory(subdir_path); 710 ASSERT_TRUE(file_util::PathExists(subdir_path)); 711 712 // Create the wildcard path 713 FilePath directory_contents = subdir_path; 714 directory_contents = directory_contents.Append(FPL("*")); 715 716 // Delete non-recursively and check nothing got deleted 717 EXPECT_TRUE(file_util::Delete(directory_contents, false)); 718 EXPECT_TRUE(file_util::PathExists(subdir_path)); 719 720 // Delete recursively and check nothing got deleted 721 EXPECT_TRUE(file_util::Delete(directory_contents, true)); 722 EXPECT_TRUE(file_util::PathExists(subdir_path)); 723 } 724 #endif 725 726 // Tests non-recursive Delete() for a directory. 727 TEST_F(FileUtilTest, DeleteDirNonRecursive) { 728 // Create a subdirectory and put a file and two directories inside. 729 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive")); 730 file_util::CreateDirectory(test_subdir); 731 ASSERT_TRUE(file_util::PathExists(test_subdir)); 732 733 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); 734 CreateTextFile(file_name, bogus_content); 735 ASSERT_TRUE(file_util::PathExists(file_name)); 736 737 FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1")); 738 file_util::CreateDirectory(subdir_path1); 739 ASSERT_TRUE(file_util::PathExists(subdir_path1)); 740 741 FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2")); 742 file_util::CreateDirectory(subdir_path2); 743 ASSERT_TRUE(file_util::PathExists(subdir_path2)); 744 745 // Delete non-recursively and check that the empty dir got deleted 746 EXPECT_TRUE(file_util::Delete(subdir_path2, false)); 747 EXPECT_FALSE(file_util::PathExists(subdir_path2)); 748 749 // Delete non-recursively and check that nothing got deleted 750 EXPECT_FALSE(file_util::Delete(test_subdir, false)); 751 EXPECT_TRUE(file_util::PathExists(test_subdir)); 752 EXPECT_TRUE(file_util::PathExists(file_name)); 753 EXPECT_TRUE(file_util::PathExists(subdir_path1)); 754 } 755 756 // Tests recursive Delete() for a directory. 757 TEST_F(FileUtilTest, DeleteDirRecursive) { 758 // Create a subdirectory and put a file and two directories inside. 759 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirRecursive")); 760 file_util::CreateDirectory(test_subdir); 761 ASSERT_TRUE(file_util::PathExists(test_subdir)); 762 763 FilePath file_name = test_subdir.Append(FPL("Test DeleteDirRecursive.txt")); 764 CreateTextFile(file_name, bogus_content); 765 ASSERT_TRUE(file_util::PathExists(file_name)); 766 767 FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1")); 768 file_util::CreateDirectory(subdir_path1); 769 ASSERT_TRUE(file_util::PathExists(subdir_path1)); 770 771 FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2")); 772 file_util::CreateDirectory(subdir_path2); 773 ASSERT_TRUE(file_util::PathExists(subdir_path2)); 774 775 // Delete recursively and check that the empty dir got deleted 776 EXPECT_TRUE(file_util::Delete(subdir_path2, true)); 777 EXPECT_FALSE(file_util::PathExists(subdir_path2)); 778 779 // Delete recursively and check that everything got deleted 780 EXPECT_TRUE(file_util::Delete(test_subdir, true)); 781 EXPECT_FALSE(file_util::PathExists(file_name)); 782 EXPECT_FALSE(file_util::PathExists(subdir_path1)); 783 EXPECT_FALSE(file_util::PathExists(test_subdir)); 784 } 785 786 TEST_F(FileUtilTest, MoveFileNew) { 787 // Create a file 788 FilePath file_name_from = 789 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 790 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 791 ASSERT_TRUE(file_util::PathExists(file_name_from)); 792 793 // The destination. 794 FilePath file_name_to = temp_dir_.path().Append( 795 FILE_PATH_LITERAL("Move_Test_File_Destination.txt")); 796 ASSERT_FALSE(file_util::PathExists(file_name_to)); 797 798 EXPECT_TRUE(file_util::Move(file_name_from, file_name_to)); 799 800 // Check everything has been moved. 801 EXPECT_FALSE(file_util::PathExists(file_name_from)); 802 EXPECT_TRUE(file_util::PathExists(file_name_to)); 803 } 804 805 TEST_F(FileUtilTest, MoveFileExists) { 806 // Create a file 807 FilePath file_name_from = 808 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 809 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 810 ASSERT_TRUE(file_util::PathExists(file_name_from)); 811 812 // The destination name. 813 FilePath file_name_to = temp_dir_.path().Append( 814 FILE_PATH_LITERAL("Move_Test_File_Destination.txt")); 815 CreateTextFile(file_name_to, L"Old file content"); 816 ASSERT_TRUE(file_util::PathExists(file_name_to)); 817 818 EXPECT_TRUE(file_util::Move(file_name_from, file_name_to)); 819 820 // Check everything has been moved. 821 EXPECT_FALSE(file_util::PathExists(file_name_from)); 822 EXPECT_TRUE(file_util::PathExists(file_name_to)); 823 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to)); 824 } 825 826 TEST_F(FileUtilTest, MoveFileDirExists) { 827 // Create a file 828 FilePath file_name_from = 829 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 830 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 831 ASSERT_TRUE(file_util::PathExists(file_name_from)); 832 833 // The destination directory 834 FilePath dir_name_to = 835 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 836 file_util::CreateDirectory(dir_name_to); 837 ASSERT_TRUE(file_util::PathExists(dir_name_to)); 838 839 EXPECT_FALSE(file_util::Move(file_name_from, dir_name_to)); 840 } 841 842 843 TEST_F(FileUtilTest, MoveNew) { 844 // Create a directory 845 FilePath dir_name_from = 846 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir")); 847 file_util::CreateDirectory(dir_name_from); 848 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 849 850 // Create a file under the directory 851 FilePath file_name_from = 852 dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 853 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 854 ASSERT_TRUE(file_util::PathExists(file_name_from)); 855 856 // Move the directory. 857 FilePath dir_name_to = 858 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_To_Subdir")); 859 FilePath file_name_to = 860 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 861 862 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 863 864 EXPECT_TRUE(file_util::Move(dir_name_from, dir_name_to)); 865 866 // Check everything has been moved. 867 EXPECT_FALSE(file_util::PathExists(dir_name_from)); 868 EXPECT_FALSE(file_util::PathExists(file_name_from)); 869 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 870 EXPECT_TRUE(file_util::PathExists(file_name_to)); 871 } 872 873 TEST_F(FileUtilTest, MoveExist) { 874 // Create a directory 875 FilePath dir_name_from = 876 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir")); 877 file_util::CreateDirectory(dir_name_from); 878 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 879 880 // Create a file under the directory 881 FilePath file_name_from = 882 dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 883 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 884 ASSERT_TRUE(file_util::PathExists(file_name_from)); 885 886 // Move the directory 887 FilePath dir_name_exists = 888 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 889 890 FilePath dir_name_to = 891 dir_name_exists.Append(FILE_PATH_LITERAL("Move_To_Subdir")); 892 FilePath file_name_to = 893 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 894 895 // Create the destination directory. 896 file_util::CreateDirectory(dir_name_exists); 897 ASSERT_TRUE(file_util::PathExists(dir_name_exists)); 898 899 EXPECT_TRUE(file_util::Move(dir_name_from, dir_name_to)); 900 901 // Check everything has been moved. 902 EXPECT_FALSE(file_util::PathExists(dir_name_from)); 903 EXPECT_FALSE(file_util::PathExists(file_name_from)); 904 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 905 EXPECT_TRUE(file_util::PathExists(file_name_to)); 906 } 907 908 TEST_F(FileUtilTest, CopyDirectoryRecursivelyNew) { 909 // Create a directory. 910 FilePath dir_name_from = 911 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 912 file_util::CreateDirectory(dir_name_from); 913 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 914 915 // Create a file under the directory. 916 FilePath file_name_from = 917 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 918 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 919 ASSERT_TRUE(file_util::PathExists(file_name_from)); 920 921 // Create a subdirectory. 922 FilePath subdir_name_from = 923 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 924 file_util::CreateDirectory(subdir_name_from); 925 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 926 927 // Create a file under the subdirectory. 928 FilePath file_name2_from = 929 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 930 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 931 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 932 933 // Copy the directory recursively. 934 FilePath dir_name_to = 935 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 936 FilePath file_name_to = 937 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 938 FilePath subdir_name_to = 939 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 940 FilePath file_name2_to = 941 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 942 943 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 944 945 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_to, true)); 946 947 // Check everything has been copied. 948 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 949 EXPECT_TRUE(file_util::PathExists(file_name_from)); 950 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 951 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 952 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 953 EXPECT_TRUE(file_util::PathExists(file_name_to)); 954 EXPECT_TRUE(file_util::PathExists(subdir_name_to)); 955 EXPECT_TRUE(file_util::PathExists(file_name2_to)); 956 } 957 958 TEST_F(FileUtilTest, CopyDirectoryRecursivelyExists) { 959 // Create a directory. 960 FilePath dir_name_from = 961 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 962 file_util::CreateDirectory(dir_name_from); 963 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 964 965 // Create a file under the directory. 966 FilePath file_name_from = 967 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 968 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 969 ASSERT_TRUE(file_util::PathExists(file_name_from)); 970 971 // Create a subdirectory. 972 FilePath subdir_name_from = 973 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 974 file_util::CreateDirectory(subdir_name_from); 975 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 976 977 // Create a file under the subdirectory. 978 FilePath file_name2_from = 979 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 980 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 981 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 982 983 // Copy the directory recursively. 984 FilePath dir_name_exists = 985 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 986 987 FilePath dir_name_to = 988 dir_name_exists.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 989 FilePath file_name_to = 990 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 991 FilePath subdir_name_to = 992 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 993 FilePath file_name2_to = 994 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 995 996 // Create the destination directory. 997 file_util::CreateDirectory(dir_name_exists); 998 ASSERT_TRUE(file_util::PathExists(dir_name_exists)); 999 1000 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_exists, true)); 1001 1002 // Check everything has been copied. 1003 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 1004 EXPECT_TRUE(file_util::PathExists(file_name_from)); 1005 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 1006 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 1007 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 1008 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1009 EXPECT_TRUE(file_util::PathExists(subdir_name_to)); 1010 EXPECT_TRUE(file_util::PathExists(file_name2_to)); 1011 } 1012 1013 TEST_F(FileUtilTest, CopyDirectoryNew) { 1014 // Create a directory. 1015 FilePath dir_name_from = 1016 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1017 file_util::CreateDirectory(dir_name_from); 1018 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 1019 1020 // Create a file under the directory. 1021 FilePath file_name_from = 1022 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1023 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1024 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1025 1026 // Create a subdirectory. 1027 FilePath subdir_name_from = 1028 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 1029 file_util::CreateDirectory(subdir_name_from); 1030 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 1031 1032 // Create a file under the subdirectory. 1033 FilePath file_name2_from = 1034 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1035 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 1036 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 1037 1038 // Copy the directory not recursively. 1039 FilePath dir_name_to = 1040 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 1041 FilePath file_name_to = 1042 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1043 FilePath subdir_name_to = 1044 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 1045 1046 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 1047 1048 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_to, false)); 1049 1050 // Check everything has been copied. 1051 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 1052 EXPECT_TRUE(file_util::PathExists(file_name_from)); 1053 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 1054 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 1055 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 1056 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1057 EXPECT_FALSE(file_util::PathExists(subdir_name_to)); 1058 } 1059 1060 TEST_F(FileUtilTest, CopyDirectoryExists) { 1061 // Create a directory. 1062 FilePath dir_name_from = 1063 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1064 file_util::CreateDirectory(dir_name_from); 1065 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 1066 1067 // Create a file under the directory. 1068 FilePath file_name_from = 1069 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1070 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1071 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1072 1073 // Create a subdirectory. 1074 FilePath subdir_name_from = 1075 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 1076 file_util::CreateDirectory(subdir_name_from); 1077 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 1078 1079 // Create a file under the subdirectory. 1080 FilePath file_name2_from = 1081 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1082 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 1083 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 1084 1085 // Copy the directory not recursively. 1086 FilePath dir_name_to = 1087 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 1088 FilePath file_name_to = 1089 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1090 FilePath subdir_name_to = 1091 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 1092 1093 // Create the destination directory. 1094 file_util::CreateDirectory(dir_name_to); 1095 ASSERT_TRUE(file_util::PathExists(dir_name_to)); 1096 1097 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_to, false)); 1098 1099 // Check everything has been copied. 1100 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 1101 EXPECT_TRUE(file_util::PathExists(file_name_from)); 1102 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 1103 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 1104 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 1105 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1106 EXPECT_FALSE(file_util::PathExists(subdir_name_to)); 1107 } 1108 1109 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToNew) { 1110 // Create a file 1111 FilePath file_name_from = 1112 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1113 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1114 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1115 1116 // The destination name 1117 FilePath file_name_to = temp_dir_.path().Append( 1118 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt")); 1119 ASSERT_FALSE(file_util::PathExists(file_name_to)); 1120 1121 EXPECT_TRUE(file_util::CopyDirectory(file_name_from, file_name_to, true)); 1122 1123 // Check the has been copied 1124 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1125 } 1126 1127 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExisting) { 1128 // Create a file 1129 FilePath file_name_from = 1130 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1131 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1132 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1133 1134 // The destination name 1135 FilePath file_name_to = temp_dir_.path().Append( 1136 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt")); 1137 CreateTextFile(file_name_to, L"Old file content"); 1138 ASSERT_TRUE(file_util::PathExists(file_name_to)); 1139 1140 EXPECT_TRUE(file_util::CopyDirectory(file_name_from, file_name_to, true)); 1141 1142 // Check the has been copied 1143 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1144 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to)); 1145 } 1146 1147 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExistingDirectory) { 1148 // Create a file 1149 FilePath file_name_from = 1150 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1151 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1152 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1153 1154 // The destination 1155 FilePath dir_name_to = 1156 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 1157 file_util::CreateDirectory(dir_name_to); 1158 ASSERT_TRUE(file_util::PathExists(dir_name_to)); 1159 FilePath file_name_to = 1160 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1161 1162 EXPECT_TRUE(file_util::CopyDirectory(file_name_from, dir_name_to, true)); 1163 1164 // Check the has been copied 1165 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1166 } 1167 1168 TEST_F(FileUtilTest, CopyFile) { 1169 // Create a directory 1170 FilePath dir_name_from = 1171 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1172 file_util::CreateDirectory(dir_name_from); 1173 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 1174 1175 // Create a file under the directory 1176 FilePath file_name_from = 1177 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1178 const std::wstring file_contents(L"Gooooooooooooooooooooogle"); 1179 CreateTextFile(file_name_from, file_contents); 1180 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1181 1182 // Copy the file. 1183 FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt")); 1184 ASSERT_TRUE(file_util::CopyFile(file_name_from, dest_file)); 1185 1186 // Copy the file to another location using '..' in the path. 1187 FilePath dest_file2(dir_name_from); 1188 dest_file2 = dest_file2.AppendASCII(".."); 1189 dest_file2 = dest_file2.AppendASCII("DestFile.txt"); 1190 ASSERT_TRUE(file_util::CopyFile(file_name_from, dest_file2)); 1191 1192 FilePath dest_file2_test(dir_name_from); 1193 dest_file2_test = dest_file2_test.DirName(); 1194 dest_file2_test = dest_file2_test.AppendASCII("DestFile.txt"); 1195 1196 // Check everything has been copied. 1197 EXPECT_TRUE(file_util::PathExists(file_name_from)); 1198 EXPECT_TRUE(file_util::PathExists(dest_file)); 1199 const std::wstring read_contents = ReadTextFile(dest_file); 1200 EXPECT_EQ(file_contents, read_contents); 1201 EXPECT_TRUE(file_util::PathExists(dest_file2_test)); 1202 EXPECT_TRUE(file_util::PathExists(dest_file2)); 1203 } 1204 1205 // TODO(erikkay): implement 1206 #if defined(OS_WIN) 1207 TEST_F(FileUtilTest, GetFileCreationLocalTime) { 1208 FilePath file_name = temp_dir_.path().Append(L"Test File.txt"); 1209 1210 SYSTEMTIME start_time; 1211 GetLocalTime(&start_time); 1212 Sleep(100); 1213 CreateTextFile(file_name, L"New file!"); 1214 Sleep(100); 1215 SYSTEMTIME end_time; 1216 GetLocalTime(&end_time); 1217 1218 SYSTEMTIME file_creation_time; 1219 file_util::GetFileCreationLocalTime(file_name.value(), &file_creation_time); 1220 1221 FILETIME start_filetime; 1222 SystemTimeToFileTime(&start_time, &start_filetime); 1223 FILETIME end_filetime; 1224 SystemTimeToFileTime(&end_time, &end_filetime); 1225 FILETIME file_creation_filetime; 1226 SystemTimeToFileTime(&file_creation_time, &file_creation_filetime); 1227 1228 EXPECT_EQ(-1, CompareFileTime(&start_filetime, &file_creation_filetime)) << 1229 "start time: " << FileTimeAsUint64(start_filetime) << ", " << 1230 "creation time: " << FileTimeAsUint64(file_creation_filetime); 1231 1232 EXPECT_EQ(-1, CompareFileTime(&file_creation_filetime, &end_filetime)) << 1233 "creation time: " << FileTimeAsUint64(file_creation_filetime) << ", " << 1234 "end time: " << FileTimeAsUint64(end_filetime); 1235 1236 ASSERT_TRUE(DeleteFile(file_name.value().c_str())); 1237 } 1238 #endif 1239 1240 // file_util winds up using autoreleased objects on the Mac, so this needs 1241 // to be a PlatformTest. 1242 typedef PlatformTest ReadOnlyFileUtilTest; 1243 1244 TEST_F(ReadOnlyFileUtilTest, ContentsEqual) { 1245 FilePath data_dir; 1246 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir)); 1247 data_dir = data_dir.Append(FILE_PATH_LITERAL("base")) 1248 .Append(FILE_PATH_LITERAL("data")) 1249 .Append(FILE_PATH_LITERAL("file_util_unittest")); 1250 ASSERT_TRUE(file_util::PathExists(data_dir)); 1251 1252 FilePath original_file = 1253 data_dir.Append(FILE_PATH_LITERAL("original.txt")); 1254 FilePath same_file = 1255 data_dir.Append(FILE_PATH_LITERAL("same.txt")); 1256 FilePath same_length_file = 1257 data_dir.Append(FILE_PATH_LITERAL("same_length.txt")); 1258 FilePath different_file = 1259 data_dir.Append(FILE_PATH_LITERAL("different.txt")); 1260 FilePath different_first_file = 1261 data_dir.Append(FILE_PATH_LITERAL("different_first.txt")); 1262 FilePath different_last_file = 1263 data_dir.Append(FILE_PATH_LITERAL("different_last.txt")); 1264 FilePath empty1_file = 1265 data_dir.Append(FILE_PATH_LITERAL("empty1.txt")); 1266 FilePath empty2_file = 1267 data_dir.Append(FILE_PATH_LITERAL("empty2.txt")); 1268 FilePath shortened_file = 1269 data_dir.Append(FILE_PATH_LITERAL("shortened.txt")); 1270 FilePath binary_file = 1271 data_dir.Append(FILE_PATH_LITERAL("binary_file.bin")); 1272 FilePath binary_file_same = 1273 data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin")); 1274 FilePath binary_file_diff = 1275 data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin")); 1276 1277 EXPECT_TRUE(file_util::ContentsEqual(original_file, original_file)); 1278 EXPECT_TRUE(file_util::ContentsEqual(original_file, same_file)); 1279 EXPECT_FALSE(file_util::ContentsEqual(original_file, same_length_file)); 1280 EXPECT_FALSE(file_util::ContentsEqual(original_file, different_file)); 1281 EXPECT_FALSE(file_util::ContentsEqual( 1282 FilePath(FILE_PATH_LITERAL("bogusname")), 1283 FilePath(FILE_PATH_LITERAL("bogusname")))); 1284 EXPECT_FALSE(file_util::ContentsEqual(original_file, different_first_file)); 1285 EXPECT_FALSE(file_util::ContentsEqual(original_file, different_last_file)); 1286 EXPECT_TRUE(file_util::ContentsEqual(empty1_file, empty2_file)); 1287 EXPECT_FALSE(file_util::ContentsEqual(original_file, shortened_file)); 1288 EXPECT_FALSE(file_util::ContentsEqual(shortened_file, original_file)); 1289 EXPECT_TRUE(file_util::ContentsEqual(binary_file, binary_file_same)); 1290 EXPECT_FALSE(file_util::ContentsEqual(binary_file, binary_file_diff)); 1291 } 1292 1293 TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) { 1294 FilePath data_dir; 1295 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir)); 1296 data_dir = data_dir.Append(FILE_PATH_LITERAL("base")) 1297 .Append(FILE_PATH_LITERAL("data")) 1298 .Append(FILE_PATH_LITERAL("file_util_unittest")); 1299 ASSERT_TRUE(file_util::PathExists(data_dir)); 1300 1301 FilePath original_file = 1302 data_dir.Append(FILE_PATH_LITERAL("original.txt")); 1303 FilePath same_file = 1304 data_dir.Append(FILE_PATH_LITERAL("same.txt")); 1305 FilePath crlf_file = 1306 data_dir.Append(FILE_PATH_LITERAL("crlf.txt")); 1307 FilePath shortened_file = 1308 data_dir.Append(FILE_PATH_LITERAL("shortened.txt")); 1309 FilePath different_file = 1310 data_dir.Append(FILE_PATH_LITERAL("different.txt")); 1311 FilePath different_first_file = 1312 data_dir.Append(FILE_PATH_LITERAL("different_first.txt")); 1313 FilePath different_last_file = 1314 data_dir.Append(FILE_PATH_LITERAL("different_last.txt")); 1315 FilePath first1_file = 1316 data_dir.Append(FILE_PATH_LITERAL("first1.txt")); 1317 FilePath first2_file = 1318 data_dir.Append(FILE_PATH_LITERAL("first2.txt")); 1319 FilePath empty1_file = 1320 data_dir.Append(FILE_PATH_LITERAL("empty1.txt")); 1321 FilePath empty2_file = 1322 data_dir.Append(FILE_PATH_LITERAL("empty2.txt")); 1323 FilePath blank_line_file = 1324 data_dir.Append(FILE_PATH_LITERAL("blank_line.txt")); 1325 FilePath blank_line_crlf_file = 1326 data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt")); 1327 1328 EXPECT_TRUE(file_util::TextContentsEqual(original_file, same_file)); 1329 EXPECT_TRUE(file_util::TextContentsEqual(original_file, crlf_file)); 1330 EXPECT_FALSE(file_util::TextContentsEqual(original_file, shortened_file)); 1331 EXPECT_FALSE(file_util::TextContentsEqual(original_file, different_file)); 1332 EXPECT_FALSE(file_util::TextContentsEqual(original_file, 1333 different_first_file)); 1334 EXPECT_FALSE(file_util::TextContentsEqual(original_file, 1335 different_last_file)); 1336 EXPECT_FALSE(file_util::TextContentsEqual(first1_file, first2_file)); 1337 EXPECT_TRUE(file_util::TextContentsEqual(empty1_file, empty2_file)); 1338 EXPECT_FALSE(file_util::TextContentsEqual(original_file, empty1_file)); 1339 EXPECT_TRUE(file_util::TextContentsEqual(blank_line_file, 1340 blank_line_crlf_file)); 1341 } 1342 1343 // We don't need equivalent functionality outside of Windows. 1344 #if defined(OS_WIN) 1345 TEST_F(FileUtilTest, ResolveShortcutTest) { 1346 FilePath target_file = temp_dir_.path().Append(L"Target.txt"); 1347 CreateTextFile(target_file, L"This is the target."); 1348 1349 FilePath link_file = temp_dir_.path().Append(L"Link.lnk"); 1350 1351 HRESULT result; 1352 IShellLink *shell = NULL; 1353 IPersistFile *persist = NULL; 1354 1355 CoInitialize(NULL); 1356 // Temporarily create a shortcut for test 1357 result = CoCreateInstance(CLSID_ShellLink, NULL, 1358 CLSCTX_INPROC_SERVER, IID_IShellLink, 1359 reinterpret_cast<LPVOID*>(&shell)); 1360 EXPECT_TRUE(SUCCEEDED(result)); 1361 result = shell->QueryInterface(IID_IPersistFile, 1362 reinterpret_cast<LPVOID*>(&persist)); 1363 EXPECT_TRUE(SUCCEEDED(result)); 1364 result = shell->SetPath(target_file.value().c_str()); 1365 EXPECT_TRUE(SUCCEEDED(result)); 1366 result = shell->SetDescription(L"ResolveShortcutTest"); 1367 EXPECT_TRUE(SUCCEEDED(result)); 1368 result = persist->Save(link_file.value().c_str(), TRUE); 1369 EXPECT_TRUE(SUCCEEDED(result)); 1370 if (persist) 1371 persist->Release(); 1372 if (shell) 1373 shell->Release(); 1374 1375 bool is_solved; 1376 is_solved = file_util::ResolveShortcut(&link_file); 1377 EXPECT_TRUE(is_solved); 1378 std::wstring contents; 1379 contents = ReadTextFile(link_file); 1380 EXPECT_EQ(L"This is the target.", contents); 1381 1382 // Cleaning 1383 DeleteFile(target_file.value().c_str()); 1384 DeleteFile(link_file.value().c_str()); 1385 CoUninitialize(); 1386 } 1387 1388 TEST_F(FileUtilTest, CreateShortcutTest) { 1389 const wchar_t file_contents[] = L"This is another target."; 1390 FilePath target_file = temp_dir_.path().Append(L"Target1.txt"); 1391 CreateTextFile(target_file, file_contents); 1392 1393 FilePath link_file = temp_dir_.path().Append(L"Link1.lnk"); 1394 1395 CoInitialize(NULL); 1396 EXPECT_TRUE(file_util::CreateShortcutLink(target_file.value().c_str(), 1397 link_file.value().c_str(), 1398 NULL, NULL, NULL, NULL, 0, NULL)); 1399 FilePath resolved_name = link_file; 1400 EXPECT_TRUE(file_util::ResolveShortcut(&resolved_name)); 1401 std::wstring read_contents = ReadTextFile(resolved_name); 1402 EXPECT_EQ(file_contents, read_contents); 1403 1404 DeleteFile(target_file.value().c_str()); 1405 DeleteFile(link_file.value().c_str()); 1406 CoUninitialize(); 1407 } 1408 1409 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) { 1410 // Create a directory 1411 FilePath dir_name_from = 1412 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir")); 1413 file_util::CreateDirectory(dir_name_from); 1414 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 1415 1416 // Create a file under the directory 1417 FilePath file_name_from = 1418 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1419 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1420 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1421 1422 // Move the directory by using CopyAndDeleteDirectory 1423 FilePath dir_name_to = temp_dir_.path().Append( 1424 FILE_PATH_LITERAL("CopyAndDelete_To_Subdir")); 1425 FilePath file_name_to = 1426 dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1427 1428 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 1429 1430 EXPECT_TRUE(file_util::CopyAndDeleteDirectory(dir_name_from, dir_name_to)); 1431 1432 // Check everything has been moved. 1433 EXPECT_FALSE(file_util::PathExists(dir_name_from)); 1434 EXPECT_FALSE(file_util::PathExists(file_name_from)); 1435 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 1436 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1437 } 1438 1439 TEST_F(FileUtilTest, GetTempDirTest) { 1440 static const TCHAR* kTmpKey = _T("TMP"); 1441 static const TCHAR* kTmpValues[] = { 1442 _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\") 1443 }; 1444 // Save the original $TMP. 1445 size_t original_tmp_size; 1446 TCHAR* original_tmp; 1447 ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey)); 1448 // original_tmp may be NULL. 1449 1450 for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) { 1451 FilePath path; 1452 ::_tputenv_s(kTmpKey, kTmpValues[i]); 1453 file_util::GetTempDir(&path); 1454 EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] << 1455 " result=" << path.value(); 1456 } 1457 1458 // Restore the original $TMP. 1459 if (original_tmp) { 1460 ::_tputenv_s(kTmpKey, original_tmp); 1461 free(original_tmp); 1462 } else { 1463 ::_tputenv_s(kTmpKey, _T("")); 1464 } 1465 } 1466 #endif // OS_WIN 1467 1468 TEST_F(FileUtilTest, CreateTemporaryFileTest) { 1469 FilePath temp_files[3]; 1470 for (int i = 0; i < 3; i++) { 1471 ASSERT_TRUE(file_util::CreateTemporaryFile(&(temp_files[i]))); 1472 EXPECT_TRUE(file_util::PathExists(temp_files[i])); 1473 EXPECT_FALSE(file_util::DirectoryExists(temp_files[i])); 1474 } 1475 for (int i = 0; i < 3; i++) 1476 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]); 1477 for (int i = 0; i < 3; i++) 1478 EXPECT_TRUE(file_util::Delete(temp_files[i], false)); 1479 } 1480 1481 TEST_F(FileUtilTest, CreateAndOpenTemporaryFileTest) { 1482 FilePath names[3]; 1483 FILE *fps[3]; 1484 int i; 1485 1486 // Create; make sure they are open and exist. 1487 for (i = 0; i < 3; ++i) { 1488 fps[i] = file_util::CreateAndOpenTemporaryFile(&(names[i])); 1489 ASSERT_TRUE(fps[i]); 1490 EXPECT_TRUE(file_util::PathExists(names[i])); 1491 } 1492 1493 // Make sure all names are unique. 1494 for (i = 0; i < 3; ++i) { 1495 EXPECT_FALSE(names[i] == names[(i+1)%3]); 1496 } 1497 1498 // Close and delete. 1499 for (i = 0; i < 3; ++i) { 1500 EXPECT_TRUE(file_util::CloseFile(fps[i])); 1501 EXPECT_TRUE(file_util::Delete(names[i], false)); 1502 } 1503 } 1504 1505 TEST_F(FileUtilTest, CreateNewTempDirectoryTest) { 1506 FilePath temp_dir; 1507 ASSERT_TRUE(file_util::CreateNewTempDirectory(FilePath::StringType(), 1508 &temp_dir)); 1509 EXPECT_TRUE(file_util::PathExists(temp_dir)); 1510 EXPECT_TRUE(file_util::Delete(temp_dir, false)); 1511 } 1512 1513 TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) { 1514 FilePath new_dir; 1515 ASSERT_TRUE(file_util::CreateTemporaryDirInDir( 1516 temp_dir_.path(), 1517 FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"), 1518 &new_dir)); 1519 EXPECT_TRUE(file_util::PathExists(new_dir)); 1520 EXPECT_TRUE(temp_dir_.path().IsParent(new_dir)); 1521 EXPECT_TRUE(file_util::Delete(new_dir, false)); 1522 } 1523 1524 TEST_F(FileUtilTest, GetShmemTempDirTest) { 1525 FilePath dir; 1526 EXPECT_TRUE(file_util::GetShmemTempDir(&dir)); 1527 EXPECT_TRUE(file_util::DirectoryExists(dir)); 1528 } 1529 1530 TEST_F(FileUtilTest, CreateDirectoryTest) { 1531 FilePath test_root = 1532 temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test")); 1533 #if defined(OS_WIN) 1534 FilePath test_path = 1535 test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\")); 1536 #elif defined(OS_POSIX) 1537 FilePath test_path = 1538 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/")); 1539 #endif 1540 1541 EXPECT_FALSE(file_util::PathExists(test_path)); 1542 EXPECT_TRUE(file_util::CreateDirectory(test_path)); 1543 EXPECT_TRUE(file_util::PathExists(test_path)); 1544 // CreateDirectory returns true if the DirectoryExists returns true. 1545 EXPECT_TRUE(file_util::CreateDirectory(test_path)); 1546 1547 // Doesn't work to create it on top of a non-dir 1548 test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt")); 1549 EXPECT_FALSE(file_util::PathExists(test_path)); 1550 CreateTextFile(test_path, L"test file"); 1551 EXPECT_TRUE(file_util::PathExists(test_path)); 1552 EXPECT_FALSE(file_util::CreateDirectory(test_path)); 1553 1554 EXPECT_TRUE(file_util::Delete(test_root, true)); 1555 EXPECT_FALSE(file_util::PathExists(test_root)); 1556 EXPECT_FALSE(file_util::PathExists(test_path)); 1557 1558 // Verify assumptions made by the Windows implementation: 1559 // 1. The current directory always exists. 1560 // 2. The root directory always exists. 1561 ASSERT_TRUE(file_util::DirectoryExists( 1562 FilePath(FilePath::kCurrentDirectory))); 1563 FilePath top_level = test_root; 1564 while (top_level != top_level.DirName()) { 1565 top_level = top_level.DirName(); 1566 } 1567 ASSERT_TRUE(file_util::DirectoryExists(top_level)); 1568 1569 // Given these assumptions hold, it should be safe to 1570 // test that "creating" these directories succeeds. 1571 EXPECT_TRUE(file_util::CreateDirectory( 1572 FilePath(FilePath::kCurrentDirectory))); 1573 EXPECT_TRUE(file_util::CreateDirectory(top_level)); 1574 1575 #if defined(OS_WIN) 1576 FilePath invalid_drive(FILE_PATH_LITERAL("o:\\")); 1577 FilePath invalid_path = 1578 invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir")); 1579 if (!file_util::PathExists(invalid_drive)) { 1580 EXPECT_FALSE(file_util::CreateDirectory(invalid_path)); 1581 } 1582 #endif 1583 } 1584 1585 TEST_F(FileUtilTest, DetectDirectoryTest) { 1586 // Check a directory 1587 FilePath test_root = 1588 temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test")); 1589 EXPECT_FALSE(file_util::PathExists(test_root)); 1590 EXPECT_TRUE(file_util::CreateDirectory(test_root)); 1591 EXPECT_TRUE(file_util::PathExists(test_root)); 1592 EXPECT_TRUE(file_util::DirectoryExists(test_root)); 1593 1594 // Check a file 1595 FilePath test_path = 1596 test_root.Append(FILE_PATH_LITERAL("foobar.txt")); 1597 EXPECT_FALSE(file_util::PathExists(test_path)); 1598 CreateTextFile(test_path, L"test file"); 1599 EXPECT_TRUE(file_util::PathExists(test_path)); 1600 EXPECT_FALSE(file_util::DirectoryExists(test_path)); 1601 EXPECT_TRUE(file_util::Delete(test_path, false)); 1602 1603 EXPECT_TRUE(file_util::Delete(test_root, true)); 1604 } 1605 1606 TEST_F(FileUtilTest, FileEnumeratorTest) { 1607 // Test an empty directory. 1608 file_util::FileEnumerator f0(temp_dir_.path(), true, FILES_AND_DIRECTORIES); 1609 EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL("")); 1610 EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL("")); 1611 1612 // Test an empty directory, non-recursively, including "..". 1613 file_util::FileEnumerator f0_dotdot(temp_dir_.path(), false, 1614 static_cast<file_util::FileEnumerator::FILE_TYPE>( 1615 FILES_AND_DIRECTORIES | file_util::FileEnumerator::INCLUDE_DOT_DOT)); 1616 EXPECT_EQ(temp_dir_.path().Append(FILE_PATH_LITERAL("..")).value(), 1617 f0_dotdot.Next().value()); 1618 EXPECT_EQ(FILE_PATH_LITERAL(""), 1619 f0_dotdot.Next().value()); 1620 1621 // create the directories 1622 FilePath dir1 = temp_dir_.path().Append(FILE_PATH_LITERAL("dir1")); 1623 EXPECT_TRUE(file_util::CreateDirectory(dir1)); 1624 FilePath dir2 = temp_dir_.path().Append(FILE_PATH_LITERAL("dir2")); 1625 EXPECT_TRUE(file_util::CreateDirectory(dir2)); 1626 FilePath dir2inner = dir2.Append(FILE_PATH_LITERAL("inner")); 1627 EXPECT_TRUE(file_util::CreateDirectory(dir2inner)); 1628 1629 // create the files 1630 FilePath dir2file = dir2.Append(FILE_PATH_LITERAL("dir2file.txt")); 1631 CreateTextFile(dir2file, L""); 1632 FilePath dir2innerfile = dir2inner.Append(FILE_PATH_LITERAL("innerfile.txt")); 1633 CreateTextFile(dir2innerfile, L""); 1634 FilePath file1 = temp_dir_.path().Append(FILE_PATH_LITERAL("file1.txt")); 1635 CreateTextFile(file1, L""); 1636 FilePath file2_rel = 1637 dir2.Append(FilePath::kParentDirectory) 1638 .Append(FILE_PATH_LITERAL("file2.txt")); 1639 CreateTextFile(file2_rel, L""); 1640 FilePath file2_abs = temp_dir_.path().Append(FILE_PATH_LITERAL("file2.txt")); 1641 1642 // Only enumerate files. 1643 file_util::FileEnumerator f1(temp_dir_.path(), true, 1644 file_util::FileEnumerator::FILES); 1645 FindResultCollector c1(f1); 1646 EXPECT_TRUE(c1.HasFile(file1)); 1647 EXPECT_TRUE(c1.HasFile(file2_abs)); 1648 EXPECT_TRUE(c1.HasFile(dir2file)); 1649 EXPECT_TRUE(c1.HasFile(dir2innerfile)); 1650 EXPECT_EQ(c1.size(), 4); 1651 1652 // Only enumerate directories. 1653 file_util::FileEnumerator f2(temp_dir_.path(), true, 1654 file_util::FileEnumerator::DIRECTORIES); 1655 FindResultCollector c2(f2); 1656 EXPECT_TRUE(c2.HasFile(dir1)); 1657 EXPECT_TRUE(c2.HasFile(dir2)); 1658 EXPECT_TRUE(c2.HasFile(dir2inner)); 1659 EXPECT_EQ(c2.size(), 3); 1660 1661 // Only enumerate directories non-recursively. 1662 file_util::FileEnumerator f2_non_recursive( 1663 temp_dir_.path(), false, file_util::FileEnumerator::DIRECTORIES); 1664 FindResultCollector c2_non_recursive(f2_non_recursive); 1665 EXPECT_TRUE(c2_non_recursive.HasFile(dir1)); 1666 EXPECT_TRUE(c2_non_recursive.HasFile(dir2)); 1667 EXPECT_EQ(c2_non_recursive.size(), 2); 1668 1669 // Only enumerate directories, non-recursively, including "..". 1670 file_util::FileEnumerator f2_dotdot( 1671 temp_dir_.path(), false, 1672 static_cast<file_util::FileEnumerator::FILE_TYPE>( 1673 file_util::FileEnumerator::DIRECTORIES | 1674 file_util::FileEnumerator::INCLUDE_DOT_DOT)); 1675 FindResultCollector c2_dotdot(f2_dotdot); 1676 EXPECT_TRUE(c2_dotdot.HasFile(dir1)); 1677 EXPECT_TRUE(c2_dotdot.HasFile(dir2)); 1678 EXPECT_TRUE(c2_dotdot.HasFile( 1679 temp_dir_.path().Append(FILE_PATH_LITERAL("..")))); 1680 EXPECT_EQ(c2_dotdot.size(), 3); 1681 1682 // Enumerate files and directories. 1683 file_util::FileEnumerator f3(temp_dir_.path(), true, FILES_AND_DIRECTORIES); 1684 FindResultCollector c3(f3); 1685 EXPECT_TRUE(c3.HasFile(dir1)); 1686 EXPECT_TRUE(c3.HasFile(dir2)); 1687 EXPECT_TRUE(c3.HasFile(file1)); 1688 EXPECT_TRUE(c3.HasFile(file2_abs)); 1689 EXPECT_TRUE(c3.HasFile(dir2file)); 1690 EXPECT_TRUE(c3.HasFile(dir2inner)); 1691 EXPECT_TRUE(c3.HasFile(dir2innerfile)); 1692 EXPECT_EQ(c3.size(), 7); 1693 1694 // Non-recursive operation. 1695 file_util::FileEnumerator f4(temp_dir_.path(), false, FILES_AND_DIRECTORIES); 1696 FindResultCollector c4(f4); 1697 EXPECT_TRUE(c4.HasFile(dir2)); 1698 EXPECT_TRUE(c4.HasFile(dir2)); 1699 EXPECT_TRUE(c4.HasFile(file1)); 1700 EXPECT_TRUE(c4.HasFile(file2_abs)); 1701 EXPECT_EQ(c4.size(), 4); 1702 1703 // Enumerate with a pattern. 1704 file_util::FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, 1705 FILE_PATH_LITERAL("dir*")); 1706 FindResultCollector c5(f5); 1707 EXPECT_TRUE(c5.HasFile(dir1)); 1708 EXPECT_TRUE(c5.HasFile(dir2)); 1709 EXPECT_TRUE(c5.HasFile(dir2file)); 1710 EXPECT_TRUE(c5.HasFile(dir2inner)); 1711 EXPECT_TRUE(c5.HasFile(dir2innerfile)); 1712 EXPECT_EQ(c5.size(), 5); 1713 1714 // Make sure the destructor closes the find handle while in the middle of a 1715 // query to allow TearDown to delete the directory. 1716 file_util::FileEnumerator f6(temp_dir_.path(), true, FILES_AND_DIRECTORIES); 1717 EXPECT_FALSE(f6.Next().value().empty()); // Should have found something 1718 // (we don't care what). 1719 } 1720 1721 TEST_F(FileUtilTest, Contains) { 1722 FilePath data_dir = 1723 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); 1724 1725 // Create a fresh, empty copy of this directory. 1726 if (file_util::PathExists(data_dir)) { 1727 ASSERT_TRUE(file_util::Delete(data_dir, true)); 1728 } 1729 ASSERT_TRUE(file_util::CreateDirectory(data_dir)); 1730 1731 FilePath foo(data_dir.Append(FILE_PATH_LITERAL("foo"))); 1732 FilePath bar(foo.Append(FILE_PATH_LITERAL("bar.txt"))); 1733 FilePath baz(data_dir.Append(FILE_PATH_LITERAL("baz.txt"))); 1734 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt"))); 1735 1736 // Annoyingly, the directories must actually exist in order for realpath(), 1737 // which Contains() relies on in posix, to work. 1738 ASSERT_TRUE(file_util::CreateDirectory(foo)); 1739 std::string data("hello"); 1740 ASSERT_TRUE(file_util::WriteFile(bar, data.c_str(), data.length())); 1741 ASSERT_TRUE(file_util::WriteFile(baz, data.c_str(), data.length())); 1742 ASSERT_TRUE(file_util::WriteFile(foobar, data.c_str(), data.length())); 1743 1744 EXPECT_TRUE(file_util::ContainsPath(foo, bar)); 1745 EXPECT_FALSE(file_util::ContainsPath(foo, baz)); 1746 EXPECT_FALSE(file_util::ContainsPath(foo, foobar)); 1747 EXPECT_FALSE(file_util::ContainsPath(foo, foo)); 1748 1749 // Platform-specific concerns. 1750 FilePath foo_caps(data_dir.Append(FILE_PATH_LITERAL("FOO"))); 1751 #if defined(OS_WIN) 1752 EXPECT_TRUE(file_util::ContainsPath(foo, 1753 foo_caps.Append(FILE_PATH_LITERAL("bar.txt")))); 1754 EXPECT_TRUE(file_util::ContainsPath(foo, 1755 FilePath(foo.value() + FILE_PATH_LITERAL("/bar.txt")))); 1756 #elif defined(OS_MACOSX) 1757 // We can't really do this test on OS X since the case-sensitivity of the 1758 // filesystem is configurable. 1759 #elif defined(OS_POSIX) 1760 EXPECT_FALSE(file_util::ContainsPath(foo, 1761 foo_caps.Append(FILE_PATH_LITERAL("bar.txt")))); 1762 #endif 1763 } 1764 1765 TEST_F(FileUtilTest, TouchFile) { 1766 FilePath data_dir = 1767 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); 1768 1769 // Create a fresh, empty copy of this directory. 1770 if (file_util::PathExists(data_dir)) { 1771 ASSERT_TRUE(file_util::Delete(data_dir, true)); 1772 } 1773 ASSERT_TRUE(file_util::CreateDirectory(data_dir)); 1774 1775 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt"))); 1776 std::string data("hello"); 1777 ASSERT_TRUE(file_util::WriteFile(foobar, data.c_str(), data.length())); 1778 1779 base::Time access_time; 1780 // This timestamp is divisible by one day (in local timezone), 1781 // to make it work on FAT too. 1782 ASSERT_TRUE(base::Time::FromString(L"Wed, 16 Nov 1994, 00:00:00", 1783 &access_time)); 1784 1785 base::Time modification_time; 1786 // Note that this timestamp is divisible by two (seconds) - FAT stores 1787 // modification times with 2s resolution. 1788 ASSERT_TRUE(base::Time::FromString(L"Tue, 15 Nov 1994, 12:45:26 GMT", 1789 &modification_time)); 1790 1791 ASSERT_TRUE(file_util::TouchFile(foobar, access_time, modification_time)); 1792 base::PlatformFileInfo file_info; 1793 ASSERT_TRUE(file_util::GetFileInfo(foobar, &file_info)); 1794 EXPECT_EQ(file_info.last_accessed.ToInternalValue(), 1795 access_time.ToInternalValue()); 1796 EXPECT_EQ(file_info.last_modified.ToInternalValue(), 1797 modification_time.ToInternalValue()); 1798 } 1799 1800 TEST_F(FileUtilTest, IsDirectoryEmpty) { 1801 FilePath empty_dir = temp_dir_.path().Append(FILE_PATH_LITERAL("EmptyDir")); 1802 1803 ASSERT_FALSE(file_util::PathExists(empty_dir)); 1804 1805 ASSERT_TRUE(file_util::CreateDirectory(empty_dir)); 1806 1807 EXPECT_TRUE(file_util::IsDirectoryEmpty(empty_dir)); 1808 1809 FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt"))); 1810 std::string bar("baz"); 1811 ASSERT_TRUE(file_util::WriteFile(foo, bar.c_str(), bar.length())); 1812 1813 EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir)); 1814 } 1815 1816 } // namespace 1817