Home | History | Annotate | Download | only in base
      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