- add sources.
[platform/framework/web/crosswalk.git] / src / base / file_util_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "build/build_config.h"
6
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #include <shellapi.h>
10 #include <shlobj.h>
11 #include <tchar.h>
12 #include <winioctl.h>
13 #endif
14
15 #include <algorithm>
16 #include <fstream>
17 #include <set>
18
19 #include "base/base_paths.h"
20 #include "base/file_util.h"
21 #include "base/files/file_enumerator.h"
22 #include "base/files/file_path.h"
23 #include "base/files/scoped_temp_dir.h"
24 #include "base/path_service.h"
25 #include "base/strings/utf_string_conversions.h"
26 #include "base/test/test_file_util.h"
27 #include "base/threading/platform_thread.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
30
31 #if defined(OS_WIN)
32 #include "base/win/scoped_handle.h"
33 #include "base/win/windows_version.h"
34 #endif
35
36 // This macro helps avoid wrapped lines in the test structs.
37 #define FPL(x) FILE_PATH_LITERAL(x)
38
39 using base::DirectoryExists;
40 using base::FileEnumerator;
41 using base::FilePath;
42 using base::PathIsWritable;
43 using base::TextContentsEqual;
44
45 namespace {
46
47 // To test that file_util::Normalize FilePath() deals with NTFS reparse points
48 // correctly, we need functions to create and delete reparse points.
49 #if defined(OS_WIN)
50 typedef struct _REPARSE_DATA_BUFFER {
51   ULONG  ReparseTag;
52   USHORT  ReparseDataLength;
53   USHORT  Reserved;
54   union {
55     struct {
56       USHORT SubstituteNameOffset;
57       USHORT SubstituteNameLength;
58       USHORT PrintNameOffset;
59       USHORT PrintNameLength;
60       ULONG Flags;
61       WCHAR PathBuffer[1];
62     } SymbolicLinkReparseBuffer;
63     struct {
64       USHORT SubstituteNameOffset;
65       USHORT SubstituteNameLength;
66       USHORT PrintNameOffset;
67       USHORT PrintNameLength;
68       WCHAR PathBuffer[1];
69     } MountPointReparseBuffer;
70     struct {
71       UCHAR DataBuffer[1];
72     } GenericReparseBuffer;
73   };
74 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
75
76 // Sets a reparse point. |source| will now point to |target|. Returns true if
77 // the call succeeds, false otherwise.
78 bool SetReparsePoint(HANDLE source, const FilePath& target_path) {
79   std::wstring kPathPrefix = L"\\??\\";
80   std::wstring target_str;
81   // The juction will not work if the target path does not start with \??\ .
82   if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size()))
83     target_str += kPathPrefix;
84   target_str += target_path.value();
85   const wchar_t* target = target_str.c_str();
86   USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]);
87   char buffer[2000] = {0};
88   DWORD returned;
89
90   REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer);
91
92   data->ReparseTag = 0xa0000003;
93   memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2);
94
95   data->MountPointReparseBuffer.SubstituteNameLength = size_target;
96   data->MountPointReparseBuffer.PrintNameOffset = size_target + 2;
97   data->ReparseDataLength = size_target + 4 + 8;
98
99   int data_size = data->ReparseDataLength + 8;
100
101   if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size,
102                        NULL, 0, &returned, NULL)) {
103     return false;
104   }
105   return true;
106 }
107
108 // Delete the reparse point referenced by |source|. Returns true if the call
109 // succeeds, false otherwise.
110 bool DeleteReparsePoint(HANDLE source) {
111   DWORD returned;
112   REPARSE_DATA_BUFFER data = {0};
113   data.ReparseTag = 0xa0000003;
114   if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0,
115                        &returned, NULL)) {
116     return false;
117   }
118   return true;
119 }
120
121 // Manages a reparse point for a test.
122 class ReparsePoint {
123  public:
124   // Creates a reparse point from |source| (an empty directory) to |target|.
125   ReparsePoint(const FilePath& source, const FilePath& target) {
126     dir_.Set(
127       ::CreateFile(source.value().c_str(),
128                    FILE_ALL_ACCESS,
129                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
130                    NULL,
131                    OPEN_EXISTING,
132                    FILE_FLAG_BACKUP_SEMANTICS,  // Needed to open a directory.
133                    NULL));
134     created_ = dir_.IsValid() && SetReparsePoint(dir_, target);
135   }
136
137   ~ReparsePoint() {
138     if (created_)
139       DeleteReparsePoint(dir_);
140   }
141
142   bool IsValid() { return created_; }
143
144  private:
145   base::win::ScopedHandle dir_;
146   bool created_;
147   DISALLOW_COPY_AND_ASSIGN(ReparsePoint);
148 };
149
150 #endif
151
152 #if defined(OS_POSIX)
153 // Provide a simple way to change the permissions bits on |path| in tests.
154 // ASSERT failures will return, but not stop the test.  Caller should wrap
155 // calls to this function in ASSERT_NO_FATAL_FAILURE().
156 void ChangePosixFilePermissions(const FilePath& path,
157                                 int mode_bits_to_set,
158                                 int mode_bits_to_clear) {
159   ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear)
160       << "Can't set and clear the same bits.";
161
162   int mode = 0;
163   ASSERT_TRUE(file_util::GetPosixFilePermissions(path, &mode));
164   mode |= mode_bits_to_set;
165   mode &= ~mode_bits_to_clear;
166   ASSERT_TRUE(file_util::SetPosixFilePermissions(path, mode));
167 }
168 #endif  // defined(OS_POSIX)
169
170 const wchar_t bogus_content[] = L"I'm cannon fodder.";
171
172 const int FILES_AND_DIRECTORIES =
173     FileEnumerator::FILES | FileEnumerator::DIRECTORIES;
174
175 // file_util winds up using autoreleased objects on the Mac, so this needs
176 // to be a PlatformTest
177 class FileUtilTest : public PlatformTest {
178  protected:
179   virtual void SetUp() OVERRIDE {
180     PlatformTest::SetUp();
181     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
182   }
183
184   base::ScopedTempDir temp_dir_;
185 };
186
187 // Collects all the results from the given file enumerator, and provides an
188 // interface to query whether a given file is present.
189 class FindResultCollector {
190  public:
191   explicit FindResultCollector(FileEnumerator& enumerator) {
192     FilePath cur_file;
193     while (!(cur_file = enumerator.Next()).value().empty()) {
194       FilePath::StringType path = cur_file.value();
195       // The file should not be returned twice.
196       EXPECT_TRUE(files_.end() == files_.find(path))
197           << "Same file returned twice";
198
199       // Save for later.
200       files_.insert(path);
201     }
202   }
203
204   // Returns true if the enumerator found the file.
205   bool HasFile(const FilePath& file) const {
206     return files_.find(file.value()) != files_.end();
207   }
208
209   int size() {
210     return static_cast<int>(files_.size());
211   }
212
213  private:
214   std::set<FilePath::StringType> files_;
215 };
216
217 // Simple function to dump some text into a new file.
218 void CreateTextFile(const FilePath& filename,
219                     const std::wstring& contents) {
220   std::wofstream file;
221   file.open(filename.value().c_str());
222   ASSERT_TRUE(file.is_open());
223   file << contents;
224   file.close();
225 }
226
227 // Simple function to take out some text from a file.
228 std::wstring ReadTextFile(const FilePath& filename) {
229   wchar_t contents[64];
230   std::wifstream file;
231   file.open(filename.value().c_str());
232   EXPECT_TRUE(file.is_open());
233   file.getline(contents, arraysize(contents));
234   file.close();
235   return std::wstring(contents);
236 }
237
238 #if defined(OS_WIN)
239 uint64 FileTimeAsUint64(const FILETIME& ft) {
240   ULARGE_INTEGER u;
241   u.LowPart = ft.dwLowDateTime;
242   u.HighPart = ft.dwHighDateTime;
243   return u.QuadPart;
244 }
245 #endif
246
247 TEST_F(FileUtilTest, FileAndDirectorySize) {
248   // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize
249   // should return 53 bytes.
250   FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt"));
251   CreateTextFile(file_01, L"12345678901234567890");
252   int64 size_f1 = 0;
253   ASSERT_TRUE(file_util::GetFileSize(file_01, &size_f1));
254   EXPECT_EQ(20ll, size_f1);
255
256   FilePath subdir_path = temp_dir_.path().Append(FPL("Level2"));
257   file_util::CreateDirectory(subdir_path);
258
259   FilePath file_02 = subdir_path.Append(FPL("The file 02.txt"));
260   CreateTextFile(file_02, L"123456789012345678901234567890");
261   int64 size_f2 = 0;
262   ASSERT_TRUE(file_util::GetFileSize(file_02, &size_f2));
263   EXPECT_EQ(30ll, size_f2);
264
265   FilePath subsubdir_path = subdir_path.Append(FPL("Level3"));
266   file_util::CreateDirectory(subsubdir_path);
267
268   FilePath file_03 = subsubdir_path.Append(FPL("The file 03.txt"));
269   CreateTextFile(file_03, L"123");
270
271   int64 computed_size = base::ComputeDirectorySize(temp_dir_.path());
272   EXPECT_EQ(size_f1 + size_f2 + 3, computed_size);
273 }
274
275 TEST_F(FileUtilTest, NormalizeFilePathBasic) {
276   // Create a directory under the test dir.  Because we create it,
277   // we know it is not a link.
278   FilePath file_a_path = temp_dir_.path().Append(FPL("file_a"));
279   FilePath dir_path = temp_dir_.path().Append(FPL("dir"));
280   FilePath file_b_path = dir_path.Append(FPL("file_b"));
281   file_util::CreateDirectory(dir_path);
282
283   FilePath normalized_file_a_path, normalized_file_b_path;
284   ASSERT_FALSE(base::PathExists(file_a_path));
285   ASSERT_FALSE(file_util::NormalizeFilePath(file_a_path,
286                                             &normalized_file_a_path))
287     << "NormalizeFilePath() should fail on nonexistent paths.";
288
289   CreateTextFile(file_a_path, bogus_content);
290   ASSERT_TRUE(base::PathExists(file_a_path));
291   ASSERT_TRUE(file_util::NormalizeFilePath(file_a_path,
292                                            &normalized_file_a_path));
293
294   CreateTextFile(file_b_path, bogus_content);
295   ASSERT_TRUE(base::PathExists(file_b_path));
296   ASSERT_TRUE(file_util::NormalizeFilePath(file_b_path,
297                                            &normalized_file_b_path));
298
299   // Beacuse this test created |dir_path|, we know it is not a link
300   // or junction.  So, the real path of the directory holding file a
301   // must be the parent of the path holding file b.
302   ASSERT_TRUE(normalized_file_a_path.DirName()
303       .IsParent(normalized_file_b_path.DirName()));
304 }
305
306 #if defined(OS_WIN)
307
308 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) {
309   // Build the following directory structure:
310   //
311   // temp_dir
312   // |-> base_a
313   // |   |-> sub_a
314   // |       |-> file.txt
315   // |       |-> long_name___... (Very long name.)
316   // |           |-> sub_long
317   // |              |-> deep.txt
318   // |-> base_b
319   //     |-> to_sub_a (reparse point to temp_dir\base_a\sub_a)
320   //     |-> to_base_b (reparse point to temp_dir\base_b)
321   //     |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long)
322
323   FilePath base_a = temp_dir_.path().Append(FPL("base_a"));
324   ASSERT_TRUE(file_util::CreateDirectory(base_a));
325
326   FilePath sub_a = base_a.Append(FPL("sub_a"));
327   ASSERT_TRUE(file_util::CreateDirectory(sub_a));
328
329   FilePath file_txt = sub_a.Append(FPL("file.txt"));
330   CreateTextFile(file_txt, bogus_content);
331
332   // Want a directory whose name is long enough to make the path to the file
333   // inside just under MAX_PATH chars.  This will be used to test that when
334   // a junction expands to a path over MAX_PATH chars in length,
335   // NormalizeFilePath() fails without crashing.
336   FilePath sub_long_rel(FPL("sub_long"));
337   FilePath deep_txt(FPL("deep.txt"));
338
339   int target_length = MAX_PATH;
340   target_length -= (sub_a.value().length() + 1);  // +1 for the sepperator '\'.
341   target_length -= (sub_long_rel.Append(deep_txt).value().length() + 1);
342   // Without making the path a bit shorter, CreateDirectory() fails.
343   // the resulting path is still long enough to hit the failing case in
344   // NormalizePath().
345   const int kCreateDirLimit = 4;
346   target_length -= kCreateDirLimit;
347   FilePath::StringType long_name_str = FPL("long_name_");
348   long_name_str.resize(target_length, '_');
349
350   FilePath long_name = sub_a.Append(FilePath(long_name_str));
351   FilePath deep_file = long_name.Append(sub_long_rel).Append(deep_txt);
352   ASSERT_EQ(MAX_PATH - kCreateDirLimit, deep_file.value().length());
353
354   FilePath sub_long = deep_file.DirName();
355   ASSERT_TRUE(file_util::CreateDirectory(sub_long));
356   CreateTextFile(deep_file, bogus_content);
357
358   FilePath base_b = temp_dir_.path().Append(FPL("base_b"));
359   ASSERT_TRUE(file_util::CreateDirectory(base_b));
360
361   FilePath to_sub_a = base_b.Append(FPL("to_sub_a"));
362   ASSERT_TRUE(file_util::CreateDirectory(to_sub_a));
363   FilePath normalized_path;
364   {
365     ReparsePoint reparse_to_sub_a(to_sub_a, sub_a);
366     ASSERT_TRUE(reparse_to_sub_a.IsValid());
367
368     FilePath to_base_b = base_b.Append(FPL("to_base_b"));
369     ASSERT_TRUE(file_util::CreateDirectory(to_base_b));
370     ReparsePoint reparse_to_base_b(to_base_b, base_b);
371     ASSERT_TRUE(reparse_to_base_b.IsValid());
372
373     FilePath to_sub_long = base_b.Append(FPL("to_sub_long"));
374     ASSERT_TRUE(file_util::CreateDirectory(to_sub_long));
375     ReparsePoint reparse_to_sub_long(to_sub_long, sub_long);
376     ASSERT_TRUE(reparse_to_sub_long.IsValid());
377
378     // Normalize a junction free path: base_a\sub_a\file.txt .
379     ASSERT_TRUE(file_util::NormalizeFilePath(file_txt, &normalized_path));
380     ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str());
381
382     // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude
383     // the junction to_sub_a.
384     ASSERT_TRUE(file_util::NormalizeFilePath(to_sub_a.Append(FPL("file.txt")),
385                                              &normalized_path));
386     ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str());
387
388     // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be
389     // normalized to exclude junctions to_base_b and to_sub_a .
390     ASSERT_TRUE(file_util::NormalizeFilePath(base_b.Append(FPL("to_base_b"))
391                                                    .Append(FPL("to_base_b"))
392                                                    .Append(FPL("to_sub_a"))
393                                                    .Append(FPL("file.txt")),
394                                              &normalized_path));
395     ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str());
396
397     // A long enough path will cause NormalizeFilePath() to fail.  Make a long
398     // path using to_base_b many times, and check that paths long enough to fail
399     // do not cause a crash.
400     FilePath long_path = base_b;
401     const int kLengthLimit = MAX_PATH + 200;
402     while (long_path.value().length() <= kLengthLimit) {
403       long_path = long_path.Append(FPL("to_base_b"));
404     }
405     long_path = long_path.Append(FPL("to_sub_a"))
406                          .Append(FPL("file.txt"));
407
408     ASSERT_FALSE(file_util::NormalizeFilePath(long_path, &normalized_path));
409
410     // Normalizing the junction to deep.txt should fail, because the expanded
411     // path to deep.txt is longer than MAX_PATH.
412     ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_long.Append(deep_txt),
413                                               &normalized_path));
414
415     // Delete the reparse points, and see that NormalizeFilePath() fails
416     // to traverse them.
417   }
418
419   ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_a.Append(FPL("file.txt")),
420                                             &normalized_path));
421 }
422
423 TEST_F(FileUtilTest, DevicePathToDriveLetter) {
424   // Get a drive letter.
425   std::wstring real_drive_letter = temp_dir_.path().value().substr(0, 2);
426   if (!isalpha(real_drive_letter[0]) || ':' != real_drive_letter[1]) {
427     LOG(ERROR) << "Can't get a drive letter to test with.";
428     return;
429   }
430
431   // Get the NT style path to that drive.
432   wchar_t device_path[MAX_PATH] = {'\0'};
433   ASSERT_TRUE(
434       ::QueryDosDevice(real_drive_letter.c_str(), device_path, MAX_PATH));
435   FilePath actual_device_path(device_path);
436   FilePath win32_path;
437
438   // Run DevicePathToDriveLetterPath() on the NT style path we got from
439   // QueryDosDevice().  Expect the drive letter we started with.
440   ASSERT_TRUE(file_util::DevicePathToDriveLetterPath(actual_device_path,
441                                                      &win32_path));
442   ASSERT_EQ(real_drive_letter, win32_path.value());
443
444   // Add some directories to the path.  Expect those extra path componenets
445   // to be preserved.
446   FilePath kRelativePath(FPL("dir1\\dir2\\file.txt"));
447   ASSERT_TRUE(file_util::DevicePathToDriveLetterPath(
448       actual_device_path.Append(kRelativePath),
449       &win32_path));
450   EXPECT_EQ(FilePath(real_drive_letter + L"\\").Append(kRelativePath).value(),
451             win32_path.value());
452
453   // Deform the real path so that it is invalid by removing the last four
454   // characters.  The way windows names devices that are hard disks
455   // (\Device\HardDiskVolume${NUMBER}) guarantees that the string is longer
456   // than three characters.  The only way the truncated string could be a
457   // real drive is if more than 10^3 disks are mounted:
458   // \Device\HardDiskVolume10000 would be truncated to \Device\HardDiskVolume1
459   // Check that DevicePathToDriveLetterPath fails.
460   int path_length = actual_device_path.value().length();
461   int new_length = path_length - 4;
462   ASSERT_LT(0, new_length);
463   FilePath prefix_of_real_device_path(
464       actual_device_path.value().substr(0, new_length));
465   ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
466       prefix_of_real_device_path,
467       &win32_path));
468
469   ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
470       prefix_of_real_device_path.Append(kRelativePath),
471       &win32_path));
472
473   // Deform the real path so that it is invalid by adding some characters. For
474   // example, if C: maps to \Device\HardDiskVolume8, then we simulate a
475   // request for the drive letter whose native path is
476   // \Device\HardDiskVolume812345 .  We assume such a device does not exist,
477   // because drives are numbered in order and mounting 112345 hard disks will
478   // never happen.
479   const FilePath::StringType kExtraChars = FPL("12345");
480
481   FilePath real_device_path_plus_numbers(
482       actual_device_path.value() + kExtraChars);
483
484   ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
485       real_device_path_plus_numbers,
486       &win32_path));
487
488   ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
489       real_device_path_plus_numbers.Append(kRelativePath),
490       &win32_path));
491 }
492
493 TEST_F(FileUtilTest, GetPlatformFileInfoForDirectory) {
494   FilePath empty_dir = temp_dir_.path().Append(FPL("gpfi_test"));
495   ASSERT_TRUE(file_util::CreateDirectory(empty_dir));
496   base::win::ScopedHandle dir(
497       ::CreateFile(empty_dir.value().c_str(),
498                    FILE_ALL_ACCESS,
499                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
500                    NULL,
501                    OPEN_EXISTING,
502                    FILE_FLAG_BACKUP_SEMANTICS,  // Needed to open a directory.
503                    NULL));
504   ASSERT_TRUE(dir.IsValid());
505   base::PlatformFileInfo info;
506   EXPECT_TRUE(base::GetPlatformFileInfo(dir.Get(), &info));
507   EXPECT_TRUE(info.is_directory);
508   EXPECT_FALSE(info.is_symbolic_link);
509   EXPECT_EQ(0, info.size);
510 }
511
512 TEST_F(FileUtilTest, CreateTemporaryFileInDirLongPathTest) {
513   // Test that CreateTemporaryFileInDir() creates a path and returns a long path
514   // if it is available. This test requires that:
515   // - the filesystem at |temp_dir_| supports long filenames.
516   // - the account has FILE_LIST_DIRECTORY permission for all ancestor
517   //   directories of |temp_dir_|.
518   const FilePath::CharType kLongDirName[] = FPL("A long path");
519   const FilePath::CharType kTestSubDirName[] = FPL("test");
520   FilePath long_test_dir = temp_dir_.path().Append(kLongDirName);
521   ASSERT_TRUE(file_util::CreateDirectory(long_test_dir));
522
523   // kLongDirName is not a 8.3 component. So GetShortName() should give us a
524   // different short name.
525   WCHAR path_buffer[MAX_PATH];
526   DWORD path_buffer_length = GetShortPathName(long_test_dir.value().c_str(),
527                                               path_buffer, MAX_PATH);
528   ASSERT_LT(path_buffer_length, DWORD(MAX_PATH));
529   ASSERT_NE(DWORD(0), path_buffer_length);
530   FilePath short_test_dir(path_buffer);
531   ASSERT_STRNE(kLongDirName, short_test_dir.BaseName().value().c_str());
532
533   FilePath temp_file;
534   ASSERT_TRUE(file_util::CreateTemporaryFileInDir(short_test_dir, &temp_file));
535   EXPECT_STREQ(kLongDirName, temp_file.DirName().BaseName().value().c_str());
536   EXPECT_TRUE(base::PathExists(temp_file));
537
538   // Create a subdirectory of |long_test_dir| and make |long_test_dir|
539   // unreadable. We should still be able to create a temp file in the
540   // subdirectory, but we won't be able to determine the long path for it. This
541   // mimics the environment that some users run where their user profiles reside
542   // in a location where the don't have full access to the higher level
543   // directories. (Note that this assumption is true for NTFS, but not for some
544   // network file systems. E.g. AFS).
545   FilePath access_test_dir = long_test_dir.Append(kTestSubDirName);
546   ASSERT_TRUE(file_util::CreateDirectory(access_test_dir));
547   file_util::PermissionRestorer long_test_dir_restorer(long_test_dir);
548   ASSERT_TRUE(file_util::MakeFileUnreadable(long_test_dir));
549
550   // Use the short form of the directory to create a temporary filename.
551   ASSERT_TRUE(file_util::CreateTemporaryFileInDir(
552       short_test_dir.Append(kTestSubDirName), &temp_file));
553   EXPECT_TRUE(base::PathExists(temp_file));
554   EXPECT_TRUE(short_test_dir.IsParent(temp_file.DirName()));
555
556   // Check that the long path can't be determined for |temp_file|.
557   path_buffer_length = GetLongPathName(temp_file.value().c_str(),
558                                        path_buffer, MAX_PATH);
559   EXPECT_EQ(DWORD(0), path_buffer_length);
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 contents
575   // through it.
576   std::wstring contents = ReadTextFile(link_from);
577   EXPECT_EQ(bogus_content, contents);
578
579   FilePath result;
580   ASSERT_TRUE(file_util::ReadSymbolicLink(link_from, &result));
581   EXPECT_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   ASSERT_TRUE(file_util::CreateDirectory(link_to));
587   ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from))
588     << "Failed to create directory symlink.";
589
590   // Test failures.
591   EXPECT_FALSE(file_util::CreateSymbolicLink(link_to, link_to));
592   EXPECT_FALSE(file_util::ReadSymbolicLink(link_to, &result));
593   FilePath missing = temp_dir_.path().Append(FPL("missing"));
594   EXPECT_FALSE(file_util::ReadSymbolicLink(missing, &result));
595 }
596
597 // The following test of NormalizeFilePath() require that we create a symlink.
598 // This can not be done on Windows before Vista.  On Vista, creating a symlink
599 // requires privilege "SeCreateSymbolicLinkPrivilege".
600 // TODO(skerner): Investigate the possibility of giving base_unittests the
601 // privileges required to create a symlink.
602 TEST_F(FileUtilTest, NormalizeFilePathSymlinks) {
603   // Link one file to another.
604   FilePath link_from = temp_dir_.path().Append(FPL("from_file"));
605   FilePath link_to = temp_dir_.path().Append(FPL("to_file"));
606   CreateTextFile(link_to, bogus_content);
607
608   ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from))
609     << "Failed to create file symlink.";
610
611   // Check that NormalizeFilePath sees the link.
612   FilePath normalized_path;
613   ASSERT_TRUE(file_util::NormalizeFilePath(link_from, &normalized_path));
614   EXPECT_NE(link_from, link_to);
615   EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value());
616   EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value());
617
618   // Link to a directory.
619   link_from = temp_dir_.path().Append(FPL("from_dir"));
620   link_to = temp_dir_.path().Append(FPL("to_dir"));
621   ASSERT_TRUE(file_util::CreateDirectory(link_to));
622   ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from))
623     << "Failed to create directory symlink.";
624
625   EXPECT_FALSE(file_util::NormalizeFilePath(link_from, &normalized_path))
626     << "Links to directories should return false.";
627
628   // Test that a loop in the links causes NormalizeFilePath() to return false.
629   link_from = temp_dir_.path().Append(FPL("link_a"));
630   link_to = temp_dir_.path().Append(FPL("link_b"));
631   ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from))
632     << "Failed to create loop symlink a.";
633   ASSERT_TRUE(file_util::CreateSymbolicLink(link_from, link_to))
634     << "Failed to create loop symlink b.";
635
636   // Infinite loop!
637   EXPECT_FALSE(file_util::NormalizeFilePath(link_from, &normalized_path));
638 }
639 #endif  // defined(OS_POSIX)
640
641 TEST_F(FileUtilTest, DeleteNonExistent) {
642   FilePath non_existent = temp_dir_.path().AppendASCII("bogus_file_dne.foobar");
643   ASSERT_FALSE(base::PathExists(non_existent));
644
645   EXPECT_TRUE(base::DeleteFile(non_existent, false));
646   ASSERT_FALSE(base::PathExists(non_existent));
647   EXPECT_TRUE(base::DeleteFile(non_existent, true));
648   ASSERT_FALSE(base::PathExists(non_existent));
649 }
650
651 TEST_F(FileUtilTest, DeleteFile) {
652   // Create a file
653   FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 1.txt"));
654   CreateTextFile(file_name, bogus_content);
655   ASSERT_TRUE(base::PathExists(file_name));
656
657   // Make sure it's deleted
658   EXPECT_TRUE(base::DeleteFile(file_name, false));
659   EXPECT_FALSE(base::PathExists(file_name));
660
661   // Test recursive case, create a new file
662   file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt"));
663   CreateTextFile(file_name, bogus_content);
664   ASSERT_TRUE(base::PathExists(file_name));
665
666   // Make sure it's deleted
667   EXPECT_TRUE(base::DeleteFile(file_name, true));
668   EXPECT_FALSE(base::PathExists(file_name));
669 }
670
671 #if defined(OS_POSIX)
672 TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) {
673   // Create a file.
674   FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt"));
675   CreateTextFile(file_name, bogus_content);
676   ASSERT_TRUE(base::PathExists(file_name));
677
678   // Create a symlink to the file.
679   FilePath file_link = temp_dir_.path().Append("file_link_2");
680   ASSERT_TRUE(file_util::CreateSymbolicLink(file_name, file_link))
681       << "Failed to create symlink.";
682
683   // Delete the symbolic link.
684   EXPECT_TRUE(base::DeleteFile(file_link, false));
685
686   // Make sure original file is not deleted.
687   EXPECT_FALSE(base::PathExists(file_link));
688   EXPECT_TRUE(base::PathExists(file_name));
689 }
690
691 TEST_F(FileUtilTest, DeleteSymlinkToNonExistentFile) {
692   // Create a non-existent file path.
693   FilePath non_existent = temp_dir_.path().Append(FPL("Test DeleteFile 3.txt"));
694   EXPECT_FALSE(base::PathExists(non_existent));
695
696   // Create a symlink to the non-existent file.
697   FilePath file_link = temp_dir_.path().Append("file_link_3");
698   ASSERT_TRUE(file_util::CreateSymbolicLink(non_existent, file_link))
699       << "Failed to create symlink.";
700
701   // Make sure the symbolic link is exist.
702   EXPECT_TRUE(file_util::IsLink(file_link));
703   EXPECT_FALSE(base::PathExists(file_link));
704
705   // Delete the symbolic link.
706   EXPECT_TRUE(base::DeleteFile(file_link, false));
707
708   // Make sure the symbolic link is deleted.
709   EXPECT_FALSE(file_util::IsLink(file_link));
710 }
711
712 TEST_F(FileUtilTest, ChangeFilePermissionsAndRead) {
713   // Create a file path.
714   FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt"));
715   EXPECT_FALSE(base::PathExists(file_name));
716
717   const std::string kData("hello");
718
719   int buffer_size = kData.length();
720   char* buffer = new char[buffer_size];
721
722   // Write file.
723   EXPECT_EQ(static_cast<int>(kData.length()),
724             file_util::WriteFile(file_name, kData.data(), kData.length()));
725   EXPECT_TRUE(base::PathExists(file_name));
726
727   // Make sure the file is readable.
728   int32 mode = 0;
729   EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode));
730   EXPECT_TRUE(mode & file_util::FILE_PERMISSION_READ_BY_USER);
731
732   // Get rid of the read permission.
733   EXPECT_TRUE(file_util::SetPosixFilePermissions(file_name, 0u));
734   EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode));
735   EXPECT_FALSE(mode & file_util::FILE_PERMISSION_READ_BY_USER);
736   // Make sure the file can't be read.
737   EXPECT_EQ(-1, file_util::ReadFile(file_name, buffer, buffer_size));
738
739   // Give the read permission.
740   EXPECT_TRUE(file_util::SetPosixFilePermissions(
741       file_name,
742       file_util::FILE_PERMISSION_READ_BY_USER));
743   EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode));
744   EXPECT_TRUE(mode & file_util::FILE_PERMISSION_READ_BY_USER);
745   // Make sure the file can be read.
746   EXPECT_EQ(static_cast<int>(kData.length()),
747             file_util::ReadFile(file_name, buffer, buffer_size));
748
749   // Delete the file.
750   EXPECT_TRUE(base::DeleteFile(file_name, false));
751   EXPECT_FALSE(base::PathExists(file_name));
752
753   delete[] buffer;
754 }
755
756 TEST_F(FileUtilTest, ChangeFilePermissionsAndWrite) {
757   // Create a file path.
758   FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt"));
759   EXPECT_FALSE(base::PathExists(file_name));
760
761   const std::string kData("hello");
762
763   // Write file.
764   EXPECT_EQ(static_cast<int>(kData.length()),
765             file_util::WriteFile(file_name, kData.data(), kData.length()));
766   EXPECT_TRUE(base::PathExists(file_name));
767
768   // Make sure the file is writable.
769   int mode = 0;
770   EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode));
771   EXPECT_TRUE(mode & file_util::FILE_PERMISSION_WRITE_BY_USER);
772   EXPECT_TRUE(PathIsWritable(file_name));
773
774   // Get rid of the write permission.
775   EXPECT_TRUE(file_util::SetPosixFilePermissions(file_name, 0u));
776   EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode));
777   EXPECT_FALSE(mode & file_util::FILE_PERMISSION_WRITE_BY_USER);
778   // Make sure the file can't be write.
779   EXPECT_EQ(-1,
780             file_util::WriteFile(file_name, kData.data(), kData.length()));
781   EXPECT_FALSE(PathIsWritable(file_name));
782
783   // Give read permission.
784   EXPECT_TRUE(file_util::SetPosixFilePermissions(
785       file_name,
786       file_util::FILE_PERMISSION_WRITE_BY_USER));
787   EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode));
788   EXPECT_TRUE(mode & file_util::FILE_PERMISSION_WRITE_BY_USER);
789   // Make sure the file can be write.
790   EXPECT_EQ(static_cast<int>(kData.length()),
791             file_util::WriteFile(file_name, kData.data(), kData.length()));
792   EXPECT_TRUE(PathIsWritable(file_name));
793
794   // Delete the file.
795   EXPECT_TRUE(base::DeleteFile(file_name, false));
796   EXPECT_FALSE(base::PathExists(file_name));
797 }
798
799 TEST_F(FileUtilTest, ChangeDirectoryPermissionsAndEnumerate) {
800   // Create a directory path.
801   FilePath subdir_path =
802       temp_dir_.path().Append(FPL("PermissionTest1"));
803   file_util::CreateDirectory(subdir_path);
804   ASSERT_TRUE(base::PathExists(subdir_path));
805
806   // Create a dummy file to enumerate.
807   FilePath file_name = subdir_path.Append(FPL("Test Readable File.txt"));
808   EXPECT_FALSE(base::PathExists(file_name));
809   const std::string kData("hello");
810   EXPECT_EQ(static_cast<int>(kData.length()),
811             file_util::WriteFile(file_name, kData.data(), kData.length()));
812   EXPECT_TRUE(base::PathExists(file_name));
813
814   // Make sure the directory has the all permissions.
815   int mode = 0;
816   EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path, &mode));
817   EXPECT_EQ(file_util::FILE_PERMISSION_USER_MASK,
818             mode & file_util::FILE_PERMISSION_USER_MASK);
819
820   // Get rid of the permissions from the directory.
821   EXPECT_TRUE(file_util::SetPosixFilePermissions(subdir_path, 0u));
822   EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path, &mode));
823   EXPECT_FALSE(mode & file_util::FILE_PERMISSION_USER_MASK);
824
825   // Make sure the file in the directory can't be enumerated.
826   FileEnumerator f1(subdir_path, true, FileEnumerator::FILES);
827   EXPECT_TRUE(base::PathExists(subdir_path));
828   FindResultCollector c1(f1);
829   EXPECT_EQ(c1.size(), 0);
830   EXPECT_FALSE(file_util::GetPosixFilePermissions(file_name, &mode));
831
832   // Give the permissions to the directory.
833   EXPECT_TRUE(file_util::SetPosixFilePermissions(
834       subdir_path,
835       file_util::FILE_PERMISSION_USER_MASK));
836   EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path, &mode));
837   EXPECT_EQ(file_util::FILE_PERMISSION_USER_MASK,
838             mode & file_util::FILE_PERMISSION_USER_MASK);
839
840   // Make sure the file in the directory can be enumerated.
841   FileEnumerator f2(subdir_path, true, FileEnumerator::FILES);
842   FindResultCollector c2(f2);
843   EXPECT_TRUE(c2.HasFile(file_name));
844   EXPECT_EQ(c2.size(), 1);
845
846   // Delete the file.
847   EXPECT_TRUE(base::DeleteFile(subdir_path, true));
848   EXPECT_FALSE(base::PathExists(subdir_path));
849 }
850
851 #endif  // defined(OS_POSIX)
852
853 #if defined(OS_WIN)
854 // Tests that the Delete function works for wild cards, especially
855 // with the recursion flag.  Also coincidentally tests PathExists.
856 // TODO(erikkay): see if anyone's actually using this feature of the API
857 TEST_F(FileUtilTest, DeleteWildCard) {
858   // Create a file and a directory
859   FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteWildCard.txt"));
860   CreateTextFile(file_name, bogus_content);
861   ASSERT_TRUE(base::PathExists(file_name));
862
863   FilePath subdir_path = temp_dir_.path().Append(FPL("DeleteWildCardDir"));
864   file_util::CreateDirectory(subdir_path);
865   ASSERT_TRUE(base::PathExists(subdir_path));
866
867   // Create the wildcard path
868   FilePath directory_contents = temp_dir_.path();
869   directory_contents = directory_contents.Append(FPL("*"));
870
871   // Delete non-recursively and check that only the file is deleted
872   EXPECT_TRUE(base::DeleteFile(directory_contents, false));
873   EXPECT_FALSE(base::PathExists(file_name));
874   EXPECT_TRUE(base::PathExists(subdir_path));
875
876   // Delete recursively and make sure all contents are deleted
877   EXPECT_TRUE(base::DeleteFile(directory_contents, true));
878   EXPECT_FALSE(base::PathExists(file_name));
879   EXPECT_FALSE(base::PathExists(subdir_path));
880 }
881
882 // TODO(erikkay): see if anyone's actually using this feature of the API
883 TEST_F(FileUtilTest, DeleteNonExistantWildCard) {
884   // Create a file and a directory
885   FilePath subdir_path =
886       temp_dir_.path().Append(FPL("DeleteNonExistantWildCard"));
887   file_util::CreateDirectory(subdir_path);
888   ASSERT_TRUE(base::PathExists(subdir_path));
889
890   // Create the wildcard path
891   FilePath directory_contents = subdir_path;
892   directory_contents = directory_contents.Append(FPL("*"));
893
894   // Delete non-recursively and check nothing got deleted
895   EXPECT_TRUE(base::DeleteFile(directory_contents, false));
896   EXPECT_TRUE(base::PathExists(subdir_path));
897
898   // Delete recursively and check nothing got deleted
899   EXPECT_TRUE(base::DeleteFile(directory_contents, true));
900   EXPECT_TRUE(base::PathExists(subdir_path));
901 }
902 #endif
903
904 // Tests non-recursive Delete() for a directory.
905 TEST_F(FileUtilTest, DeleteDirNonRecursive) {
906   // Create a subdirectory and put a file and two directories inside.
907   FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive"));
908   file_util::CreateDirectory(test_subdir);
909   ASSERT_TRUE(base::PathExists(test_subdir));
910
911   FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt"));
912   CreateTextFile(file_name, bogus_content);
913   ASSERT_TRUE(base::PathExists(file_name));
914
915   FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
916   file_util::CreateDirectory(subdir_path1);
917   ASSERT_TRUE(base::PathExists(subdir_path1));
918
919   FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
920   file_util::CreateDirectory(subdir_path2);
921   ASSERT_TRUE(base::PathExists(subdir_path2));
922
923   // Delete non-recursively and check that the empty dir got deleted
924   EXPECT_TRUE(base::DeleteFile(subdir_path2, false));
925   EXPECT_FALSE(base::PathExists(subdir_path2));
926
927   // Delete non-recursively and check that nothing got deleted
928   EXPECT_FALSE(base::DeleteFile(test_subdir, false));
929   EXPECT_TRUE(base::PathExists(test_subdir));
930   EXPECT_TRUE(base::PathExists(file_name));
931   EXPECT_TRUE(base::PathExists(subdir_path1));
932 }
933
934 // Tests recursive Delete() for a directory.
935 TEST_F(FileUtilTest, DeleteDirRecursive) {
936   // Create a subdirectory and put a file and two directories inside.
937   FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirRecursive"));
938   file_util::CreateDirectory(test_subdir);
939   ASSERT_TRUE(base::PathExists(test_subdir));
940
941   FilePath file_name = test_subdir.Append(FPL("Test DeleteDirRecursive.txt"));
942   CreateTextFile(file_name, bogus_content);
943   ASSERT_TRUE(base::PathExists(file_name));
944
945   FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
946   file_util::CreateDirectory(subdir_path1);
947   ASSERT_TRUE(base::PathExists(subdir_path1));
948
949   FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
950   file_util::CreateDirectory(subdir_path2);
951   ASSERT_TRUE(base::PathExists(subdir_path2));
952
953   // Delete recursively and check that the empty dir got deleted
954   EXPECT_TRUE(base::DeleteFile(subdir_path2, true));
955   EXPECT_FALSE(base::PathExists(subdir_path2));
956
957   // Delete recursively and check that everything got deleted
958   EXPECT_TRUE(base::DeleteFile(test_subdir, true));
959   EXPECT_FALSE(base::PathExists(file_name));
960   EXPECT_FALSE(base::PathExists(subdir_path1));
961   EXPECT_FALSE(base::PathExists(test_subdir));
962 }
963
964 TEST_F(FileUtilTest, MoveFileNew) {
965   // Create a file
966   FilePath file_name_from =
967       temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
968   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
969   ASSERT_TRUE(base::PathExists(file_name_from));
970
971   // The destination.
972   FilePath file_name_to = temp_dir_.path().Append(
973       FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
974   ASSERT_FALSE(base::PathExists(file_name_to));
975
976   EXPECT_TRUE(base::Move(file_name_from, file_name_to));
977
978   // Check everything has been moved.
979   EXPECT_FALSE(base::PathExists(file_name_from));
980   EXPECT_TRUE(base::PathExists(file_name_to));
981 }
982
983 TEST_F(FileUtilTest, MoveFileExists) {
984   // Create a file
985   FilePath file_name_from =
986       temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
987   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
988   ASSERT_TRUE(base::PathExists(file_name_from));
989
990   // The destination name.
991   FilePath file_name_to = temp_dir_.path().Append(
992       FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
993   CreateTextFile(file_name_to, L"Old file content");
994   ASSERT_TRUE(base::PathExists(file_name_to));
995
996   EXPECT_TRUE(base::Move(file_name_from, file_name_to));
997
998   // Check everything has been moved.
999   EXPECT_FALSE(base::PathExists(file_name_from));
1000   EXPECT_TRUE(base::PathExists(file_name_to));
1001   EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
1002 }
1003
1004 TEST_F(FileUtilTest, MoveFileDirExists) {
1005   // Create a file
1006   FilePath file_name_from =
1007       temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1008   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1009   ASSERT_TRUE(base::PathExists(file_name_from));
1010
1011   // The destination directory
1012   FilePath dir_name_to =
1013       temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1014   file_util::CreateDirectory(dir_name_to);
1015   ASSERT_TRUE(base::PathExists(dir_name_to));
1016
1017   EXPECT_FALSE(base::Move(file_name_from, dir_name_to));
1018 }
1019
1020
1021 TEST_F(FileUtilTest, MoveNew) {
1022   // Create a directory
1023   FilePath dir_name_from =
1024       temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1025   file_util::CreateDirectory(dir_name_from);
1026   ASSERT_TRUE(base::PathExists(dir_name_from));
1027
1028   // Create a file under the directory
1029   FilePath txt_file_name(FILE_PATH_LITERAL("Move_Test_File.txt"));
1030   FilePath file_name_from = dir_name_from.Append(txt_file_name);
1031   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1032   ASSERT_TRUE(base::PathExists(file_name_from));
1033
1034   // Move the directory.
1035   FilePath dir_name_to =
1036       temp_dir_.path().Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1037   FilePath file_name_to =
1038       dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1039
1040   ASSERT_FALSE(base::PathExists(dir_name_to));
1041
1042   EXPECT_TRUE(base::Move(dir_name_from, dir_name_to));
1043
1044   // Check everything has been moved.
1045   EXPECT_FALSE(base::PathExists(dir_name_from));
1046   EXPECT_FALSE(base::PathExists(file_name_from));
1047   EXPECT_TRUE(base::PathExists(dir_name_to));
1048   EXPECT_TRUE(base::PathExists(file_name_to));
1049
1050   // Test path traversal.
1051   file_name_from = dir_name_to.Append(txt_file_name);
1052   file_name_to = dir_name_to.Append(FILE_PATH_LITERAL(".."));
1053   file_name_to = file_name_to.Append(txt_file_name);
1054   EXPECT_FALSE(base::Move(file_name_from, file_name_to));
1055   EXPECT_TRUE(base::PathExists(file_name_from));
1056   EXPECT_FALSE(base::PathExists(file_name_to));
1057   EXPECT_TRUE(base::internal::MoveUnsafe(file_name_from, file_name_to));
1058   EXPECT_FALSE(base::PathExists(file_name_from));
1059   EXPECT_TRUE(base::PathExists(file_name_to));
1060 }
1061
1062 TEST_F(FileUtilTest, MoveExist) {
1063   // Create a directory
1064   FilePath dir_name_from =
1065       temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1066   file_util::CreateDirectory(dir_name_from);
1067   ASSERT_TRUE(base::PathExists(dir_name_from));
1068
1069   // Create a file under the directory
1070   FilePath file_name_from =
1071       dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1072   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1073   ASSERT_TRUE(base::PathExists(file_name_from));
1074
1075   // Move the directory
1076   FilePath dir_name_exists =
1077       temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1078
1079   FilePath dir_name_to =
1080       dir_name_exists.Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1081   FilePath file_name_to =
1082       dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1083
1084   // Create the destination directory.
1085   file_util::CreateDirectory(dir_name_exists);
1086   ASSERT_TRUE(base::PathExists(dir_name_exists));
1087
1088   EXPECT_TRUE(base::Move(dir_name_from, dir_name_to));
1089
1090   // Check everything has been moved.
1091   EXPECT_FALSE(base::PathExists(dir_name_from));
1092   EXPECT_FALSE(base::PathExists(file_name_from));
1093   EXPECT_TRUE(base::PathExists(dir_name_to));
1094   EXPECT_TRUE(base::PathExists(file_name_to));
1095 }
1096
1097 TEST_F(FileUtilTest, CopyDirectoryRecursivelyNew) {
1098   // Create a directory.
1099   FilePath dir_name_from =
1100       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1101   file_util::CreateDirectory(dir_name_from);
1102   ASSERT_TRUE(base::PathExists(dir_name_from));
1103
1104   // Create a file under the directory.
1105   FilePath file_name_from =
1106       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1107   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1108   ASSERT_TRUE(base::PathExists(file_name_from));
1109
1110   // Create a subdirectory.
1111   FilePath subdir_name_from =
1112       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1113   file_util::CreateDirectory(subdir_name_from);
1114   ASSERT_TRUE(base::PathExists(subdir_name_from));
1115
1116   // Create a file under the subdirectory.
1117   FilePath file_name2_from =
1118       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1119   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1120   ASSERT_TRUE(base::PathExists(file_name2_from));
1121
1122   // Copy the directory recursively.
1123   FilePath dir_name_to =
1124       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1125   FilePath file_name_to =
1126       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1127   FilePath subdir_name_to =
1128       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1129   FilePath file_name2_to =
1130       subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1131
1132   ASSERT_FALSE(base::PathExists(dir_name_to));
1133
1134   EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_to, true));
1135
1136   // Check everything has been copied.
1137   EXPECT_TRUE(base::PathExists(dir_name_from));
1138   EXPECT_TRUE(base::PathExists(file_name_from));
1139   EXPECT_TRUE(base::PathExists(subdir_name_from));
1140   EXPECT_TRUE(base::PathExists(file_name2_from));
1141   EXPECT_TRUE(base::PathExists(dir_name_to));
1142   EXPECT_TRUE(base::PathExists(file_name_to));
1143   EXPECT_TRUE(base::PathExists(subdir_name_to));
1144   EXPECT_TRUE(base::PathExists(file_name2_to));
1145 }
1146
1147 TEST_F(FileUtilTest, CopyDirectoryRecursivelyExists) {
1148   // Create a directory.
1149   FilePath dir_name_from =
1150       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1151   file_util::CreateDirectory(dir_name_from);
1152   ASSERT_TRUE(base::PathExists(dir_name_from));
1153
1154   // Create a file under the directory.
1155   FilePath file_name_from =
1156       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1157   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1158   ASSERT_TRUE(base::PathExists(file_name_from));
1159
1160   // Create a subdirectory.
1161   FilePath subdir_name_from =
1162       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1163   file_util::CreateDirectory(subdir_name_from);
1164   ASSERT_TRUE(base::PathExists(subdir_name_from));
1165
1166   // Create a file under the subdirectory.
1167   FilePath file_name2_from =
1168       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1169   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1170   ASSERT_TRUE(base::PathExists(file_name2_from));
1171
1172   // Copy the directory recursively.
1173   FilePath dir_name_exists =
1174       temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1175
1176   FilePath dir_name_to =
1177       dir_name_exists.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1178   FilePath file_name_to =
1179       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1180   FilePath subdir_name_to =
1181       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1182   FilePath file_name2_to =
1183       subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1184
1185   // Create the destination directory.
1186   file_util::CreateDirectory(dir_name_exists);
1187   ASSERT_TRUE(base::PathExists(dir_name_exists));
1188
1189   EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_exists, true));
1190
1191   // Check everything has been copied.
1192   EXPECT_TRUE(base::PathExists(dir_name_from));
1193   EXPECT_TRUE(base::PathExists(file_name_from));
1194   EXPECT_TRUE(base::PathExists(subdir_name_from));
1195   EXPECT_TRUE(base::PathExists(file_name2_from));
1196   EXPECT_TRUE(base::PathExists(dir_name_to));
1197   EXPECT_TRUE(base::PathExists(file_name_to));
1198   EXPECT_TRUE(base::PathExists(subdir_name_to));
1199   EXPECT_TRUE(base::PathExists(file_name2_to));
1200 }
1201
1202 TEST_F(FileUtilTest, CopyDirectoryNew) {
1203   // Create a directory.
1204   FilePath dir_name_from =
1205       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1206   file_util::CreateDirectory(dir_name_from);
1207   ASSERT_TRUE(base::PathExists(dir_name_from));
1208
1209   // Create a file under the directory.
1210   FilePath file_name_from =
1211       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1212   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1213   ASSERT_TRUE(base::PathExists(file_name_from));
1214
1215   // Create a subdirectory.
1216   FilePath subdir_name_from =
1217       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1218   file_util::CreateDirectory(subdir_name_from);
1219   ASSERT_TRUE(base::PathExists(subdir_name_from));
1220
1221   // Create a file under the subdirectory.
1222   FilePath file_name2_from =
1223       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1224   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1225   ASSERT_TRUE(base::PathExists(file_name2_from));
1226
1227   // Copy the directory not recursively.
1228   FilePath dir_name_to =
1229       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1230   FilePath file_name_to =
1231       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1232   FilePath subdir_name_to =
1233       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1234
1235   ASSERT_FALSE(base::PathExists(dir_name_to));
1236
1237   EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_to, false));
1238
1239   // Check everything has been copied.
1240   EXPECT_TRUE(base::PathExists(dir_name_from));
1241   EXPECT_TRUE(base::PathExists(file_name_from));
1242   EXPECT_TRUE(base::PathExists(subdir_name_from));
1243   EXPECT_TRUE(base::PathExists(file_name2_from));
1244   EXPECT_TRUE(base::PathExists(dir_name_to));
1245   EXPECT_TRUE(base::PathExists(file_name_to));
1246   EXPECT_FALSE(base::PathExists(subdir_name_to));
1247 }
1248
1249 TEST_F(FileUtilTest, CopyDirectoryExists) {
1250   // Create a directory.
1251   FilePath dir_name_from =
1252       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1253   file_util::CreateDirectory(dir_name_from);
1254   ASSERT_TRUE(base::PathExists(dir_name_from));
1255
1256   // Create a file under the directory.
1257   FilePath file_name_from =
1258       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1259   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1260   ASSERT_TRUE(base::PathExists(file_name_from));
1261
1262   // Create a subdirectory.
1263   FilePath subdir_name_from =
1264       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1265   file_util::CreateDirectory(subdir_name_from);
1266   ASSERT_TRUE(base::PathExists(subdir_name_from));
1267
1268   // Create a file under the subdirectory.
1269   FilePath file_name2_from =
1270       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1271   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1272   ASSERT_TRUE(base::PathExists(file_name2_from));
1273
1274   // Copy the directory not recursively.
1275   FilePath dir_name_to =
1276       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1277   FilePath file_name_to =
1278       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1279   FilePath subdir_name_to =
1280       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1281
1282   // Create the destination directory.
1283   file_util::CreateDirectory(dir_name_to);
1284   ASSERT_TRUE(base::PathExists(dir_name_to));
1285
1286   EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_to, false));
1287
1288   // Check everything has been copied.
1289   EXPECT_TRUE(base::PathExists(dir_name_from));
1290   EXPECT_TRUE(base::PathExists(file_name_from));
1291   EXPECT_TRUE(base::PathExists(subdir_name_from));
1292   EXPECT_TRUE(base::PathExists(file_name2_from));
1293   EXPECT_TRUE(base::PathExists(dir_name_to));
1294   EXPECT_TRUE(base::PathExists(file_name_to));
1295   EXPECT_FALSE(base::PathExists(subdir_name_to));
1296 }
1297
1298 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToNew) {
1299   // Create a file
1300   FilePath file_name_from =
1301       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1302   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1303   ASSERT_TRUE(base::PathExists(file_name_from));
1304
1305   // The destination name
1306   FilePath file_name_to = temp_dir_.path().Append(
1307       FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1308   ASSERT_FALSE(base::PathExists(file_name_to));
1309
1310   EXPECT_TRUE(base::CopyDirectory(file_name_from, file_name_to, true));
1311
1312   // Check the has been copied
1313   EXPECT_TRUE(base::PathExists(file_name_to));
1314 }
1315
1316 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExisting) {
1317   // Create a file
1318   FilePath file_name_from =
1319       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1320   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1321   ASSERT_TRUE(base::PathExists(file_name_from));
1322
1323   // The destination name
1324   FilePath file_name_to = temp_dir_.path().Append(
1325       FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1326   CreateTextFile(file_name_to, L"Old file content");
1327   ASSERT_TRUE(base::PathExists(file_name_to));
1328
1329   EXPECT_TRUE(base::CopyDirectory(file_name_from, file_name_to, true));
1330
1331   // Check the has been copied
1332   EXPECT_TRUE(base::PathExists(file_name_to));
1333   EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
1334 }
1335
1336 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExistingDirectory) {
1337   // Create a file
1338   FilePath file_name_from =
1339       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1340   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1341   ASSERT_TRUE(base::PathExists(file_name_from));
1342
1343   // The destination
1344   FilePath dir_name_to =
1345       temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1346   file_util::CreateDirectory(dir_name_to);
1347   ASSERT_TRUE(base::PathExists(dir_name_to));
1348   FilePath file_name_to =
1349       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1350
1351   EXPECT_TRUE(base::CopyDirectory(file_name_from, dir_name_to, true));
1352
1353   // Check the has been copied
1354   EXPECT_TRUE(base::PathExists(file_name_to));
1355 }
1356
1357 TEST_F(FileUtilTest, CopyDirectoryWithTrailingSeparators) {
1358   // Create a directory.
1359   FilePath dir_name_from =
1360       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1361   file_util::CreateDirectory(dir_name_from);
1362   ASSERT_TRUE(base::PathExists(dir_name_from));
1363
1364   // Create a file under the directory.
1365   FilePath file_name_from =
1366       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1367   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1368   ASSERT_TRUE(base::PathExists(file_name_from));
1369
1370   // Copy the directory recursively.
1371   FilePath dir_name_to =
1372       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1373   FilePath file_name_to =
1374       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1375
1376   // Create from path with trailing separators.
1377 #if defined(OS_WIN)
1378   FilePath from_path =
1379       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir\\\\\\"));
1380 #elif defined (OS_POSIX)
1381   FilePath from_path =
1382       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///"));
1383 #endif
1384
1385   EXPECT_TRUE(base::CopyDirectory(from_path, dir_name_to, true));
1386
1387   // Check everything has been copied.
1388   EXPECT_TRUE(base::PathExists(dir_name_from));
1389   EXPECT_TRUE(base::PathExists(file_name_from));
1390   EXPECT_TRUE(base::PathExists(dir_name_to));
1391   EXPECT_TRUE(base::PathExists(file_name_to));
1392 }
1393
1394 TEST_F(FileUtilTest, CopyFile) {
1395   // Create a directory
1396   FilePath dir_name_from =
1397       temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1398   file_util::CreateDirectory(dir_name_from);
1399   ASSERT_TRUE(base::PathExists(dir_name_from));
1400
1401   // Create a file under the directory
1402   FilePath file_name_from =
1403       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1404   const std::wstring file_contents(L"Gooooooooooooooooooooogle");
1405   CreateTextFile(file_name_from, file_contents);
1406   ASSERT_TRUE(base::PathExists(file_name_from));
1407
1408   // Copy the file.
1409   FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt"));
1410   ASSERT_TRUE(base::CopyFile(file_name_from, dest_file));
1411
1412   // Copy the file to another location using '..' in the path.
1413   FilePath dest_file2(dir_name_from);
1414   dest_file2 = dest_file2.AppendASCII("..");
1415   dest_file2 = dest_file2.AppendASCII("DestFile.txt");
1416   ASSERT_FALSE(base::CopyFile(file_name_from, dest_file2));
1417   ASSERT_TRUE(base::internal::CopyFileUnsafe(file_name_from, dest_file2));
1418
1419   FilePath dest_file2_test(dir_name_from);
1420   dest_file2_test = dest_file2_test.DirName();
1421   dest_file2_test = dest_file2_test.AppendASCII("DestFile.txt");
1422
1423   // Check everything has been copied.
1424   EXPECT_TRUE(base::PathExists(file_name_from));
1425   EXPECT_TRUE(base::PathExists(dest_file));
1426   const std::wstring read_contents = ReadTextFile(dest_file);
1427   EXPECT_EQ(file_contents, read_contents);
1428   EXPECT_TRUE(base::PathExists(dest_file2_test));
1429   EXPECT_TRUE(base::PathExists(dest_file2));
1430 }
1431
1432 // file_util winds up using autoreleased objects on the Mac, so this needs
1433 // to be a PlatformTest.
1434 typedef PlatformTest ReadOnlyFileUtilTest;
1435
1436 TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
1437   FilePath data_dir;
1438   ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir));
1439   data_dir = data_dir.AppendASCII("file_util");
1440   ASSERT_TRUE(base::PathExists(data_dir));
1441
1442   FilePath original_file =
1443       data_dir.Append(FILE_PATH_LITERAL("original.txt"));
1444   FilePath same_file =
1445       data_dir.Append(FILE_PATH_LITERAL("same.txt"));
1446   FilePath same_length_file =
1447       data_dir.Append(FILE_PATH_LITERAL("same_length.txt"));
1448   FilePath different_file =
1449       data_dir.Append(FILE_PATH_LITERAL("different.txt"));
1450   FilePath different_first_file =
1451       data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
1452   FilePath different_last_file =
1453       data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
1454   FilePath empty1_file =
1455       data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
1456   FilePath empty2_file =
1457       data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
1458   FilePath shortened_file =
1459       data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
1460   FilePath binary_file =
1461       data_dir.Append(FILE_PATH_LITERAL("binary_file.bin"));
1462   FilePath binary_file_same =
1463       data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin"));
1464   FilePath binary_file_diff =
1465       data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin"));
1466
1467   EXPECT_TRUE(ContentsEqual(original_file, original_file));
1468   EXPECT_TRUE(ContentsEqual(original_file, same_file));
1469   EXPECT_FALSE(ContentsEqual(original_file, same_length_file));
1470   EXPECT_FALSE(ContentsEqual(original_file, different_file));
1471   EXPECT_FALSE(ContentsEqual(FilePath(FILE_PATH_LITERAL("bogusname")),
1472                              FilePath(FILE_PATH_LITERAL("bogusname"))));
1473   EXPECT_FALSE(ContentsEqual(original_file, different_first_file));
1474   EXPECT_FALSE(ContentsEqual(original_file, different_last_file));
1475   EXPECT_TRUE(ContentsEqual(empty1_file, empty2_file));
1476   EXPECT_FALSE(ContentsEqual(original_file, shortened_file));
1477   EXPECT_FALSE(ContentsEqual(shortened_file, original_file));
1478   EXPECT_TRUE(ContentsEqual(binary_file, binary_file_same));
1479   EXPECT_FALSE(ContentsEqual(binary_file, binary_file_diff));
1480 }
1481
1482 TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) {
1483   FilePath data_dir;
1484   ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir));
1485   data_dir = data_dir.AppendASCII("file_util");
1486   ASSERT_TRUE(base::PathExists(data_dir));
1487
1488   FilePath original_file =
1489       data_dir.Append(FILE_PATH_LITERAL("original.txt"));
1490   FilePath same_file =
1491       data_dir.Append(FILE_PATH_LITERAL("same.txt"));
1492   FilePath crlf_file =
1493       data_dir.Append(FILE_PATH_LITERAL("crlf.txt"));
1494   FilePath shortened_file =
1495       data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
1496   FilePath different_file =
1497       data_dir.Append(FILE_PATH_LITERAL("different.txt"));
1498   FilePath different_first_file =
1499       data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
1500   FilePath different_last_file =
1501       data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
1502   FilePath first1_file =
1503       data_dir.Append(FILE_PATH_LITERAL("first1.txt"));
1504   FilePath first2_file =
1505       data_dir.Append(FILE_PATH_LITERAL("first2.txt"));
1506   FilePath empty1_file =
1507       data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
1508   FilePath empty2_file =
1509       data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
1510   FilePath blank_line_file =
1511       data_dir.Append(FILE_PATH_LITERAL("blank_line.txt"));
1512   FilePath blank_line_crlf_file =
1513       data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt"));
1514
1515   EXPECT_TRUE(TextContentsEqual(original_file, same_file));
1516   EXPECT_TRUE(TextContentsEqual(original_file, crlf_file));
1517   EXPECT_FALSE(TextContentsEqual(original_file, shortened_file));
1518   EXPECT_FALSE(TextContentsEqual(original_file, different_file));
1519   EXPECT_FALSE(TextContentsEqual(original_file, different_first_file));
1520   EXPECT_FALSE(TextContentsEqual(original_file, different_last_file));
1521   EXPECT_FALSE(TextContentsEqual(first1_file, first2_file));
1522   EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file));
1523   EXPECT_FALSE(TextContentsEqual(original_file, empty1_file));
1524   EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file));
1525 }
1526
1527 // We don't need equivalent functionality outside of Windows.
1528 #if defined(OS_WIN)
1529 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) {
1530   // Create a directory
1531   FilePath dir_name_from =
1532       temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir"));
1533   file_util::CreateDirectory(dir_name_from);
1534   ASSERT_TRUE(base::PathExists(dir_name_from));
1535
1536   // Create a file under the directory
1537   FilePath file_name_from =
1538       dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
1539   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1540   ASSERT_TRUE(base::PathExists(file_name_from));
1541
1542   // Move the directory by using CopyAndDeleteDirectory
1543   FilePath dir_name_to = temp_dir_.path().Append(
1544       FILE_PATH_LITERAL("CopyAndDelete_To_Subdir"));
1545   FilePath file_name_to =
1546       dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
1547
1548   ASSERT_FALSE(base::PathExists(dir_name_to));
1549
1550   EXPECT_TRUE(base::internal::CopyAndDeleteDirectory(dir_name_from,
1551                                                      dir_name_to));
1552
1553   // Check everything has been moved.
1554   EXPECT_FALSE(base::PathExists(dir_name_from));
1555   EXPECT_FALSE(base::PathExists(file_name_from));
1556   EXPECT_TRUE(base::PathExists(dir_name_to));
1557   EXPECT_TRUE(base::PathExists(file_name_to));
1558 }
1559
1560 TEST_F(FileUtilTest, GetTempDirTest) {
1561   static const TCHAR* kTmpKey = _T("TMP");
1562   static const TCHAR* kTmpValues[] = {
1563     _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\")
1564   };
1565   // Save the original $TMP.
1566   size_t original_tmp_size;
1567   TCHAR* original_tmp;
1568   ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey));
1569   // original_tmp may be NULL.
1570
1571   for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) {
1572     FilePath path;
1573     ::_tputenv_s(kTmpKey, kTmpValues[i]);
1574     file_util::GetTempDir(&path);
1575     EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] <<
1576         " result=" << path.value();
1577   }
1578
1579   // Restore the original $TMP.
1580   if (original_tmp) {
1581     ::_tputenv_s(kTmpKey, original_tmp);
1582     free(original_tmp);
1583   } else {
1584     ::_tputenv_s(kTmpKey, _T(""));
1585   }
1586 }
1587 #endif  // OS_WIN
1588
1589 TEST_F(FileUtilTest, CreateTemporaryFileTest) {
1590   FilePath temp_files[3];
1591   for (int i = 0; i < 3; i++) {
1592     ASSERT_TRUE(file_util::CreateTemporaryFile(&(temp_files[i])));
1593     EXPECT_TRUE(base::PathExists(temp_files[i]));
1594     EXPECT_FALSE(DirectoryExists(temp_files[i]));
1595   }
1596   for (int i = 0; i < 3; i++)
1597     EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]);
1598   for (int i = 0; i < 3; i++)
1599     EXPECT_TRUE(base::DeleteFile(temp_files[i], false));
1600 }
1601
1602 TEST_F(FileUtilTest, CreateAndOpenTemporaryFileTest) {
1603   FilePath names[3];
1604   FILE* fps[3];
1605   int i;
1606
1607   // Create; make sure they are open and exist.
1608   for (i = 0; i < 3; ++i) {
1609     fps[i] = file_util::CreateAndOpenTemporaryFile(&(names[i]));
1610     ASSERT_TRUE(fps[i]);
1611     EXPECT_TRUE(base::PathExists(names[i]));
1612   }
1613
1614   // Make sure all names are unique.
1615   for (i = 0; i < 3; ++i) {
1616     EXPECT_FALSE(names[i] == names[(i+1)%3]);
1617   }
1618
1619   // Close and delete.
1620   for (i = 0; i < 3; ++i) {
1621     EXPECT_TRUE(file_util::CloseFile(fps[i]));
1622     EXPECT_TRUE(base::DeleteFile(names[i], false));
1623   }
1624 }
1625
1626 TEST_F(FileUtilTest, CreateNewTempDirectoryTest) {
1627   FilePath temp_dir;
1628   ASSERT_TRUE(file_util::CreateNewTempDirectory(FilePath::StringType(),
1629                                                 &temp_dir));
1630   EXPECT_TRUE(base::PathExists(temp_dir));
1631   EXPECT_TRUE(base::DeleteFile(temp_dir, false));
1632 }
1633
1634 TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) {
1635   FilePath new_dir;
1636   ASSERT_TRUE(file_util::CreateTemporaryDirInDir(
1637                   temp_dir_.path(),
1638                   FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"),
1639                   &new_dir));
1640   EXPECT_TRUE(base::PathExists(new_dir));
1641   EXPECT_TRUE(temp_dir_.path().IsParent(new_dir));
1642   EXPECT_TRUE(base::DeleteFile(new_dir, false));
1643 }
1644
1645 TEST_F(FileUtilTest, GetShmemTempDirTest) {
1646   FilePath dir;
1647   EXPECT_TRUE(file_util::GetShmemTempDir(&dir, false));
1648   EXPECT_TRUE(DirectoryExists(dir));
1649 }
1650
1651 TEST_F(FileUtilTest, CreateDirectoryTest) {
1652   FilePath test_root =
1653       temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test"));
1654 #if defined(OS_WIN)
1655   FilePath test_path =
1656       test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\"));
1657 #elif defined(OS_POSIX)
1658   FilePath test_path =
1659       test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/"));
1660 #endif
1661
1662   EXPECT_FALSE(base::PathExists(test_path));
1663   EXPECT_TRUE(file_util::CreateDirectory(test_path));
1664   EXPECT_TRUE(base::PathExists(test_path));
1665   // CreateDirectory returns true if the DirectoryExists returns true.
1666   EXPECT_TRUE(file_util::CreateDirectory(test_path));
1667
1668   // Doesn't work to create it on top of a non-dir
1669   test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt"));
1670   EXPECT_FALSE(base::PathExists(test_path));
1671   CreateTextFile(test_path, L"test file");
1672   EXPECT_TRUE(base::PathExists(test_path));
1673   EXPECT_FALSE(file_util::CreateDirectory(test_path));
1674
1675   EXPECT_TRUE(base::DeleteFile(test_root, true));
1676   EXPECT_FALSE(base::PathExists(test_root));
1677   EXPECT_FALSE(base::PathExists(test_path));
1678
1679   // Verify assumptions made by the Windows implementation:
1680   // 1. The current directory always exists.
1681   // 2. The root directory always exists.
1682   ASSERT_TRUE(DirectoryExists(FilePath(FilePath::kCurrentDirectory)));
1683   FilePath top_level = test_root;
1684   while (top_level != top_level.DirName()) {
1685     top_level = top_level.DirName();
1686   }
1687   ASSERT_TRUE(DirectoryExists(top_level));
1688
1689   // Given these assumptions hold, it should be safe to
1690   // test that "creating" these directories succeeds.
1691   EXPECT_TRUE(file_util::CreateDirectory(
1692       FilePath(FilePath::kCurrentDirectory)));
1693   EXPECT_TRUE(file_util::CreateDirectory(top_level));
1694
1695 #if defined(OS_WIN)
1696   FilePath invalid_drive(FILE_PATH_LITERAL("o:\\"));
1697   FilePath invalid_path =
1698       invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir"));
1699   if (!base::PathExists(invalid_drive)) {
1700     EXPECT_FALSE(file_util::CreateDirectory(invalid_path));
1701   }
1702 #endif
1703 }
1704
1705 TEST_F(FileUtilTest, DetectDirectoryTest) {
1706   // Check a directory
1707   FilePath test_root =
1708       temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test"));
1709   EXPECT_FALSE(base::PathExists(test_root));
1710   EXPECT_TRUE(file_util::CreateDirectory(test_root));
1711   EXPECT_TRUE(base::PathExists(test_root));
1712   EXPECT_TRUE(DirectoryExists(test_root));
1713   // Check a file
1714   FilePath test_path =
1715       test_root.Append(FILE_PATH_LITERAL("foobar.txt"));
1716   EXPECT_FALSE(base::PathExists(test_path));
1717   CreateTextFile(test_path, L"test file");
1718   EXPECT_TRUE(base::PathExists(test_path));
1719   EXPECT_FALSE(DirectoryExists(test_path));
1720   EXPECT_TRUE(base::DeleteFile(test_path, false));
1721
1722   EXPECT_TRUE(base::DeleteFile(test_root, true));
1723 }
1724
1725 TEST_F(FileUtilTest, FileEnumeratorTest) {
1726   // Test an empty directory.
1727   FileEnumerator f0(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1728   EXPECT_EQ(f0.Next().value(), FPL(""));
1729   EXPECT_EQ(f0.Next().value(), FPL(""));
1730
1731   // Test an empty directory, non-recursively, including "..".
1732   FileEnumerator f0_dotdot(temp_dir_.path(), false,
1733       FILES_AND_DIRECTORIES | FileEnumerator::INCLUDE_DOT_DOT);
1734   EXPECT_EQ(temp_dir_.path().Append(FPL("..")).value(),
1735             f0_dotdot.Next().value());
1736   EXPECT_EQ(FPL(""), f0_dotdot.Next().value());
1737
1738   // create the directories
1739   FilePath dir1 = temp_dir_.path().Append(FPL("dir1"));
1740   EXPECT_TRUE(file_util::CreateDirectory(dir1));
1741   FilePath dir2 = temp_dir_.path().Append(FPL("dir2"));
1742   EXPECT_TRUE(file_util::CreateDirectory(dir2));
1743   FilePath dir2inner = dir2.Append(FPL("inner"));
1744   EXPECT_TRUE(file_util::CreateDirectory(dir2inner));
1745
1746   // create the files
1747   FilePath dir2file = dir2.Append(FPL("dir2file.txt"));
1748   CreateTextFile(dir2file, std::wstring());
1749   FilePath dir2innerfile = dir2inner.Append(FPL("innerfile.txt"));
1750   CreateTextFile(dir2innerfile, std::wstring());
1751   FilePath file1 = temp_dir_.path().Append(FPL("file1.txt"));
1752   CreateTextFile(file1, std::wstring());
1753   FilePath file2_rel = dir2.Append(FilePath::kParentDirectory)
1754       .Append(FPL("file2.txt"));
1755   CreateTextFile(file2_rel, std::wstring());
1756   FilePath file2_abs = temp_dir_.path().Append(FPL("file2.txt"));
1757
1758   // Only enumerate files.
1759   FileEnumerator f1(temp_dir_.path(), true, FileEnumerator::FILES);
1760   FindResultCollector c1(f1);
1761   EXPECT_TRUE(c1.HasFile(file1));
1762   EXPECT_TRUE(c1.HasFile(file2_abs));
1763   EXPECT_TRUE(c1.HasFile(dir2file));
1764   EXPECT_TRUE(c1.HasFile(dir2innerfile));
1765   EXPECT_EQ(c1.size(), 4);
1766
1767   // Only enumerate directories.
1768   FileEnumerator f2(temp_dir_.path(), true, FileEnumerator::DIRECTORIES);
1769   FindResultCollector c2(f2);
1770   EXPECT_TRUE(c2.HasFile(dir1));
1771   EXPECT_TRUE(c2.HasFile(dir2));
1772   EXPECT_TRUE(c2.HasFile(dir2inner));
1773   EXPECT_EQ(c2.size(), 3);
1774
1775   // Only enumerate directories non-recursively.
1776   FileEnumerator f2_non_recursive(
1777       temp_dir_.path(), false, FileEnumerator::DIRECTORIES);
1778   FindResultCollector c2_non_recursive(f2_non_recursive);
1779   EXPECT_TRUE(c2_non_recursive.HasFile(dir1));
1780   EXPECT_TRUE(c2_non_recursive.HasFile(dir2));
1781   EXPECT_EQ(c2_non_recursive.size(), 2);
1782
1783   // Only enumerate directories, non-recursively, including "..".
1784   FileEnumerator f2_dotdot(temp_dir_.path(), false,
1785                            FileEnumerator::DIRECTORIES |
1786                            FileEnumerator::INCLUDE_DOT_DOT);
1787   FindResultCollector c2_dotdot(f2_dotdot);
1788   EXPECT_TRUE(c2_dotdot.HasFile(dir1));
1789   EXPECT_TRUE(c2_dotdot.HasFile(dir2));
1790   EXPECT_TRUE(c2_dotdot.HasFile(temp_dir_.path().Append(FPL(".."))));
1791   EXPECT_EQ(c2_dotdot.size(), 3);
1792
1793   // Enumerate files and directories.
1794   FileEnumerator f3(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1795   FindResultCollector c3(f3);
1796   EXPECT_TRUE(c3.HasFile(dir1));
1797   EXPECT_TRUE(c3.HasFile(dir2));
1798   EXPECT_TRUE(c3.HasFile(file1));
1799   EXPECT_TRUE(c3.HasFile(file2_abs));
1800   EXPECT_TRUE(c3.HasFile(dir2file));
1801   EXPECT_TRUE(c3.HasFile(dir2inner));
1802   EXPECT_TRUE(c3.HasFile(dir2innerfile));
1803   EXPECT_EQ(c3.size(), 7);
1804
1805   // Non-recursive operation.
1806   FileEnumerator f4(temp_dir_.path(), false, FILES_AND_DIRECTORIES);
1807   FindResultCollector c4(f4);
1808   EXPECT_TRUE(c4.HasFile(dir2));
1809   EXPECT_TRUE(c4.HasFile(dir2));
1810   EXPECT_TRUE(c4.HasFile(file1));
1811   EXPECT_TRUE(c4.HasFile(file2_abs));
1812   EXPECT_EQ(c4.size(), 4);
1813
1814   // Enumerate with a pattern.
1815   FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*"));
1816   FindResultCollector c5(f5);
1817   EXPECT_TRUE(c5.HasFile(dir1));
1818   EXPECT_TRUE(c5.HasFile(dir2));
1819   EXPECT_TRUE(c5.HasFile(dir2file));
1820   EXPECT_TRUE(c5.HasFile(dir2inner));
1821   EXPECT_TRUE(c5.HasFile(dir2innerfile));
1822   EXPECT_EQ(c5.size(), 5);
1823
1824 #if defined(OS_WIN)
1825   {
1826     // Make dir1 point to dir2.
1827     ReparsePoint reparse_point(dir1, dir2);
1828     EXPECT_TRUE(reparse_point.IsValid());
1829
1830     if ((base::win::GetVersion() >= base::win::VERSION_VISTA)) {
1831       // There can be a delay for the enumeration code to see the change on
1832       // the file system so skip this test for XP.
1833       // Enumerate the reparse point.
1834       FileEnumerator f6(dir1, true, FILES_AND_DIRECTORIES);
1835       FindResultCollector c6(f6);
1836       FilePath inner2 = dir1.Append(FPL("inner"));
1837       EXPECT_TRUE(c6.HasFile(inner2));
1838       EXPECT_TRUE(c6.HasFile(inner2.Append(FPL("innerfile.txt"))));
1839       EXPECT_TRUE(c6.HasFile(dir1.Append(FPL("dir2file.txt"))));
1840       EXPECT_EQ(c6.size(), 3);
1841     }
1842
1843     // No changes for non recursive operation.
1844     FileEnumerator f7(temp_dir_.path(), false, FILES_AND_DIRECTORIES);
1845     FindResultCollector c7(f7);
1846     EXPECT_TRUE(c7.HasFile(dir2));
1847     EXPECT_TRUE(c7.HasFile(dir2));
1848     EXPECT_TRUE(c7.HasFile(file1));
1849     EXPECT_TRUE(c7.HasFile(file2_abs));
1850     EXPECT_EQ(c7.size(), 4);
1851
1852     // Should not enumerate inside dir1 when using recursion.
1853     FileEnumerator f8(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1854     FindResultCollector c8(f8);
1855     EXPECT_TRUE(c8.HasFile(dir1));
1856     EXPECT_TRUE(c8.HasFile(dir2));
1857     EXPECT_TRUE(c8.HasFile(file1));
1858     EXPECT_TRUE(c8.HasFile(file2_abs));
1859     EXPECT_TRUE(c8.HasFile(dir2file));
1860     EXPECT_TRUE(c8.HasFile(dir2inner));
1861     EXPECT_TRUE(c8.HasFile(dir2innerfile));
1862     EXPECT_EQ(c8.size(), 7);
1863   }
1864 #endif
1865
1866   // Make sure the destructor closes the find handle while in the middle of a
1867   // query to allow TearDown to delete the directory.
1868   FileEnumerator f9(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1869   EXPECT_FALSE(f9.Next().value().empty());  // Should have found something
1870                                             // (we don't care what).
1871 }
1872
1873 TEST_F(FileUtilTest, AppendToFile) {
1874   FilePath data_dir =
1875       temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
1876
1877   // Create a fresh, empty copy of this directory.
1878   if (base::PathExists(data_dir)) {
1879     ASSERT_TRUE(base::DeleteFile(data_dir, true));
1880   }
1881   ASSERT_TRUE(file_util::CreateDirectory(data_dir));
1882
1883   // Create a fresh, empty copy of this directory.
1884   if (base::PathExists(data_dir)) {
1885     ASSERT_TRUE(base::DeleteFile(data_dir, true));
1886   }
1887   ASSERT_TRUE(file_util::CreateDirectory(data_dir));
1888   FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
1889
1890   std::string data("hello");
1891   EXPECT_EQ(-1, file_util::AppendToFile(foobar, data.c_str(), data.length()));
1892   EXPECT_EQ(static_cast<int>(data.length()),
1893             file_util::WriteFile(foobar, data.c_str(), data.length()));
1894   EXPECT_EQ(static_cast<int>(data.length()),
1895             file_util::AppendToFile(foobar, data.c_str(), data.length()));
1896
1897   const std::wstring read_content = ReadTextFile(foobar);
1898   EXPECT_EQ(L"hellohello", read_content);
1899 }
1900
1901 TEST_F(FileUtilTest, TouchFile) {
1902   FilePath data_dir =
1903       temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
1904
1905   // Create a fresh, empty copy of this directory.
1906   if (base::PathExists(data_dir)) {
1907     ASSERT_TRUE(base::DeleteFile(data_dir, true));
1908   }
1909   ASSERT_TRUE(file_util::CreateDirectory(data_dir));
1910
1911   FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
1912   std::string data("hello");
1913   ASSERT_TRUE(file_util::WriteFile(foobar, data.c_str(), data.length()));
1914
1915   base::Time access_time;
1916   // This timestamp is divisible by one day (in local timezone),
1917   // to make it work on FAT too.
1918   ASSERT_TRUE(base::Time::FromString("Wed, 16 Nov 1994, 00:00:00",
1919                                      &access_time));
1920
1921   base::Time modification_time;
1922   // Note that this timestamp is divisible by two (seconds) - FAT stores
1923   // modification times with 2s resolution.
1924   ASSERT_TRUE(base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT",
1925               &modification_time));
1926
1927   ASSERT_TRUE(file_util::TouchFile(foobar, access_time, modification_time));
1928   base::PlatformFileInfo file_info;
1929   ASSERT_TRUE(file_util::GetFileInfo(foobar, &file_info));
1930   EXPECT_EQ(file_info.last_accessed.ToInternalValue(),
1931             access_time.ToInternalValue());
1932   EXPECT_EQ(file_info.last_modified.ToInternalValue(),
1933             modification_time.ToInternalValue());
1934 }
1935
1936 TEST_F(FileUtilTest, IsDirectoryEmpty) {
1937   FilePath empty_dir = temp_dir_.path().Append(FILE_PATH_LITERAL("EmptyDir"));
1938
1939   ASSERT_FALSE(base::PathExists(empty_dir));
1940
1941   ASSERT_TRUE(file_util::CreateDirectory(empty_dir));
1942
1943   EXPECT_TRUE(file_util::IsDirectoryEmpty(empty_dir));
1944
1945   FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt")));
1946   std::string bar("baz");
1947   ASSERT_TRUE(file_util::WriteFile(foo, bar.c_str(), bar.length()));
1948
1949   EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir));
1950 }
1951
1952 #if defined(OS_POSIX)
1953
1954 // Testing VerifyPathControlledByAdmin() is hard, because there is no
1955 // way a test can make a file owned by root, or change file paths
1956 // at the root of the file system.  VerifyPathControlledByAdmin()
1957 // is implemented as a call to VerifyPathControlledByUser, which gives
1958 // us the ability to test with paths under the test's temp directory,
1959 // using a user id we control.
1960 // Pull tests of VerifyPathControlledByUserTest() into a separate test class
1961 // with a common SetUp() method.
1962 class VerifyPathControlledByUserTest : public FileUtilTest {
1963  protected:
1964   virtual void SetUp() OVERRIDE {
1965     FileUtilTest::SetUp();
1966
1967     // Create a basic structure used by each test.
1968     // base_dir_
1969     //  |-> sub_dir_
1970     //       |-> text_file_
1971
1972     base_dir_ = temp_dir_.path().AppendASCII("base_dir");
1973     ASSERT_TRUE(file_util::CreateDirectory(base_dir_));
1974
1975     sub_dir_ = base_dir_.AppendASCII("sub_dir");
1976     ASSERT_TRUE(file_util::CreateDirectory(sub_dir_));
1977
1978     text_file_ = sub_dir_.AppendASCII("file.txt");
1979     CreateTextFile(text_file_, L"This text file has some text in it.");
1980
1981     // Get the user and group files are created with from |base_dir_|.
1982     struct stat stat_buf;
1983     ASSERT_EQ(0, stat(base_dir_.value().c_str(), &stat_buf));
1984     uid_ = stat_buf.st_uid;
1985     ok_gids_.insert(stat_buf.st_gid);
1986     bad_gids_.insert(stat_buf.st_gid + 1);
1987
1988     ASSERT_EQ(uid_, getuid());  // This process should be the owner.
1989
1990     // To ensure that umask settings do not cause the initial state
1991     // of permissions to be different from what we expect, explicitly
1992     // set permissions on the directories we create.
1993     // Make all files and directories non-world-writable.
1994
1995     // Users and group can read, write, traverse
1996     int enabled_permissions =
1997         file_util::FILE_PERMISSION_USER_MASK |
1998         file_util::FILE_PERMISSION_GROUP_MASK;
1999     // Other users can't read, write, traverse
2000     int disabled_permissions =
2001         file_util::FILE_PERMISSION_OTHERS_MASK;
2002
2003     ASSERT_NO_FATAL_FAILURE(
2004         ChangePosixFilePermissions(
2005             base_dir_, enabled_permissions, disabled_permissions));
2006     ASSERT_NO_FATAL_FAILURE(
2007         ChangePosixFilePermissions(
2008             sub_dir_, enabled_permissions, disabled_permissions));
2009   }
2010
2011   FilePath base_dir_;
2012   FilePath sub_dir_;
2013   FilePath text_file_;
2014   uid_t uid_;
2015
2016   std::set<gid_t> ok_gids_;
2017   std::set<gid_t> bad_gids_;
2018 };
2019
2020 TEST_F(VerifyPathControlledByUserTest, BadPaths) {
2021   // File does not exist.
2022   FilePath does_not_exist = base_dir_.AppendASCII("does")
2023                                      .AppendASCII("not")
2024                                      .AppendASCII("exist");
2025   EXPECT_FALSE(
2026       file_util::VerifyPathControlledByUser(
2027           base_dir_, does_not_exist, uid_, ok_gids_));
2028
2029   // |base| not a subpath of |path|.
2030   EXPECT_FALSE(
2031       file_util::VerifyPathControlledByUser(
2032           sub_dir_, base_dir_, uid_, ok_gids_));
2033
2034   // An empty base path will fail to be a prefix for any path.
2035   FilePath empty;
2036   EXPECT_FALSE(
2037       file_util::VerifyPathControlledByUser(
2038           empty, base_dir_, uid_, ok_gids_));
2039
2040   // Finding that a bad call fails proves nothing unless a good call succeeds.
2041   EXPECT_TRUE(
2042       file_util::VerifyPathControlledByUser(
2043           base_dir_, sub_dir_, uid_, ok_gids_));
2044 }
2045
2046 TEST_F(VerifyPathControlledByUserTest, Symlinks) {
2047   // Symlinks in the path should cause failure.
2048
2049   // Symlink to the file at the end of the path.
2050   FilePath file_link =  base_dir_.AppendASCII("file_link");
2051   ASSERT_TRUE(file_util::CreateSymbolicLink(text_file_, file_link))
2052       << "Failed to create symlink.";
2053
2054   EXPECT_FALSE(
2055       file_util::VerifyPathControlledByUser(
2056           base_dir_, file_link, uid_, ok_gids_));
2057   EXPECT_FALSE(
2058       file_util::VerifyPathControlledByUser(
2059           file_link, file_link, uid_, ok_gids_));
2060
2061   // Symlink from one directory to another within the path.
2062   FilePath link_to_sub_dir =  base_dir_.AppendASCII("link_to_sub_dir");
2063   ASSERT_TRUE(file_util::CreateSymbolicLink(sub_dir_, link_to_sub_dir))
2064     << "Failed to create symlink.";
2065
2066   FilePath file_path_with_link = link_to_sub_dir.AppendASCII("file.txt");
2067   ASSERT_TRUE(base::PathExists(file_path_with_link));
2068
2069   EXPECT_FALSE(
2070       file_util::VerifyPathControlledByUser(
2071           base_dir_, file_path_with_link, uid_, ok_gids_));
2072
2073   EXPECT_FALSE(
2074       file_util::VerifyPathControlledByUser(
2075           link_to_sub_dir, file_path_with_link, uid_, ok_gids_));
2076
2077   // Symlinks in parents of base path are allowed.
2078   EXPECT_TRUE(
2079       file_util::VerifyPathControlledByUser(
2080           file_path_with_link, file_path_with_link, uid_, ok_gids_));
2081 }
2082
2083 TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) {
2084   // Get a uid that is not the uid of files we create.
2085   uid_t bad_uid = uid_ + 1;
2086
2087   // Make all files and directories non-world-writable.
2088   ASSERT_NO_FATAL_FAILURE(
2089       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
2090   ASSERT_NO_FATAL_FAILURE(
2091       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
2092   ASSERT_NO_FATAL_FAILURE(
2093       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
2094
2095   // We control these paths.
2096   EXPECT_TRUE(
2097       file_util::VerifyPathControlledByUser(
2098           base_dir_, sub_dir_, uid_, ok_gids_));
2099   EXPECT_TRUE(
2100       file_util::VerifyPathControlledByUser(
2101           base_dir_, text_file_, uid_, ok_gids_));
2102   EXPECT_TRUE(
2103       file_util::VerifyPathControlledByUser(
2104           sub_dir_, text_file_, uid_, ok_gids_));
2105
2106   // Another user does not control these paths.
2107   EXPECT_FALSE(
2108       file_util::VerifyPathControlledByUser(
2109           base_dir_, sub_dir_, bad_uid, ok_gids_));
2110   EXPECT_FALSE(
2111       file_util::VerifyPathControlledByUser(
2112           base_dir_, text_file_, bad_uid, ok_gids_));
2113   EXPECT_FALSE(
2114       file_util::VerifyPathControlledByUser(
2115           sub_dir_, text_file_, bad_uid, ok_gids_));
2116
2117   // Another group does not control the paths.
2118   EXPECT_FALSE(
2119       file_util::VerifyPathControlledByUser(
2120           base_dir_, sub_dir_, uid_, bad_gids_));
2121   EXPECT_FALSE(
2122       file_util::VerifyPathControlledByUser(
2123           base_dir_, text_file_, uid_, bad_gids_));
2124   EXPECT_FALSE(
2125       file_util::VerifyPathControlledByUser(
2126           sub_dir_, text_file_, uid_, bad_gids_));
2127 }
2128
2129 TEST_F(VerifyPathControlledByUserTest, GroupWriteTest) {
2130   // Make all files and directories writable only by their owner.
2131   ASSERT_NO_FATAL_FAILURE(
2132       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH|S_IWGRP));
2133   ASSERT_NO_FATAL_FAILURE(
2134       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH|S_IWGRP));
2135   ASSERT_NO_FATAL_FAILURE(
2136       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH|S_IWGRP));
2137
2138   // Any group is okay because the path is not group-writable.
2139   EXPECT_TRUE(
2140       file_util::VerifyPathControlledByUser(
2141           base_dir_, sub_dir_, uid_, ok_gids_));
2142   EXPECT_TRUE(
2143       file_util::VerifyPathControlledByUser(
2144           base_dir_, text_file_, uid_, ok_gids_));
2145   EXPECT_TRUE(
2146       file_util::VerifyPathControlledByUser(
2147           sub_dir_, text_file_, uid_, ok_gids_));
2148
2149   EXPECT_TRUE(
2150       file_util::VerifyPathControlledByUser(
2151           base_dir_, sub_dir_, uid_, bad_gids_));
2152   EXPECT_TRUE(
2153       file_util::VerifyPathControlledByUser(
2154           base_dir_, text_file_, uid_, bad_gids_));
2155   EXPECT_TRUE(
2156       file_util::VerifyPathControlledByUser(
2157           sub_dir_, text_file_, uid_, bad_gids_));
2158
2159   // No group is okay, because we don't check the group
2160   // if no group can write.
2161   std::set<gid_t> no_gids;  // Empty set of gids.
2162   EXPECT_TRUE(
2163       file_util::VerifyPathControlledByUser(
2164           base_dir_, sub_dir_, uid_, no_gids));
2165   EXPECT_TRUE(
2166       file_util::VerifyPathControlledByUser(
2167           base_dir_, text_file_, uid_, no_gids));
2168   EXPECT_TRUE(
2169       file_util::VerifyPathControlledByUser(
2170           sub_dir_, text_file_, uid_, no_gids));
2171
2172
2173   // Make all files and directories writable by their group.
2174   ASSERT_NO_FATAL_FAILURE(
2175       ChangePosixFilePermissions(base_dir_, S_IWGRP, 0u));
2176   ASSERT_NO_FATAL_FAILURE(
2177       ChangePosixFilePermissions(sub_dir_, S_IWGRP, 0u));
2178   ASSERT_NO_FATAL_FAILURE(
2179       ChangePosixFilePermissions(text_file_, S_IWGRP, 0u));
2180
2181   // Now |ok_gids_| works, but |bad_gids_| fails.
2182   EXPECT_TRUE(
2183       file_util::VerifyPathControlledByUser(
2184           base_dir_, sub_dir_, uid_, ok_gids_));
2185   EXPECT_TRUE(
2186       file_util::VerifyPathControlledByUser(
2187           base_dir_, text_file_, uid_, ok_gids_));
2188   EXPECT_TRUE(
2189       file_util::VerifyPathControlledByUser(
2190           sub_dir_, text_file_, uid_, ok_gids_));
2191
2192   EXPECT_FALSE(
2193       file_util::VerifyPathControlledByUser(
2194           base_dir_, sub_dir_, uid_, bad_gids_));
2195   EXPECT_FALSE(
2196       file_util::VerifyPathControlledByUser(
2197           base_dir_, text_file_, uid_, bad_gids_));
2198   EXPECT_FALSE(
2199       file_util::VerifyPathControlledByUser(
2200           sub_dir_, text_file_, uid_, bad_gids_));
2201
2202   // Because any group in the group set is allowed,
2203   // the union of good and bad gids passes.
2204
2205   std::set<gid_t> multiple_gids;
2206   std::set_union(
2207       ok_gids_.begin(), ok_gids_.end(),
2208       bad_gids_.begin(), bad_gids_.end(),
2209       std::inserter(multiple_gids, multiple_gids.begin()));
2210
2211   EXPECT_TRUE(
2212       file_util::VerifyPathControlledByUser(
2213           base_dir_, sub_dir_, uid_, multiple_gids));
2214   EXPECT_TRUE(
2215       file_util::VerifyPathControlledByUser(
2216           base_dir_, text_file_, uid_, multiple_gids));
2217   EXPECT_TRUE(
2218       file_util::VerifyPathControlledByUser(
2219           sub_dir_, text_file_, uid_, multiple_gids));
2220 }
2221
2222 TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) {
2223   // Make all files and directories non-world-writable.
2224   ASSERT_NO_FATAL_FAILURE(
2225       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
2226   ASSERT_NO_FATAL_FAILURE(
2227       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
2228   ASSERT_NO_FATAL_FAILURE(
2229       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
2230
2231   // Initialy, we control all parts of the path.
2232   EXPECT_TRUE(
2233       file_util::VerifyPathControlledByUser(
2234           base_dir_, sub_dir_, uid_, ok_gids_));
2235   EXPECT_TRUE(
2236       file_util::VerifyPathControlledByUser(
2237           base_dir_, text_file_, uid_, ok_gids_));
2238   EXPECT_TRUE(
2239       file_util::VerifyPathControlledByUser(
2240           sub_dir_, text_file_, uid_, ok_gids_));
2241
2242   // Make base_dir_ world-writable.
2243   ASSERT_NO_FATAL_FAILURE(
2244       ChangePosixFilePermissions(base_dir_, S_IWOTH, 0u));
2245   EXPECT_FALSE(
2246       file_util::VerifyPathControlledByUser(
2247           base_dir_, sub_dir_, uid_, ok_gids_));
2248   EXPECT_FALSE(
2249       file_util::VerifyPathControlledByUser(
2250           base_dir_, text_file_, uid_, ok_gids_));
2251   EXPECT_TRUE(
2252       file_util::VerifyPathControlledByUser(
2253           sub_dir_, text_file_, uid_, ok_gids_));
2254
2255   // Make sub_dir_ world writable.
2256   ASSERT_NO_FATAL_FAILURE(
2257       ChangePosixFilePermissions(sub_dir_, S_IWOTH, 0u));
2258   EXPECT_FALSE(
2259       file_util::VerifyPathControlledByUser(
2260           base_dir_, sub_dir_, uid_, ok_gids_));
2261   EXPECT_FALSE(
2262       file_util::VerifyPathControlledByUser(
2263           base_dir_, text_file_, uid_, ok_gids_));
2264   EXPECT_FALSE(
2265       file_util::VerifyPathControlledByUser(
2266           sub_dir_, text_file_, uid_, ok_gids_));
2267
2268   // Make text_file_ world writable.
2269   ASSERT_NO_FATAL_FAILURE(
2270       ChangePosixFilePermissions(text_file_, S_IWOTH, 0u));
2271   EXPECT_FALSE(
2272       file_util::VerifyPathControlledByUser(
2273           base_dir_, sub_dir_, uid_, ok_gids_));
2274   EXPECT_FALSE(
2275       file_util::VerifyPathControlledByUser(
2276           base_dir_, text_file_, uid_, ok_gids_));
2277   EXPECT_FALSE(
2278       file_util::VerifyPathControlledByUser(
2279           sub_dir_, text_file_, uid_, ok_gids_));
2280
2281   // Make sub_dir_ non-world writable.
2282   ASSERT_NO_FATAL_FAILURE(
2283       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
2284   EXPECT_FALSE(
2285       file_util::VerifyPathControlledByUser(
2286           base_dir_, sub_dir_, uid_, ok_gids_));
2287   EXPECT_FALSE(
2288       file_util::VerifyPathControlledByUser(
2289           base_dir_, text_file_, uid_, ok_gids_));
2290   EXPECT_FALSE(
2291       file_util::VerifyPathControlledByUser(
2292           sub_dir_, text_file_, uid_, ok_gids_));
2293
2294   // Make base_dir_ non-world-writable.
2295   ASSERT_NO_FATAL_FAILURE(
2296       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
2297   EXPECT_TRUE(
2298       file_util::VerifyPathControlledByUser(
2299           base_dir_, sub_dir_, uid_, ok_gids_));
2300   EXPECT_FALSE(
2301       file_util::VerifyPathControlledByUser(
2302           base_dir_, text_file_, uid_, ok_gids_));
2303   EXPECT_FALSE(
2304       file_util::VerifyPathControlledByUser(
2305           sub_dir_, text_file_, uid_, ok_gids_));
2306
2307   // Back to the initial state: Nothing is writable, so every path
2308   // should pass.
2309   ASSERT_NO_FATAL_FAILURE(
2310       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
2311   EXPECT_TRUE(
2312       file_util::VerifyPathControlledByUser(
2313           base_dir_, sub_dir_, uid_, ok_gids_));
2314   EXPECT_TRUE(
2315       file_util::VerifyPathControlledByUser(
2316           base_dir_, text_file_, uid_, ok_gids_));
2317   EXPECT_TRUE(
2318       file_util::VerifyPathControlledByUser(
2319           sub_dir_, text_file_, uid_, ok_gids_));
2320 }
2321
2322 #endif  // defined(OS_POSIX)
2323
2324 }  // namespace