1 // Copyright (c) 2009 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 <shellapi.h> 10 #include <shlobj.h> 11 #include <tchar.h> 12 #endif 13 14 #include <fstream> 15 #include <iostream> 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/logging.h" 22 #include "base/path_service.h" 23 #include "base/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 // This macro helps avoid wrapped lines in the test structs. 30 #define FPL(x) FILE_PATH_LITERAL(x) 31 32 namespace { 33 34 const file_util::FileEnumerator::FILE_TYPE FILES_AND_DIRECTORIES = 35 static_cast<file_util::FileEnumerator::FILE_TYPE>( 36 file_util::FileEnumerator::FILES | 37 file_util::FileEnumerator::DIRECTORIES); 38 39 // file_util winds up using autoreleased objects on the Mac, so this needs 40 // to be a PlatformTest 41 class FileUtilTest : public PlatformTest { 42 protected: 43 virtual void SetUp() { 44 PlatformTest::SetUp(); 45 // Name a subdirectory of the temp directory. 46 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &test_dir_)); 47 test_dir_ = test_dir_.Append(FILE_PATH_LITERAL("FileUtilTest")); 48 49 // Create a fresh, empty copy of this directory. 50 file_util::Delete(test_dir_, true); 51 file_util::CreateDirectory(test_dir_); 52 } 53 virtual void TearDown() { 54 PlatformTest::TearDown(); 55 // Clean up test directory 56 ASSERT_TRUE(file_util::Delete(test_dir_, true)); 57 ASSERT_FALSE(file_util::PathExists(test_dir_)); 58 } 59 60 // the path to temporary directory used to contain the test operations 61 FilePath test_dir_; 62 }; 63 64 // Collects all the results from the given file enumerator, and provides an 65 // interface to query whether a given file is present. 66 class FindResultCollector { 67 public: 68 explicit FindResultCollector(file_util::FileEnumerator& enumerator) { 69 FilePath cur_file; 70 while (!(cur_file = enumerator.Next()).value().empty()) { 71 FilePath::StringType path = cur_file.value(); 72 // The file should not be returned twice. 73 EXPECT_TRUE(files_.end() == files_.find(path)) 74 << "Same file returned twice"; 75 76 // Save for later. 77 files_.insert(path); 78 } 79 } 80 81 // Returns true if the enumerator found the file. 82 bool HasFile(const FilePath& file) const { 83 return files_.find(file.value()) != files_.end(); 84 } 85 86 int size() { 87 return static_cast<int>(files_.size()); 88 } 89 90 private: 91 std::set<FilePath::StringType> files_; 92 }; 93 94 // Simple function to dump some text into a new file. 95 void CreateTextFile(const FilePath& filename, 96 const std::wstring& contents) { 97 std::ofstream file; 98 file.open(WideToUTF8(filename.ToWStringHack()).c_str()); 99 ASSERT_TRUE(file.is_open()); 100 file << contents; 101 file.close(); 102 } 103 104 // Simple function to take out some text from a file. 105 std::wstring ReadTextFile(const FilePath& filename) { 106 wchar_t contents[64]; 107 std::wifstream file; 108 file.open(WideToUTF8(filename.ToWStringHack()).c_str()); 109 EXPECT_TRUE(file.is_open()); 110 file.getline(contents, 64); 111 file.close(); 112 return std::wstring(contents); 113 } 114 115 #if defined(OS_WIN) 116 uint64 FileTimeAsUint64(const FILETIME& ft) { 117 ULARGE_INTEGER u; 118 u.LowPart = ft.dwLowDateTime; 119 u.HighPart = ft.dwHighDateTime; 120 return u.QuadPart; 121 } 122 #endif 123 124 const struct append_case { 125 const wchar_t* path; 126 const wchar_t* ending; 127 const wchar_t* result; 128 } append_cases[] = { 129 #if defined(OS_WIN) 130 {L"c:\\colon\\backslash", L"path", L"c:\\colon\\backslash\\path"}, 131 {L"c:\\colon\\backslash\\", L"path", L"c:\\colon\\backslash\\path"}, 132 {L"c:\\colon\\backslash\\\\", L"path", L"c:\\colon\\backslash\\\\path"}, 133 {L"c:\\colon\\backslash\\", L"", L"c:\\colon\\backslash\\"}, 134 {L"c:\\colon\\backslash", L"", L"c:\\colon\\backslash\\"}, 135 {L"", L"path", L"\\path"}, 136 {L"", L"", L"\\"}, 137 #elif defined(OS_POSIX) 138 {L"/foo/bar", L"path", L"/foo/bar/path"}, 139 {L"/foo/bar/", L"path", L"/foo/bar/path"}, 140 {L"/foo/bar//", L"path", L"/foo/bar//path"}, 141 {L"/foo/bar/", L"", L"/foo/bar/"}, 142 {L"/foo/bar", L"", L"/foo/bar/"}, 143 {L"", L"path", L"/path"}, 144 {L"", L"", L"/"}, 145 #endif 146 }; 147 148 TEST_F(FileUtilTest, AppendToPath) { 149 for (unsigned int i = 0; i < arraysize(append_cases); ++i) { 150 const append_case& value = append_cases[i]; 151 std::wstring result = value.path; 152 file_util::AppendToPath(&result, value.ending); 153 EXPECT_EQ(value.result, result); 154 } 155 156 #ifdef NDEBUG 157 file_util::AppendToPath(NULL, L"path"); // asserts in debug mode 158 #endif 159 } 160 161 static const struct InsertBeforeExtensionCase { 162 const FilePath::CharType* path; 163 const FilePath::CharType* suffix; 164 const FilePath::CharType* result; 165 } kInsertBeforeExtension[] = { 166 {FPL(""), FPL(""), FPL("")}, 167 {FPL(""), FPL("txt"), FPL("txt")}, 168 {FPL("."), FPL("txt"), FPL("txt.")}, 169 {FPL("."), FPL(""), FPL(".")}, 170 {FPL("foo.dll"), FPL("txt"), FPL("footxt.dll")}, 171 {FPL("foo.dll"), FPL(".txt"), FPL("foo.txt.dll")}, 172 {FPL("foo"), FPL("txt"), FPL("footxt")}, 173 {FPL("foo"), FPL(".txt"), FPL("foo.txt")}, 174 {FPL("foo.baz.dll"), FPL("txt"), FPL("foo.baztxt.dll")}, 175 {FPL("foo.baz.dll"), FPL(".txt"), FPL("foo.baz.txt.dll")}, 176 {FPL("foo.dll"), FPL(""), FPL("foo.dll")}, 177 {FPL("foo.dll"), FPL("."), FPL("foo..dll")}, 178 {FPL("foo"), FPL(""), FPL("foo")}, 179 {FPL("foo"), FPL("."), FPL("foo.")}, 180 {FPL("foo.baz.dll"), FPL(""), FPL("foo.baz.dll")}, 181 {FPL("foo.baz.dll"), FPL("."), FPL("foo.baz..dll")}, 182 #if defined(OS_WIN) 183 {FPL("\\"), FPL(""), FPL("\\")}, 184 {FPL("\\"), FPL("txt"), FPL("\\txt")}, 185 {FPL("\\."), FPL("txt"), FPL("\\txt.")}, 186 {FPL("\\."), FPL(""), FPL("\\.")}, 187 {FPL("C:\\bar\\foo.dll"), FPL("txt"), FPL("C:\\bar\\footxt.dll")}, 188 {FPL("C:\\bar.baz\\foodll"), FPL("txt"), FPL("C:\\bar.baz\\foodlltxt")}, 189 {FPL("C:\\bar.baz\\foo.dll"), FPL("txt"), FPL("C:\\bar.baz\\footxt.dll")}, 190 {FPL("C:\\bar.baz\\foo.dll.exe"), FPL("txt"), 191 FPL("C:\\bar.baz\\foo.dlltxt.exe")}, 192 {FPL("C:\\bar.baz\\foo"), FPL(""), FPL("C:\\bar.baz\\foo")}, 193 {FPL("C:\\bar.baz\\foo.exe"), FPL(""), FPL("C:\\bar.baz\\foo.exe")}, 194 {FPL("C:\\bar.baz\\foo.dll.exe"), FPL(""), FPL("C:\\bar.baz\\foo.dll.exe")}, 195 {FPL("C:\\bar\\baz\\foo.exe"), FPL(" (1)"), FPL("C:\\bar\\baz\\foo (1).exe")}, 196 #elif defined(OS_POSIX) 197 {FPL("/"), FPL(""), FPL("/")}, 198 {FPL("/"), FPL("txt"), FPL("/txt")}, 199 {FPL("/."), FPL("txt"), FPL("/txt.")}, 200 {FPL("/."), FPL(""), FPL("/.")}, 201 {FPL("/bar/foo.dll"), FPL("txt"), FPL("/bar/footxt.dll")}, 202 {FPL("/bar.baz/foodll"), FPL("txt"), FPL("/bar.baz/foodlltxt")}, 203 {FPL("/bar.baz/foo.dll"), FPL("txt"), FPL("/bar.baz/footxt.dll")}, 204 {FPL("/bar.baz/foo.dll.exe"), FPL("txt"), FPL("/bar.baz/foo.dlltxt.exe")}, 205 {FPL("/bar.baz/foo"), FPL(""), FPL("/bar.baz/foo")}, 206 {FPL("/bar.baz/foo.exe"), FPL(""), FPL("/bar.baz/foo.exe")}, 207 {FPL("/bar.baz/foo.dll.exe"), FPL(""), FPL("/bar.baz/foo.dll.exe")}, 208 {FPL("/bar/baz/foo.exe"), FPL(" (1)"), FPL("/bar/baz/foo (1).exe")}, 209 #endif 210 }; 211 212 TEST_F(FileUtilTest, InsertBeforeExtensionTest) { 213 for (unsigned int i = 0; i < arraysize(kInsertBeforeExtension); ++i) { 214 FilePath path(kInsertBeforeExtension[i].path); 215 file_util::InsertBeforeExtension(&path, kInsertBeforeExtension[i].suffix); 216 EXPECT_EQ(kInsertBeforeExtension[i].result, path.value()); 217 } 218 } 219 220 static const struct filename_case { 221 const wchar_t* path; 222 const wchar_t* filename; 223 } filename_cases[] = { 224 #if defined(OS_WIN) 225 {L"c:\\colon\\backslash", L"backslash"}, 226 {L"c:\\colon\\backslash\\", L""}, 227 {L"\\\\filename.exe", L"filename.exe"}, 228 {L"filename.exe", L"filename.exe"}, 229 {L"", L""}, 230 {L"\\\\\\", L""}, 231 {L"c:/colon/backslash", L"backslash"}, 232 {L"c:/colon/backslash/", L""}, 233 {L"//////", L""}, 234 {L"///filename.exe", L"filename.exe"}, 235 #elif defined(OS_POSIX) 236 {L"/foo/bar", L"bar"}, 237 {L"/foo/bar/", L""}, 238 {L"/filename.exe", L"filename.exe"}, 239 {L"filename.exe", L"filename.exe"}, 240 {L"", L""}, 241 {L"/", L""}, 242 #endif 243 }; 244 245 TEST_F(FileUtilTest, GetFilenameFromPath) { 246 for (unsigned int i = 0; i < arraysize(filename_cases); ++i) { 247 const filename_case& value = filename_cases[i]; 248 std::wstring result = file_util::GetFilenameFromPath(value.path); 249 EXPECT_EQ(value.filename, result); 250 } 251 } 252 253 // Test finding the file type from a path name 254 static const struct extension_case { 255 const wchar_t* path; 256 const wchar_t* extension; 257 } extension_cases[] = { 258 #if defined(OS_WIN) 259 {L"C:\\colon\\backslash\\filename.extension", L"extension"}, 260 {L"C:\\colon\\backslash\\filename.", L""}, 261 {L"C:\\colon\\backslash\\filename", L""}, 262 {L"C:\\colon\\backslash\\", L""}, 263 {L"C:\\colon\\backslash.\\", L""}, 264 {L"C:\\colon\\backslash\filename.extension.extension2", L"extension2"}, 265 #elif defined(OS_POSIX) 266 {L"/foo/bar/filename.extension", L"extension"}, 267 {L"/foo/bar/filename.", L""}, 268 {L"/foo/bar/filename", L""}, 269 {L"/foo/bar/", L""}, 270 {L"/foo/bar./", L""}, 271 {L"/foo/bar/filename.extension.extension2", L"extension2"}, 272 {L".", L""}, 273 {L"..", L""}, 274 {L"./foo", L""}, 275 {L"./foo.extension", L"extension"}, 276 {L"/foo.extension1/bar.extension2", L"extension2"}, 277 #endif 278 }; 279 280 TEST_F(FileUtilTest, GetFileExtensionFromPath) { 281 for (unsigned int i = 0; i < arraysize(extension_cases); ++i) { 282 const extension_case& ext = extension_cases[i]; 283 const std::wstring fext = file_util::GetFileExtensionFromPath(ext.path); 284 EXPECT_EQ(ext.extension, fext); 285 } 286 } 287 288 // Test finding the directory component of a path 289 static const struct dir_case { 290 const wchar_t* full_path; 291 const wchar_t* directory; 292 } dir_cases[] = { 293 #if defined(OS_WIN) 294 {L"C:\\WINDOWS\\system32\\gdi32.dll", L"C:\\WINDOWS\\system32"}, 295 {L"C:\\WINDOWS\\system32\\not_exist_thx_1138", L"C:\\WINDOWS\\system32"}, 296 {L"C:\\WINDOWS\\system32\\", L"C:\\WINDOWS\\system32"}, 297 {L"C:\\WINDOWS\\system32\\\\", L"C:\\WINDOWS\\system32"}, 298 {L"C:\\WINDOWS\\system32", L"C:\\WINDOWS"}, 299 {L"C:\\WINDOWS\\system32.\\", L"C:\\WINDOWS\\system32."}, 300 {L"C:\\", L"C:\\"}, 301 #elif defined(OS_POSIX) 302 {L"/foo/bar/gdi32.dll", L"/foo/bar"}, 303 {L"/foo/bar/not_exist_thx_1138", L"/foo/bar"}, 304 {L"/foo/bar/", L"/foo/bar"}, 305 {L"/foo/bar//", L"/foo/bar"}, 306 {L"/foo/bar", L"/foo"}, 307 {L"/foo/bar./", L"/foo/bar."}, 308 {L"/", L"/"}, 309 {L".", L"."}, 310 {L"..", L"."}, // yes, ".." technically lives in "." 311 #endif 312 }; 313 314 TEST_F(FileUtilTest, GetDirectoryFromPath) { 315 for (unsigned int i = 0; i < arraysize(dir_cases); ++i) { 316 const dir_case& dir = dir_cases[i]; 317 const std::wstring parent = 318 file_util::GetDirectoryFromPath(dir.full_path); 319 EXPECT_EQ(dir.directory, parent); 320 } 321 } 322 323 TEST_F(FileUtilTest, CountFilesCreatedAfter) { 324 // Create old file (that we don't want to count) 325 FilePath old_file_name = test_dir_.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 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 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(test_dir_, now)); 340 341 // Create a new file (that we do want to count) 342 FilePath new_file_name = test_dir_.Append(FILE_PATH_LITERAL("New File.txt")); 343 CreateTextFile(new_file_name, L"Waaaaaaaaaaaaaah."); 344 345 // We should see only the new file. 346 EXPECT_EQ(1, file_util::CountFilesCreatedAfter(test_dir_, now)); 347 348 // Delete new file, we should see no files after cutoff now 349 EXPECT_TRUE(file_util::Delete(new_file_name, false)); 350 EXPECT_EQ(0, file_util::CountFilesCreatedAfter(test_dir_, now)); 351 } 352 353 // Tests that the Delete function works as expected, especially 354 // the recursion flag. Also coincidentally tests PathExists. 355 TEST_F(FileUtilTest, Delete) { 356 // Create a file 357 FilePath file_name = test_dir_.Append(FILE_PATH_LITERAL("Test File.txt")); 358 CreateTextFile(file_name, L"I'm cannon fodder."); 359 360 ASSERT_TRUE(file_util::PathExists(file_name)); 361 362 FilePath subdir_path = test_dir_.Append(FILE_PATH_LITERAL("Subdirectory")); 363 file_util::CreateDirectory(subdir_path); 364 365 ASSERT_TRUE(file_util::PathExists(subdir_path)); 366 367 FilePath directory_contents = test_dir_; 368 #if defined(OS_WIN) 369 // TODO(erikkay): see if anyone's actually using this feature of the API 370 directory_contents = directory_contents.Append(FILE_PATH_LITERAL("*")); 371 // Delete non-recursively and check that only the file is deleted 372 ASSERT_TRUE(file_util::Delete(directory_contents, false)); 373 EXPECT_FALSE(file_util::PathExists(file_name)); 374 EXPECT_TRUE(file_util::PathExists(subdir_path)); 375 #endif 376 377 // Delete recursively and make sure all contents are deleted 378 ASSERT_TRUE(file_util::Delete(directory_contents, true)); 379 EXPECT_FALSE(file_util::PathExists(file_name)); 380 EXPECT_FALSE(file_util::PathExists(subdir_path)); 381 } 382 383 TEST_F(FileUtilTest, MoveFileNew) { 384 // Create a file 385 FilePath file_name_from = 386 test_dir_.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 387 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 388 ASSERT_TRUE(file_util::PathExists(file_name_from)); 389 390 // The destination 391 FilePath file_name_to = 392 test_dir_.Append(FILE_PATH_LITERAL("Move_Test_File_Destination.txt")); 393 ASSERT_FALSE(file_util::PathExists(file_name_to)); 394 395 EXPECT_TRUE(file_util::Move(file_name_from, file_name_to)); 396 397 // Check everything has been moved. 398 EXPECT_FALSE(file_util::PathExists(file_name_from)); 399 EXPECT_TRUE(file_util::PathExists(file_name_to)); 400 } 401 402 TEST_F(FileUtilTest, MoveFileExists) { 403 // Create a file 404 FilePath file_name_from = 405 test_dir_.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 406 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 407 ASSERT_TRUE(file_util::PathExists(file_name_from)); 408 409 // The destination name 410 FilePath file_name_to = 411 test_dir_.Append(FILE_PATH_LITERAL("Move_Test_File_Destination.txt")); 412 CreateTextFile(file_name_to, L"Old file content"); 413 ASSERT_TRUE(file_util::PathExists(file_name_to)); 414 415 EXPECT_TRUE(file_util::Move(file_name_from, file_name_to)); 416 417 // Check everything has been moved. 418 EXPECT_FALSE(file_util::PathExists(file_name_from)); 419 EXPECT_TRUE(file_util::PathExists(file_name_to)); 420 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to)); 421 } 422 423 TEST_F(FileUtilTest, MoveFileDirExists) { 424 // Create a file 425 FilePath file_name_from = 426 test_dir_.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 427 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 428 ASSERT_TRUE(file_util::PathExists(file_name_from)); 429 430 // The destination directory 431 FilePath dir_name_to = 432 test_dir_.Append(FILE_PATH_LITERAL("Destination")); 433 file_util::CreateDirectory(dir_name_to); 434 ASSERT_TRUE(file_util::PathExists(dir_name_to)); 435 436 EXPECT_FALSE(file_util::Move(file_name_from, dir_name_to)); 437 } 438 439 440 TEST_F(FileUtilTest, MoveNew) { 441 // Create a directory 442 FilePath dir_name_from = 443 test_dir_.Append(FILE_PATH_LITERAL("Move_From_Subdir")); 444 file_util::CreateDirectory(dir_name_from); 445 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 446 447 // Create a file under the directory 448 FilePath file_name_from = 449 dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 450 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 451 ASSERT_TRUE(file_util::PathExists(file_name_from)); 452 453 // Move the directory 454 FilePath dir_name_to = test_dir_.Append(FILE_PATH_LITERAL("Move_To_Subdir")); 455 FilePath file_name_to = 456 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 457 458 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 459 460 EXPECT_TRUE(file_util::Move(dir_name_from, dir_name_to)); 461 462 // Check everything has been moved. 463 EXPECT_FALSE(file_util::PathExists(dir_name_from)); 464 EXPECT_FALSE(file_util::PathExists(file_name_from)); 465 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 466 EXPECT_TRUE(file_util::PathExists(file_name_to)); 467 } 468 469 TEST_F(FileUtilTest, MoveExist) { 470 // Create a directory 471 FilePath dir_name_from = 472 test_dir_.Append(FILE_PATH_LITERAL("Move_From_Subdir")); 473 file_util::CreateDirectory(dir_name_from); 474 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 475 476 // Create a file under the directory 477 FilePath file_name_from = 478 dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 479 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 480 ASSERT_TRUE(file_util::PathExists(file_name_from)); 481 482 // Move the directory 483 FilePath dir_name_exists = 484 test_dir_.Append(FILE_PATH_LITERAL("Destination")); 485 486 FilePath dir_name_to = 487 dir_name_exists.Append(FILE_PATH_LITERAL("Move_To_Subdir")); 488 FilePath file_name_to = 489 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 490 491 // Create the destination directory. 492 file_util::CreateDirectory(dir_name_exists); 493 ASSERT_TRUE(file_util::PathExists(dir_name_exists)); 494 495 EXPECT_TRUE(file_util::Move(dir_name_from, dir_name_to)); 496 497 // Check everything has been moved. 498 EXPECT_FALSE(file_util::PathExists(dir_name_from)); 499 EXPECT_FALSE(file_util::PathExists(file_name_from)); 500 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 501 EXPECT_TRUE(file_util::PathExists(file_name_to)); 502 } 503 504 TEST_F(FileUtilTest, CopyDirectoryRecursivelyNew) { 505 // Create a directory. 506 FilePath dir_name_from = 507 test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 508 file_util::CreateDirectory(dir_name_from); 509 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 510 511 // Create a file under the directory. 512 FilePath file_name_from = 513 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 514 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 515 ASSERT_TRUE(file_util::PathExists(file_name_from)); 516 517 // Create a subdirectory. 518 FilePath subdir_name_from = 519 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 520 file_util::CreateDirectory(subdir_name_from); 521 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 522 523 // Create a file under the subdirectory. 524 FilePath file_name2_from = 525 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 526 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 527 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 528 529 // Copy the directory recursively. 530 FilePath dir_name_to = 531 test_dir_.Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 532 FilePath file_name_to = 533 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 534 FilePath subdir_name_to = 535 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 536 FilePath file_name2_to = 537 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 538 539 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 540 541 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_to, true)); 542 543 // Check everything has been copied. 544 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 545 EXPECT_TRUE(file_util::PathExists(file_name_from)); 546 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 547 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 548 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 549 EXPECT_TRUE(file_util::PathExists(file_name_to)); 550 EXPECT_TRUE(file_util::PathExists(subdir_name_to)); 551 EXPECT_TRUE(file_util::PathExists(file_name2_to)); 552 } 553 554 TEST_F(FileUtilTest, CopyDirectoryRecursivelyExists) { 555 // Create a directory. 556 FilePath dir_name_from = 557 test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 558 file_util::CreateDirectory(dir_name_from); 559 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 560 561 // Create a file under the directory. 562 FilePath file_name_from = 563 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 564 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 565 ASSERT_TRUE(file_util::PathExists(file_name_from)); 566 567 // Create a subdirectory. 568 FilePath subdir_name_from = 569 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 570 file_util::CreateDirectory(subdir_name_from); 571 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 572 573 // Create a file under the subdirectory. 574 FilePath file_name2_from = 575 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 576 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 577 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 578 579 // Copy the directory recursively. 580 FilePath dir_name_exists = 581 test_dir_.Append(FILE_PATH_LITERAL("Destination")); 582 583 FilePath dir_name_to = 584 dir_name_exists.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 585 FilePath file_name_to = 586 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 587 FilePath subdir_name_to = 588 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 589 FilePath file_name2_to = 590 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 591 592 // Create the destination directory. 593 file_util::CreateDirectory(dir_name_exists); 594 ASSERT_TRUE(file_util::PathExists(dir_name_exists)); 595 596 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_exists, true)); 597 598 // Check everything has been copied. 599 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 600 EXPECT_TRUE(file_util::PathExists(file_name_from)); 601 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 602 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 603 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 604 EXPECT_TRUE(file_util::PathExists(file_name_to)); 605 EXPECT_TRUE(file_util::PathExists(subdir_name_to)); 606 EXPECT_TRUE(file_util::PathExists(file_name2_to)); 607 } 608 609 TEST_F(FileUtilTest, CopyDirectoryNew) { 610 // Create a directory. 611 FilePath dir_name_from = 612 test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 613 file_util::CreateDirectory(dir_name_from); 614 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 615 616 // Create a file under the directory. 617 FilePath file_name_from = 618 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 619 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 620 ASSERT_TRUE(file_util::PathExists(file_name_from)); 621 622 // Create a subdirectory. 623 FilePath subdir_name_from = 624 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 625 file_util::CreateDirectory(subdir_name_from); 626 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 627 628 // Create a file under the subdirectory. 629 FilePath file_name2_from = 630 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 631 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 632 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 633 634 // Copy the directory not recursively. 635 FilePath dir_name_to = 636 test_dir_.Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 637 FilePath file_name_to = 638 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 639 FilePath subdir_name_to = 640 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 641 642 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 643 644 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_to, false)); 645 646 // Check everything has been copied. 647 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 648 EXPECT_TRUE(file_util::PathExists(file_name_from)); 649 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 650 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 651 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 652 EXPECT_TRUE(file_util::PathExists(file_name_to)); 653 EXPECT_FALSE(file_util::PathExists(subdir_name_to)); 654 } 655 656 TEST_F(FileUtilTest, CopyDirectoryExists) { 657 // Create a directory. 658 FilePath dir_name_from = 659 test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 660 file_util::CreateDirectory(dir_name_from); 661 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 662 663 // Create a file under the directory. 664 FilePath file_name_from = 665 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 666 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 667 ASSERT_TRUE(file_util::PathExists(file_name_from)); 668 669 // Create a subdirectory. 670 FilePath subdir_name_from = 671 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 672 file_util::CreateDirectory(subdir_name_from); 673 ASSERT_TRUE(file_util::PathExists(subdir_name_from)); 674 675 // Create a file under the subdirectory. 676 FilePath file_name2_from = 677 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 678 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 679 ASSERT_TRUE(file_util::PathExists(file_name2_from)); 680 681 // Copy the directory not recursively. 682 FilePath dir_name_to = 683 test_dir_.Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 684 FilePath file_name_to = 685 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 686 FilePath subdir_name_to = 687 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 688 689 // Create the destination directory. 690 file_util::CreateDirectory(dir_name_to); 691 ASSERT_TRUE(file_util::PathExists(dir_name_to)); 692 693 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from, dir_name_to, false)); 694 695 // Check everything has been copied. 696 EXPECT_TRUE(file_util::PathExists(dir_name_from)); 697 EXPECT_TRUE(file_util::PathExists(file_name_from)); 698 EXPECT_TRUE(file_util::PathExists(subdir_name_from)); 699 EXPECT_TRUE(file_util::PathExists(file_name2_from)); 700 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 701 EXPECT_TRUE(file_util::PathExists(file_name_to)); 702 EXPECT_FALSE(file_util::PathExists(subdir_name_to)); 703 } 704 705 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToNew) { 706 // Create a file 707 FilePath file_name_from = 708 test_dir_.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 709 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 710 ASSERT_TRUE(file_util::PathExists(file_name_from)); 711 712 // The destination name 713 FilePath file_name_to = 714 test_dir_.Append(FILE_PATH_LITERAL("Copy_Test_File_Destination.txt")); 715 ASSERT_FALSE(file_util::PathExists(file_name_to)); 716 717 EXPECT_TRUE(file_util::CopyDirectory(file_name_from, file_name_to, true)); 718 719 // Check the has been copied 720 EXPECT_TRUE(file_util::PathExists(file_name_to)); 721 } 722 723 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExisting) { 724 // Create a file 725 FilePath file_name_from = 726 test_dir_.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 727 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 728 ASSERT_TRUE(file_util::PathExists(file_name_from)); 729 730 // The destination name 731 FilePath file_name_to = 732 test_dir_.Append(FILE_PATH_LITERAL("Copy_Test_File_Destination.txt")); 733 CreateTextFile(file_name_to, L"Old file content"); 734 ASSERT_TRUE(file_util::PathExists(file_name_to)); 735 736 EXPECT_TRUE(file_util::CopyDirectory(file_name_from, file_name_to, true)); 737 738 // Check the has been copied 739 EXPECT_TRUE(file_util::PathExists(file_name_to)); 740 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to)); 741 } 742 743 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExistingDirectory) { 744 // Create a file 745 FilePath file_name_from = 746 test_dir_.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 747 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 748 ASSERT_TRUE(file_util::PathExists(file_name_from)); 749 750 // The destination 751 FilePath dir_name_to = 752 test_dir_.Append(FILE_PATH_LITERAL("Destination")); 753 file_util::CreateDirectory(dir_name_to); 754 ASSERT_TRUE(file_util::PathExists(dir_name_to)); 755 FilePath file_name_to = 756 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 757 758 EXPECT_TRUE(file_util::CopyDirectory(file_name_from, dir_name_to, true)); 759 760 // Check the has been copied 761 EXPECT_TRUE(file_util::PathExists(file_name_to)); 762 } 763 764 TEST_F(FileUtilTest, CopyFile) { 765 // Create a directory 766 FilePath dir_name_from = 767 test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 768 file_util::CreateDirectory(dir_name_from); 769 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 770 771 // Create a file under the directory 772 FilePath file_name_from = 773 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 774 const std::wstring file_contents(L"Gooooooooooooooooooooogle"); 775 CreateTextFile(file_name_from, file_contents); 776 ASSERT_TRUE(file_util::PathExists(file_name_from)); 777 778 // Copy the file. 779 FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt")); 780 ASSERT_TRUE(file_util::CopyFile(file_name_from, dest_file)); 781 782 // Copy the file to another location using '..' in the path. 783 FilePath dest_file2(dir_name_from); 784 dest_file2 = dest_file2.AppendASCII(".."); 785 dest_file2 = dest_file2.AppendASCII("DestFile.txt"); 786 ASSERT_TRUE(file_util::CopyFile(file_name_from, dest_file2)); 787 788 FilePath dest_file2_test(dir_name_from); 789 dest_file2_test = dest_file2_test.DirName(); 790 dest_file2_test = dest_file2_test.AppendASCII("DestFile.txt"); 791 792 // Check everything has been copied. 793 EXPECT_TRUE(file_util::PathExists(file_name_from)); 794 EXPECT_TRUE(file_util::PathExists(dest_file)); 795 const std::wstring read_contents = ReadTextFile(dest_file); 796 EXPECT_EQ(file_contents, read_contents); 797 EXPECT_TRUE(file_util::PathExists(dest_file2_test)); 798 EXPECT_TRUE(file_util::PathExists(dest_file2)); 799 } 800 801 // TODO(erikkay): implement 802 #if defined(OS_WIN) 803 TEST_F(FileUtilTest, GetFileCreationLocalTime) { 804 FilePath file_name = test_dir_.Append(L"Test File.txt"); 805 806 SYSTEMTIME start_time; 807 GetLocalTime(&start_time); 808 Sleep(100); 809 CreateTextFile(file_name, L"New file!"); 810 Sleep(100); 811 SYSTEMTIME end_time; 812 GetLocalTime(&end_time); 813 814 SYSTEMTIME file_creation_time; 815 file_util::GetFileCreationLocalTime(file_name.value(), &file_creation_time); 816 817 FILETIME start_filetime; 818 SystemTimeToFileTime(&start_time, &start_filetime); 819 FILETIME end_filetime; 820 SystemTimeToFileTime(&end_time, &end_filetime); 821 FILETIME file_creation_filetime; 822 SystemTimeToFileTime(&file_creation_time, &file_creation_filetime); 823 824 EXPECT_EQ(-1, CompareFileTime(&start_filetime, &file_creation_filetime)) << 825 "start time: " << FileTimeAsUint64(start_filetime) << ", " << 826 "creation time: " << FileTimeAsUint64(file_creation_filetime); 827 828 EXPECT_EQ(-1, CompareFileTime(&file_creation_filetime, &end_filetime)) << 829 "creation time: " << FileTimeAsUint64(file_creation_filetime) << ", " << 830 "end time: " << FileTimeAsUint64(end_filetime); 831 832 ASSERT_TRUE(DeleteFile(file_name.value().c_str())); 833 } 834 #endif 835 836 // file_util winds up using autoreleased objects on the Mac, so this needs 837 // to be a PlatformTest. 838 typedef PlatformTest ReadOnlyFileUtilTest; 839 840 TEST_F(ReadOnlyFileUtilTest, ContentsEqual) { 841 FilePath data_dir; 842 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir)); 843 data_dir = data_dir.Append(FILE_PATH_LITERAL("base")) 844 .Append(FILE_PATH_LITERAL("data")) 845 .Append(FILE_PATH_LITERAL("file_util_unittest")); 846 ASSERT_TRUE(file_util::PathExists(data_dir)); 847 848 FilePath original_file = 849 data_dir.Append(FILE_PATH_LITERAL("original.txt")); 850 FilePath same_file = 851 data_dir.Append(FILE_PATH_LITERAL("same.txt")); 852 FilePath same_length_file = 853 data_dir.Append(FILE_PATH_LITERAL("same_length.txt")); 854 FilePath different_file = 855 data_dir.Append(FILE_PATH_LITERAL("different.txt")); 856 FilePath different_first_file = 857 data_dir.Append(FILE_PATH_LITERAL("different_first.txt")); 858 FilePath different_last_file = 859 data_dir.Append(FILE_PATH_LITERAL("different_last.txt")); 860 FilePath empty1_file = 861 data_dir.Append(FILE_PATH_LITERAL("empty1.txt")); 862 FilePath empty2_file = 863 data_dir.Append(FILE_PATH_LITERAL("empty2.txt")); 864 FilePath shortened_file = 865 data_dir.Append(FILE_PATH_LITERAL("shortened.txt")); 866 FilePath binary_file = 867 data_dir.Append(FILE_PATH_LITERAL("binary_file.bin")); 868 FilePath binary_file_same = 869 data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin")); 870 FilePath binary_file_diff = 871 data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin")); 872 873 EXPECT_TRUE(file_util::ContentsEqual(original_file, original_file)); 874 EXPECT_TRUE(file_util::ContentsEqual(original_file, same_file)); 875 EXPECT_FALSE(file_util::ContentsEqual(original_file, same_length_file)); 876 EXPECT_FALSE(file_util::ContentsEqual(original_file, different_file)); 877 EXPECT_FALSE(file_util::ContentsEqual( 878 FilePath(FILE_PATH_LITERAL("bogusname")), 879 FilePath(FILE_PATH_LITERAL("bogusname")))); 880 EXPECT_FALSE(file_util::ContentsEqual(original_file, different_first_file)); 881 EXPECT_FALSE(file_util::ContentsEqual(original_file, different_last_file)); 882 EXPECT_TRUE(file_util::ContentsEqual(empty1_file, empty2_file)); 883 EXPECT_FALSE(file_util::ContentsEqual(original_file, shortened_file)); 884 EXPECT_FALSE(file_util::ContentsEqual(shortened_file, original_file)); 885 EXPECT_TRUE(file_util::ContentsEqual(binary_file, binary_file_same)); 886 EXPECT_FALSE(file_util::ContentsEqual(binary_file, binary_file_diff)); 887 } 888 889 TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) { 890 FilePath data_dir; 891 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir)); 892 data_dir = data_dir.Append(FILE_PATH_LITERAL("base")) 893 .Append(FILE_PATH_LITERAL("data")) 894 .Append(FILE_PATH_LITERAL("file_util_unittest")); 895 ASSERT_TRUE(file_util::PathExists(data_dir)); 896 897 FilePath original_file = 898 data_dir.Append(FILE_PATH_LITERAL("original.txt")); 899 FilePath same_file = 900 data_dir.Append(FILE_PATH_LITERAL("same.txt")); 901 FilePath crlf_file = 902 data_dir.Append(FILE_PATH_LITERAL("crlf.txt")); 903 FilePath shortened_file = 904 data_dir.Append(FILE_PATH_LITERAL("shortened.txt")); 905 FilePath different_file = 906 data_dir.Append(FILE_PATH_LITERAL("different.txt")); 907 FilePath different_first_file = 908 data_dir.Append(FILE_PATH_LITERAL("different_first.txt")); 909 FilePath different_last_file = 910 data_dir.Append(FILE_PATH_LITERAL("different_last.txt")); 911 FilePath first1_file = 912 data_dir.Append(FILE_PATH_LITERAL("first1.txt")); 913 FilePath first2_file = 914 data_dir.Append(FILE_PATH_LITERAL("first2.txt")); 915 FilePath empty1_file = 916 data_dir.Append(FILE_PATH_LITERAL("empty1.txt")); 917 FilePath empty2_file = 918 data_dir.Append(FILE_PATH_LITERAL("empty2.txt")); 919 FilePath blank_line_file = 920 data_dir.Append(FILE_PATH_LITERAL("blank_line.txt")); 921 FilePath blank_line_crlf_file = 922 data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt")); 923 924 EXPECT_TRUE(file_util::TextContentsEqual(original_file, same_file)); 925 EXPECT_TRUE(file_util::TextContentsEqual(original_file, crlf_file)); 926 EXPECT_FALSE(file_util::TextContentsEqual(original_file, shortened_file)); 927 EXPECT_FALSE(file_util::TextContentsEqual(original_file, different_file)); 928 EXPECT_FALSE(file_util::TextContentsEqual(original_file, 929 different_first_file)); 930 EXPECT_FALSE(file_util::TextContentsEqual(original_file, 931 different_last_file)); 932 EXPECT_FALSE(file_util::TextContentsEqual(first1_file, first2_file)); 933 EXPECT_TRUE(file_util::TextContentsEqual(empty1_file, empty2_file)); 934 EXPECT_FALSE(file_util::TextContentsEqual(original_file, empty1_file)); 935 EXPECT_TRUE(file_util::TextContentsEqual(blank_line_file, 936 blank_line_crlf_file)); 937 } 938 939 // We don't need equivalent functionality outside of Windows. 940 #if defined(OS_WIN) 941 TEST_F(FileUtilTest, ResolveShortcutTest) { 942 FilePath target_file = test_dir_.Append(L"Target.txt"); 943 CreateTextFile(target_file, L"This is the target."); 944 945 FilePath link_file = test_dir_.Append(L"Link.lnk"); 946 947 HRESULT result; 948 IShellLink *shell = NULL; 949 IPersistFile *persist = NULL; 950 951 CoInitialize(NULL); 952 // Temporarily create a shortcut for test 953 result = CoCreateInstance(CLSID_ShellLink, NULL, 954 CLSCTX_INPROC_SERVER, IID_IShellLink, 955 reinterpret_cast<LPVOID*>(&shell)); 956 EXPECT_TRUE(SUCCEEDED(result)); 957 result = shell->QueryInterface(IID_IPersistFile, 958 reinterpret_cast<LPVOID*>(&persist)); 959 EXPECT_TRUE(SUCCEEDED(result)); 960 result = shell->SetPath(target_file.value().c_str()); 961 EXPECT_TRUE(SUCCEEDED(result)); 962 result = shell->SetDescription(L"ResolveShortcutTest"); 963 EXPECT_TRUE(SUCCEEDED(result)); 964 result = persist->Save(link_file.value().c_str(), TRUE); 965 EXPECT_TRUE(SUCCEEDED(result)); 966 if (persist) 967 persist->Release(); 968 if (shell) 969 shell->Release(); 970 971 bool is_solved; 972 is_solved = file_util::ResolveShortcut(&link_file); 973 EXPECT_TRUE(is_solved); 974 std::wstring contents; 975 contents = ReadTextFile(link_file); 976 EXPECT_EQ(L"This is the target.", contents); 977 978 // Cleaning 979 DeleteFile(target_file.value().c_str()); 980 DeleteFile(link_file.value().c_str()); 981 CoUninitialize(); 982 } 983 984 TEST_F(FileUtilTest, CreateShortcutTest) { 985 const wchar_t file_contents[] = L"This is another target."; 986 FilePath target_file = test_dir_.Append(L"Target1.txt"); 987 CreateTextFile(target_file, file_contents); 988 989 FilePath link_file = test_dir_.Append(L"Link1.lnk"); 990 991 CoInitialize(NULL); 992 EXPECT_TRUE(file_util::CreateShortcutLink(target_file.value().c_str(), 993 link_file.value().c_str(), 994 NULL, NULL, NULL, NULL, 0, NULL)); 995 FilePath resolved_name = link_file; 996 EXPECT_TRUE(file_util::ResolveShortcut(&resolved_name)); 997 std::wstring read_contents = ReadTextFile(resolved_name); 998 EXPECT_EQ(file_contents, read_contents); 999 1000 DeleteFile(target_file.value().c_str()); 1001 DeleteFile(link_file.value().c_str()); 1002 CoUninitialize(); 1003 } 1004 1005 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) { 1006 // Create a directory 1007 FilePath dir_name_from = 1008 test_dir_.Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir")); 1009 file_util::CreateDirectory(dir_name_from); 1010 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 1011 1012 // Create a file under the directory 1013 FilePath file_name_from = 1014 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1015 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1016 ASSERT_TRUE(file_util::PathExists(file_name_from)); 1017 1018 // Move the directory by using CopyAndDeleteDirectory 1019 FilePath dir_name_to = test_dir_.Append( 1020 FILE_PATH_LITERAL("CopyAndDelete_To_Subdir")); 1021 FilePath file_name_to = 1022 dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1023 1024 ASSERT_FALSE(file_util::PathExists(dir_name_to)); 1025 1026 EXPECT_TRUE(file_util::CopyAndDeleteDirectory(dir_name_from, dir_name_to)); 1027 1028 // Check everything has been moved. 1029 EXPECT_FALSE(file_util::PathExists(dir_name_from)); 1030 EXPECT_FALSE(file_util::PathExists(file_name_from)); 1031 EXPECT_TRUE(file_util::PathExists(dir_name_to)); 1032 EXPECT_TRUE(file_util::PathExists(file_name_to)); 1033 } 1034 1035 TEST_F(FileUtilTest, GetTempDirTest) { 1036 static const TCHAR* kTmpKey = _T("TMP"); 1037 static const TCHAR* kTmpValues[] = { 1038 _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\") 1039 }; 1040 // Save the original $TMP. 1041 size_t original_tmp_size; 1042 TCHAR* original_tmp; 1043 ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey)); 1044 // original_tmp may be NULL. 1045 1046 for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) { 1047 FilePath path; 1048 ::_tputenv_s(kTmpKey, kTmpValues[i]); 1049 file_util::GetTempDir(&path); 1050 EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] << 1051 " result=" << path.value(); 1052 } 1053 1054 // Restore the original $TMP. 1055 if (original_tmp) { 1056 ::_tputenv_s(kTmpKey, original_tmp); 1057 free(original_tmp); 1058 } else { 1059 ::_tputenv_s(kTmpKey, _T("")); 1060 } 1061 } 1062 #endif // OS_WIN 1063 1064 TEST_F(FileUtilTest, CreateTemporaryFileTest) { 1065 FilePath temp_files[3]; 1066 for (int i = 0; i < 3; i++) { 1067 ASSERT_TRUE(file_util::CreateTemporaryFile(&(temp_files[i]))); 1068 EXPECT_TRUE(file_util::PathExists(temp_files[i])); 1069 EXPECT_FALSE(file_util::DirectoryExists(temp_files[i])); 1070 } 1071 for (int i = 0; i < 3; i++) 1072 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]); 1073 for (int i = 0; i < 3; i++) 1074 EXPECT_TRUE(file_util::Delete(temp_files[i], false)); 1075 } 1076 1077 TEST_F(FileUtilTest, CreateAndOpenTemporaryFileTest) { 1078 FilePath names[3]; 1079 FILE *fps[3]; 1080 int i; 1081 1082 // Create; make sure they are open and exist. 1083 for (i = 0; i < 3; ++i) { 1084 fps[i] = file_util::CreateAndOpenTemporaryFile(&(names[i])); 1085 ASSERT_TRUE(fps[i]); 1086 EXPECT_TRUE(file_util::PathExists(names[i])); 1087 } 1088 1089 // Make sure all names are unique. 1090 for (i = 0; i < 3; ++i) { 1091 EXPECT_FALSE(names[i] == names[(i+1)%3]); 1092 } 1093 1094 // Close and delete. 1095 for (i = 0; i < 3; ++i) { 1096 EXPECT_TRUE(file_util::CloseFile(fps[i])); 1097 EXPECT_TRUE(file_util::Delete(names[i], false)); 1098 } 1099 } 1100 1101 TEST_F(FileUtilTest, CreateNewTempDirectoryTest) { 1102 FilePath temp_dir; 1103 ASSERT_TRUE(file_util::CreateNewTempDirectory(FilePath::StringType(), 1104 &temp_dir)); 1105 EXPECT_TRUE(file_util::PathExists(temp_dir)); 1106 EXPECT_TRUE(file_util::Delete(temp_dir, false)); 1107 } 1108 1109 TEST_F(FileUtilTest, GetShmemTempDirTest) { 1110 FilePath dir; 1111 EXPECT_TRUE(file_util::GetShmemTempDir(&dir)); 1112 EXPECT_TRUE(file_util::DirectoryExists(dir)); 1113 } 1114 1115 TEST_F(FileUtilTest, CreateDirectoryTest) { 1116 FilePath test_root = 1117 test_dir_.Append(FILE_PATH_LITERAL("create_directory_test")); 1118 #if defined(OS_WIN) 1119 FilePath test_path = 1120 test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\")); 1121 #elif defined(OS_POSIX) 1122 FilePath test_path = 1123 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/")); 1124 #endif 1125 1126 EXPECT_FALSE(file_util::PathExists(test_path)); 1127 EXPECT_TRUE(file_util::CreateDirectory(test_path)); 1128 EXPECT_TRUE(file_util::PathExists(test_path)); 1129 // CreateDirectory returns true if the DirectoryExists returns true. 1130 EXPECT_TRUE(file_util::CreateDirectory(test_path)); 1131 1132 // Doesn't work to create it on top of a non-dir 1133 test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt")); 1134 EXPECT_FALSE(file_util::PathExists(test_path)); 1135 CreateTextFile(test_path, L"test file"); 1136 EXPECT_TRUE(file_util::PathExists(test_path)); 1137 EXPECT_FALSE(file_util::CreateDirectory(test_path)); 1138 1139 EXPECT_TRUE(file_util::Delete(test_root, true)); 1140 EXPECT_FALSE(file_util::PathExists(test_root)); 1141 EXPECT_FALSE(file_util::PathExists(test_path)); 1142 1143 // Verify assumptions made by the Windows implementation: 1144 // 1. The current directory always exists. 1145 // 2. The root directory always exists. 1146 ASSERT_TRUE(file_util::DirectoryExists( 1147 FilePath(FilePath::kCurrentDirectory))); 1148 FilePath top_level = test_root; 1149 while (top_level != top_level.DirName()) { 1150 top_level = top_level.DirName(); 1151 } 1152 ASSERT_TRUE(file_util::DirectoryExists(top_level)); 1153 1154 // Given these assumptions hold, it should be safe to 1155 // test that "creating" these directories succeeds. 1156 EXPECT_TRUE(file_util::CreateDirectory( 1157 FilePath(FilePath::kCurrentDirectory))); 1158 EXPECT_TRUE(file_util::CreateDirectory(top_level)); 1159 1160 #if defined(OS_WIN) 1161 FilePath invalid_drive(FILE_PATH_LITERAL("o:\\")); 1162 FilePath invalid_path = 1163 invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir")); 1164 if (!file_util::PathExists(invalid_drive)) { 1165 EXPECT_FALSE(file_util::CreateDirectory(invalid_path)); 1166 } 1167 #endif 1168 } 1169 1170 TEST_F(FileUtilTest, DetectDirectoryTest) { 1171 // Check a directory 1172 FilePath test_root = 1173 test_dir_.Append(FILE_PATH_LITERAL("detect_directory_test")); 1174 EXPECT_FALSE(file_util::PathExists(test_root)); 1175 EXPECT_TRUE(file_util::CreateDirectory(test_root)); 1176 EXPECT_TRUE(file_util::PathExists(test_root)); 1177 EXPECT_TRUE(file_util::DirectoryExists(test_root)); 1178 1179 // Check a file 1180 FilePath test_path = 1181 test_root.Append(FILE_PATH_LITERAL("foobar.txt")); 1182 EXPECT_FALSE(file_util::PathExists(test_path)); 1183 CreateTextFile(test_path, L"test file"); 1184 EXPECT_TRUE(file_util::PathExists(test_path)); 1185 EXPECT_FALSE(file_util::DirectoryExists(test_path)); 1186 EXPECT_TRUE(file_util::Delete(test_path, false)); 1187 1188 EXPECT_TRUE(file_util::Delete(test_root, true)); 1189 } 1190 1191 static const struct ReplaceExtensionCase { 1192 std::wstring file_name; 1193 FilePath::StringType extension; 1194 std::wstring result; 1195 } kReplaceExtension[] = { 1196 {L"", FILE_PATH_LITERAL(""), L""}, 1197 {L"", FILE_PATH_LITERAL("txt"), L".txt"}, 1198 {L".", FILE_PATH_LITERAL("txt"), L".txt"}, 1199 {L".", FILE_PATH_LITERAL(""), L""}, 1200 {L"foo.dll", FILE_PATH_LITERAL("txt"), L"foo.txt"}, 1201 {L"foo.dll", FILE_PATH_LITERAL(".txt"), L"foo.txt"}, 1202 {L"foo", FILE_PATH_LITERAL("txt"), L"foo.txt"}, 1203 {L"foo", FILE_PATH_LITERAL(".txt"), L"foo.txt"}, 1204 {L"foo.baz.dll", FILE_PATH_LITERAL("txt"), L"foo.baz.txt"}, 1205 {L"foo.baz.dll", FILE_PATH_LITERAL(".txt"), L"foo.baz.txt"}, 1206 {L"foo.dll", FILE_PATH_LITERAL(""), L"foo"}, 1207 {L"foo.dll", FILE_PATH_LITERAL("."), L"foo"}, 1208 {L"foo", FILE_PATH_LITERAL(""), L"foo"}, 1209 {L"foo", FILE_PATH_LITERAL("."), L"foo"}, 1210 {L"foo.baz.dll", FILE_PATH_LITERAL(""), L"foo.baz"}, 1211 {L"foo.baz.dll", FILE_PATH_LITERAL("."), L"foo.baz"}, 1212 }; 1213 1214 TEST_F(FileUtilTest, ReplaceExtensionTest) { 1215 for (unsigned int i = 0; i < arraysize(kReplaceExtension); ++i) { 1216 FilePath path = FilePath::FromWStringHack(kReplaceExtension[i].file_name); 1217 file_util::ReplaceExtension(&path, kReplaceExtension[i].extension); 1218 EXPECT_EQ(kReplaceExtension[i].result, path.ToWStringHack()); 1219 } 1220 } 1221 1222 // Make sure ReplaceExtension doesn't replace an extension that occurs as one of 1223 // the directory names of the path. 1224 TEST_F(FileUtilTest, ReplaceExtensionTestWithPathSeparators) { 1225 FilePath path; 1226 path = path.Append(FILE_PATH_LITERAL("foo.bar")); 1227 path = path.Append(FILE_PATH_LITERAL("foo")); 1228 // '/foo.bar/foo' with extension '.baz' 1229 FilePath result_path = path; 1230 file_util::ReplaceExtension(&result_path, FILE_PATH_LITERAL(".baz")); 1231 EXPECT_EQ(path.value() + FILE_PATH_LITERAL(".baz"), 1232 result_path.value()); 1233 } 1234 1235 TEST_F(FileUtilTest, FileEnumeratorTest) { 1236 // Test an empty directory. 1237 file_util::FileEnumerator f0(test_dir_, true, FILES_AND_DIRECTORIES); 1238 EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL("")); 1239 EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL("")); 1240 1241 // Test an empty directory, non-recursively, including "..". 1242 file_util::FileEnumerator f0_dotdot(test_dir_, false, 1243 static_cast<file_util::FileEnumerator::FILE_TYPE>( 1244 FILES_AND_DIRECTORIES | file_util::FileEnumerator::INCLUDE_DOT_DOT)); 1245 EXPECT_EQ(test_dir_.Append(FILE_PATH_LITERAL("..")).value(), 1246 f0_dotdot.Next().value()); 1247 EXPECT_EQ(FILE_PATH_LITERAL(""), 1248 f0_dotdot.Next().value()); 1249 1250 // create the directories 1251 FilePath dir1 = test_dir_.Append(FILE_PATH_LITERAL("dir1")); 1252 EXPECT_TRUE(file_util::CreateDirectory(dir1)); 1253 FilePath dir2 = test_dir_.Append(FILE_PATH_LITERAL("dir2")); 1254 EXPECT_TRUE(file_util::CreateDirectory(dir2)); 1255 FilePath dir2inner = dir2.Append(FILE_PATH_LITERAL("inner")); 1256 EXPECT_TRUE(file_util::CreateDirectory(dir2inner)); 1257 1258 // create the files 1259 FilePath dir2file = dir2.Append(FILE_PATH_LITERAL("dir2file.txt")); 1260 CreateTextFile(dir2file, L""); 1261 FilePath dir2innerfile = dir2inner.Append(FILE_PATH_LITERAL("innerfile.txt")); 1262 CreateTextFile(dir2innerfile, L""); 1263 FilePath file1 = test_dir_.Append(FILE_PATH_LITERAL("file1.txt")); 1264 CreateTextFile(file1, L""); 1265 FilePath file2_rel = 1266 dir2.Append(FilePath::kParentDirectory) 1267 .Append(FILE_PATH_LITERAL("file2.txt")); 1268 CreateTextFile(file2_rel, L""); 1269 FilePath file2_abs = test_dir_.Append(FILE_PATH_LITERAL("file2.txt")); 1270 1271 // Only enumerate files. 1272 file_util::FileEnumerator f1(test_dir_, true, 1273 file_util::FileEnumerator::FILES); 1274 FindResultCollector c1(f1); 1275 EXPECT_TRUE(c1.HasFile(file1)); 1276 EXPECT_TRUE(c1.HasFile(file2_abs)); 1277 EXPECT_TRUE(c1.HasFile(dir2file)); 1278 EXPECT_TRUE(c1.HasFile(dir2innerfile)); 1279 EXPECT_EQ(c1.size(), 4); 1280 1281 // Only enumerate directories. 1282 file_util::FileEnumerator f2(test_dir_, true, 1283 file_util::FileEnumerator::DIRECTORIES); 1284 FindResultCollector c2(f2); 1285 EXPECT_TRUE(c2.HasFile(dir1)); 1286 EXPECT_TRUE(c2.HasFile(dir2)); 1287 EXPECT_TRUE(c2.HasFile(dir2inner)); 1288 EXPECT_EQ(c2.size(), 3); 1289 1290 // Only enumerate directories non-recursively. 1291 file_util::FileEnumerator f2_non_recursive( 1292 test_dir_, false, file_util::FileEnumerator::DIRECTORIES); 1293 FindResultCollector c2_non_recursive(f2_non_recursive); 1294 EXPECT_TRUE(c2_non_recursive.HasFile(dir1)); 1295 EXPECT_TRUE(c2_non_recursive.HasFile(dir2)); 1296 EXPECT_EQ(c2_non_recursive.size(), 2); 1297 1298 // Only enumerate directories, non-recursively, including "..". 1299 file_util::FileEnumerator f2_dotdot( 1300 test_dir_, false, 1301 static_cast<file_util::FileEnumerator::FILE_TYPE>( 1302 file_util::FileEnumerator::DIRECTORIES | 1303 file_util::FileEnumerator::INCLUDE_DOT_DOT)); 1304 FindResultCollector c2_dotdot(f2_dotdot); 1305 EXPECT_TRUE(c2_dotdot.HasFile(dir1)); 1306 EXPECT_TRUE(c2_dotdot.HasFile(dir2)); 1307 EXPECT_TRUE(c2_dotdot.HasFile(test_dir_.Append(FILE_PATH_LITERAL("..")))); 1308 EXPECT_EQ(c2_dotdot.size(), 3); 1309 1310 // Enumerate files and directories. 1311 file_util::FileEnumerator f3(test_dir_, true, FILES_AND_DIRECTORIES); 1312 FindResultCollector c3(f3); 1313 EXPECT_TRUE(c3.HasFile(dir1)); 1314 EXPECT_TRUE(c3.HasFile(dir2)); 1315 EXPECT_TRUE(c3.HasFile(file1)); 1316 EXPECT_TRUE(c3.HasFile(file2_abs)); 1317 EXPECT_TRUE(c3.HasFile(dir2file)); 1318 EXPECT_TRUE(c3.HasFile(dir2inner)); 1319 EXPECT_TRUE(c3.HasFile(dir2innerfile)); 1320 EXPECT_EQ(c3.size(), 7); 1321 1322 // Non-recursive operation. 1323 file_util::FileEnumerator f4(test_dir_, false, FILES_AND_DIRECTORIES); 1324 FindResultCollector c4(f4); 1325 EXPECT_TRUE(c4.HasFile(dir2)); 1326 EXPECT_TRUE(c4.HasFile(dir2)); 1327 EXPECT_TRUE(c4.HasFile(file1)); 1328 EXPECT_TRUE(c4.HasFile(file2_abs)); 1329 EXPECT_EQ(c4.size(), 4); 1330 1331 // Enumerate with a pattern. 1332 file_util::FileEnumerator f5(test_dir_, true, FILES_AND_DIRECTORIES, 1333 FILE_PATH_LITERAL("dir*")); 1334 FindResultCollector c5(f5); 1335 EXPECT_TRUE(c5.HasFile(dir1)); 1336 EXPECT_TRUE(c5.HasFile(dir2)); 1337 EXPECT_TRUE(c5.HasFile(dir2file)); 1338 EXPECT_TRUE(c5.HasFile(dir2inner)); 1339 EXPECT_TRUE(c5.HasFile(dir2innerfile)); 1340 EXPECT_EQ(c5.size(), 5); 1341 1342 // Make sure the destructor closes the find handle while in the middle of a 1343 // query to allow TearDown to delete the directory. 1344 file_util::FileEnumerator f6(test_dir_, true, FILES_AND_DIRECTORIES); 1345 EXPECT_FALSE(f6.Next().value().empty()); // Should have found something 1346 // (we don't care what). 1347 } 1348 1349 TEST_F(FileUtilTest, Contains) { 1350 FilePath data_dir = test_dir_.Append(FILE_PATH_LITERAL("FilePathTest")); 1351 1352 // Create a fresh, empty copy of this directory. 1353 if (file_util::PathExists(data_dir)) { 1354 ASSERT_TRUE(file_util::Delete(data_dir, true)); 1355 } 1356 ASSERT_TRUE(file_util::CreateDirectory(data_dir)); 1357 1358 FilePath foo(data_dir.Append(FILE_PATH_LITERAL("foo"))); 1359 FilePath bar(foo.Append(FILE_PATH_LITERAL("bar.txt"))); 1360 FilePath baz(data_dir.Append(FILE_PATH_LITERAL("baz.txt"))); 1361 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt"))); 1362 1363 // Annoyingly, the directories must actually exist in order for realpath(), 1364 // which Contains() relies on in posix, to work. 1365 ASSERT_TRUE(file_util::CreateDirectory(foo)); 1366 std::string data("hello"); 1367 ASSERT_TRUE(file_util::WriteFile(bar, data.c_str(), data.length())); 1368 ASSERT_TRUE(file_util::WriteFile(baz, data.c_str(), data.length())); 1369 ASSERT_TRUE(file_util::WriteFile(foobar, data.c_str(), data.length())); 1370 1371 EXPECT_TRUE(file_util::ContainsPath(foo, bar)); 1372 EXPECT_FALSE(file_util::ContainsPath(foo, baz)); 1373 EXPECT_FALSE(file_util::ContainsPath(foo, foobar)); 1374 EXPECT_FALSE(file_util::ContainsPath(foo, foo)); 1375 1376 // Platform-specific concerns. 1377 FilePath foo_caps(data_dir.Append(FILE_PATH_LITERAL("FOO"))); 1378 #if defined(OS_WIN) 1379 EXPECT_TRUE(file_util::ContainsPath(foo, 1380 foo_caps.Append(FILE_PATH_LITERAL("bar.txt")))); 1381 EXPECT_TRUE(file_util::ContainsPath(foo, 1382 FilePath(foo.value() + FILE_PATH_LITERAL("/bar.txt")))); 1383 #elif defined(OS_MACOSX) 1384 // We can't really do this test on OS X since the case-sensitivity of the 1385 // filesystem is configurable. 1386 #elif defined(OS_POSIX) 1387 EXPECT_FALSE(file_util::ContainsPath(foo, 1388 foo_caps.Append(FILE_PATH_LITERAL("bar.txt")))); 1389 #endif 1390 } 1391 1392 } // namespace 1393