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