• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
SetReparsePoint(HANDLE source,const FilePath & target_path)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.
DeleteReparsePoint(HANDLE source)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:
SetUp()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:
FindResultCollector(file_util::FileEnumerator & enumerator)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.
HasFile(const FilePath & file) const150   bool HasFile(const FilePath& file) const {
151     return files_.find(file.value()) != files_.end();
152   }
153 
size()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.
CreateTextFile(const FilePath & filename,const std::wstring & contents)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.
ReadTextFile(const FilePath & filename)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)
FileTimeAsUint64(const FILETIME & ft)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.
TEST_F(FileUtilTest,AppendToPath)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.
TEST_F(FileUtilTest,GetFileExtensionFromPath)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
TEST_F(FileUtilTest,FLAKY_CountFilesCreatedAfter)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 
TEST_F(FileUtilTest,FileAndDirectorySize)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 
TEST_F(FileUtilTest,NormalizeFilePathBasic)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 
TEST_F(FileUtilTest,NormalizeFilePathReparsePoints)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 
TEST_F(FileUtilTest,CreateAndReadSymlinks)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.
TEST_F(FileUtilTest,NormalizeFilePathSymlinks)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 
TEST_F(FileUtilTest,DeleteNonExistent)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 
TEST_F(FileUtilTest,DeleteFile)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
TEST_F(FileUtilTest,DeleteWildCard)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
TEST_F(FileUtilTest,DeleteNonExistantWildCard)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.
TEST_F(FileUtilTest,DeleteDirNonRecursive)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.
TEST_F(FileUtilTest,DeleteDirRecursive)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 
TEST_F(FileUtilTest,MoveFileNew)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 
TEST_F(FileUtilTest,MoveFileExists)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 
TEST_F(FileUtilTest,MoveFileDirExists)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 
TEST_F(FileUtilTest,MoveNew)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 
TEST_F(FileUtilTest,MoveExist)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 
TEST_F(FileUtilTest,CopyDirectoryRecursivelyNew)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 
TEST_F(FileUtilTest,CopyDirectoryRecursivelyExists)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 
TEST_F(FileUtilTest,CopyDirectoryNew)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 
TEST_F(FileUtilTest,CopyDirectoryExists)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 
TEST_F(FileUtilTest,CopyFileWithCopyDirectoryRecursiveToNew)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 
TEST_F(FileUtilTest,CopyFileWithCopyDirectoryRecursiveToExisting)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 
TEST_F(FileUtilTest,CopyFileWithCopyDirectoryRecursiveToExistingDirectory)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 
TEST_F(FileUtilTest,CopyFile)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)
TEST_F(FileUtilTest,GetFileCreationLocalTime)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 
TEST_F(ReadOnlyFileUtilTest,ContentsEqual)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 
TEST_F(ReadOnlyFileUtilTest,TextContentsEqual)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)
TEST_F(FileUtilTest,ResolveShortcutTest)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 
TEST_F(FileUtilTest,CreateShortcutTest)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 
TEST_F(FileUtilTest,CopyAndDeleteDirectoryTest)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 
TEST_F(FileUtilTest,GetTempDirTest)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 
TEST_F(FileUtilTest,CreateTemporaryFileTest)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 
TEST_F(FileUtilTest,CreateAndOpenTemporaryFileTest)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 
TEST_F(FileUtilTest,CreateNewTempDirectoryTest)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 
TEST_F(FileUtilTest,CreateNewTemporaryDirInDirTest)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 
TEST_F(FileUtilTest,GetShmemTempDirTest)1524 TEST_F(FileUtilTest, GetShmemTempDirTest) {
1525   FilePath dir;
1526   EXPECT_TRUE(file_util::GetShmemTempDir(&dir));
1527   EXPECT_TRUE(file_util::DirectoryExists(dir));
1528 }
1529 
TEST_F(FileUtilTest,CreateDirectoryTest)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 
TEST_F(FileUtilTest,DetectDirectoryTest)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 
TEST_F(FileUtilTest,FileEnumeratorTest)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 
TEST_F(FileUtilTest,Contains)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 
TEST_F(FileUtilTest,TouchFile)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 
TEST_F(FileUtilTest,IsDirectoryEmpty)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