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