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.
5 #include "build/build_config.h"
19 #include "base/base_paths.h"
20 #include "base/file_path.h"
21 #include "base/file_util.h"
22 #include "base/files/scoped_temp_dir.h"
23 #include "base/path_service.h"
24 #include "base/test/test_file_util.h"
25 #include "base/threading/platform_thread.h"
26 #include "base/utf_string_conversions.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "testing/platform_test.h"
31 #include "base/win/scoped_handle.h"
34 // This macro helps avoid wrapped lines in the test structs.
35 #define FPL(x) FILE_PATH_LITERAL(x)
39 // To test that file_util::Normalize FilePath() deals with NTFS reparse points
40 // correctly, we need functions to create and delete reparse points.
42 typedef struct _REPARSE_DATA_BUFFER
{
44 USHORT ReparseDataLength
;
48 USHORT SubstituteNameOffset
;
49 USHORT SubstituteNameLength
;
50 USHORT PrintNameOffset
;
51 USHORT PrintNameLength
;
54 } SymbolicLinkReparseBuffer
;
56 USHORT SubstituteNameOffset
;
57 USHORT SubstituteNameLength
;
58 USHORT PrintNameOffset
;
59 USHORT PrintNameLength
;
61 } MountPointReparseBuffer
;
64 } GenericReparseBuffer
;
66 } REPARSE_DATA_BUFFER
, *PREPARSE_DATA_BUFFER
;
68 // Sets a reparse point. |source| will now point to |target|. Returns true if
69 // the call succeeds, false otherwise.
70 bool SetReparsePoint(HANDLE source
, const FilePath
& target_path
) {
71 std::wstring kPathPrefix
= L
"\\??\\";
72 std::wstring target_str
;
73 // The juction will not work if the target path does not start with \??\ .
74 if (kPathPrefix
!= target_path
.value().substr(0, kPathPrefix
.size()))
75 target_str
+= kPathPrefix
;
76 target_str
+= target_path
.value();
77 const wchar_t* target
= target_str
.c_str();
78 USHORT size_target
= static_cast<USHORT
>(wcslen(target
)) * sizeof(target
[0]);
79 char buffer
[2000] = {0};
82 REPARSE_DATA_BUFFER
* data
= reinterpret_cast<REPARSE_DATA_BUFFER
*>(buffer
);
84 data
->ReparseTag
= 0xa0000003;
85 memcpy(data
->MountPointReparseBuffer
.PathBuffer
, target
, size_target
+ 2);
87 data
->MountPointReparseBuffer
.SubstituteNameLength
= size_target
;
88 data
->MountPointReparseBuffer
.PrintNameOffset
= size_target
+ 2;
89 data
->ReparseDataLength
= size_target
+ 4 + 8;
91 int data_size
= data
->ReparseDataLength
+ 8;
93 if (!DeviceIoControl(source
, FSCTL_SET_REPARSE_POINT
, &buffer
, data_size
,
94 NULL
, 0, &returned
, NULL
)) {
100 // Delete the reparse point referenced by |source|. Returns true if the call
101 // succeeds, false otherwise.
102 bool DeleteReparsePoint(HANDLE source
) {
104 REPARSE_DATA_BUFFER data
= {0};
105 data
.ReparseTag
= 0xa0000003;
106 if (!DeviceIoControl(source
, FSCTL_DELETE_REPARSE_POINT
, &data
, 8, NULL
, 0,
114 #if defined(OS_POSIX)
115 // Provide a simple way to change the permissions bits on |path| in tests.
116 // ASSERT failures will return, but not stop the test. Caller should wrap
117 // calls to this function in ASSERT_NO_FATAL_FAILURE().
118 void ChangePosixFilePermissions(const FilePath
& path
,
119 int mode_bits_to_set
,
120 int mode_bits_to_clear
) {
121 ASSERT_FALSE(mode_bits_to_set
& mode_bits_to_clear
)
122 << "Can't set and clear the same bits.";
125 ASSERT_TRUE(file_util::GetPosixFilePermissions(path
, &mode
));
126 mode
|= mode_bits_to_set
;
127 mode
&= ~mode_bits_to_clear
;
128 ASSERT_TRUE(file_util::SetPosixFilePermissions(path
, mode
));
130 #endif // defined(OS_POSIX)
132 const wchar_t bogus_content
[] = L
"I'm cannon fodder.";
134 const int FILES_AND_DIRECTORIES
=
135 file_util::FileEnumerator::FILES
| file_util::FileEnumerator::DIRECTORIES
;
137 // file_util winds up using autoreleased objects on the Mac, so this needs
138 // to be a PlatformTest
139 class FileUtilTest
: public PlatformTest
{
141 virtual void SetUp() OVERRIDE
{
142 PlatformTest::SetUp();
143 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
146 base::ScopedTempDir temp_dir_
;
149 // Collects all the results from the given file enumerator, and provides an
150 // interface to query whether a given file is present.
151 class FindResultCollector
{
153 explicit FindResultCollector(file_util::FileEnumerator
& enumerator
) {
155 while (!(cur_file
= enumerator
.Next()).value().empty()) {
156 FilePath::StringType path
= cur_file
.value();
157 // The file should not be returned twice.
158 EXPECT_TRUE(files_
.end() == files_
.find(path
))
159 << "Same file returned twice";
166 // Returns true if the enumerator found the file.
167 bool HasFile(const FilePath
& file
) const {
168 return files_
.find(file
.value()) != files_
.end();
172 return static_cast<int>(files_
.size());
176 std::set
<FilePath::StringType
> files_
;
179 // Simple function to dump some text into a new file.
180 void CreateTextFile(const FilePath
& filename
,
181 const std::wstring
& contents
) {
183 file
.open(filename
.value().c_str());
184 ASSERT_TRUE(file
.is_open());
189 // Simple function to take out some text from a file.
190 std::wstring
ReadTextFile(const FilePath
& filename
) {
191 wchar_t contents
[64];
193 file
.open(filename
.value().c_str());
194 EXPECT_TRUE(file
.is_open());
195 file
.getline(contents
, arraysize(contents
));
197 return std::wstring(contents
);
201 uint64
FileTimeAsUint64(const FILETIME
& ft
) {
203 u
.LowPart
= ft
.dwLowDateTime
;
204 u
.HighPart
= ft
.dwHighDateTime
;
209 const struct append_case
{
211 const wchar_t* ending
;
212 const wchar_t* result
;
215 {L
"c:\\colon\\backslash", L
"path", L
"c:\\colon\\backslash\\path"},
216 {L
"c:\\colon\\backslash\\", L
"path", L
"c:\\colon\\backslash\\path"},
217 {L
"c:\\colon\\backslash\\\\", L
"path", L
"c:\\colon\\backslash\\\\path"},
218 {L
"c:\\colon\\backslash\\", L
"", L
"c:\\colon\\backslash\\"},
219 {L
"c:\\colon\\backslash", L
"", L
"c:\\colon\\backslash\\"},
220 {L
"", L
"path", L
"\\path"},
222 #elif defined(OS_POSIX)
223 {L
"/foo/bar", L
"path", L
"/foo/bar/path"},
224 {L
"/foo/bar/", L
"path", L
"/foo/bar/path"},
225 {L
"/foo/bar//", L
"path", L
"/foo/bar//path"},
226 {L
"/foo/bar/", L
"", L
"/foo/bar/"},
227 {L
"/foo/bar", L
"", L
"/foo/bar/"},
228 {L
"", L
"path", L
"/path"},
233 static const struct filename_case
{
235 const wchar_t* filename
;
236 } filename_cases
[] = {
238 {L
"c:\\colon\\backslash", L
"backslash"},
239 {L
"c:\\colon\\backslash\\", L
""},
240 {L
"\\\\filename.exe", L
"filename.exe"},
241 {L
"filename.exe", L
"filename.exe"},
244 {L
"c:/colon/backslash", L
"backslash"},
245 {L
"c:/colon/backslash/", L
""},
247 {L
"///filename.exe", L
"filename.exe"},
248 #elif defined(OS_POSIX)
249 {L
"/foo/bar", L
"bar"},
251 {L
"/filename.exe", L
"filename.exe"},
252 {L
"filename.exe", L
"filename.exe"},
258 // Test finding the file type from a path name
259 static const struct extension_case
{
261 const wchar_t* extension
;
262 } extension_cases
[] = {
264 {L
"C:\\colon\\backslash\\filename.extension", L
"extension"},
265 {L
"C:\\colon\\backslash\\filename.", L
""},
266 {L
"C:\\colon\\backslash\\filename", L
""},
267 {L
"C:\\colon\\backslash\\", L
""},
268 {L
"C:\\colon\\backslash.\\", L
""},
269 {L
"C:\\colon\\backslash\filename.extension.extension2", L
"extension2"},
270 #elif defined(OS_POSIX)
271 {L
"/foo/bar/filename.extension", L
"extension"},
272 {L
"/foo/bar/filename.", L
""},
273 {L
"/foo/bar/filename", L
""},
275 {L
"/foo/bar./", L
""},
276 {L
"/foo/bar/filename.extension.extension2", L
"extension2"},
280 {L
"./foo.extension", L
"extension"},
281 {L
"/foo.extension1/bar.extension2", L
"extension2"},
285 // Test finding the directory component of a path
286 static const struct dir_case
{
287 const wchar_t* full_path
;
288 const wchar_t* directory
;
291 {L
"C:\\WINDOWS\\system32\\gdi32.dll", L
"C:\\WINDOWS\\system32"},
292 {L
"C:\\WINDOWS\\system32\\not_exist_thx_1138", L
"C:\\WINDOWS\\system32"},
293 {L
"C:\\WINDOWS\\system32\\", L
"C:\\WINDOWS\\system32"},
294 {L
"C:\\WINDOWS\\system32\\\\", L
"C:\\WINDOWS\\system32"},
295 {L
"C:\\WINDOWS\\system32", L
"C:\\WINDOWS"},
296 {L
"C:\\WINDOWS\\system32.\\", L
"C:\\WINDOWS\\system32."},
298 #elif defined(OS_POSIX)
299 {L
"/foo/bar/gdi32.dll", L
"/foo/bar"},
300 {L
"/foo/bar/not_exist_thx_1138", L
"/foo/bar"},
301 {L
"/foo/bar/", L
"/foo/bar"},
302 {L
"/foo/bar//", L
"/foo/bar"},
303 {L
"/foo/bar", L
"/foo"},
304 {L
"/foo/bar./", L
"/foo/bar."},
307 {L
"..", L
"."}, // yes, ".." technically lives in "."
311 TEST_F(FileUtilTest
, CountFilesCreatedAfter
) {
313 temp_dir_
.path().Append(FILE_PATH_LITERAL("f.txt"));
314 CreateTextFile(file_name
, L
"test");
316 base::PlatformFileInfo info
;
317 file_util::GetFileInfo(file_name
, &info
);
318 base::Time file_time
= info
.creation_time
;
320 base::TimeDelta two_secs
= base::TimeDelta::FromSeconds(2);
321 base::Time after
= file_time
+ two_secs
;
322 EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_
.path(), after
));
324 base::Time before
= file_time
- two_secs
;
325 EXPECT_EQ(1, file_util::CountFilesCreatedAfter(temp_dir_
.path(), before
));
327 // After deleting the file, shouldn't find it any more.
328 EXPECT_TRUE(file_util::Delete(file_name
, false));
329 EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_
.path(), before
));
330 EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_
.path(), after
));
333 TEST_F(FileUtilTest
, FileAndDirectorySize
) {
334 // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize
335 // should return 53 bytes.
336 FilePath file_01
= temp_dir_
.path().Append(FPL("The file 01.txt"));
337 CreateTextFile(file_01
, L
"12345678901234567890");
339 ASSERT_TRUE(file_util::GetFileSize(file_01
, &size_f1
));
340 EXPECT_EQ(20ll, size_f1
);
342 FilePath subdir_path
= temp_dir_
.path().Append(FPL("Level2"));
343 file_util::CreateDirectory(subdir_path
);
345 FilePath file_02
= subdir_path
.Append(FPL("The file 02.txt"));
346 CreateTextFile(file_02
, L
"123456789012345678901234567890");
348 ASSERT_TRUE(file_util::GetFileSize(file_02
, &size_f2
));
349 EXPECT_EQ(30ll, size_f2
);
351 FilePath subsubdir_path
= subdir_path
.Append(FPL("Level3"));
352 file_util::CreateDirectory(subsubdir_path
);
354 FilePath file_03
= subsubdir_path
.Append(FPL("The file 03.txt"));
355 CreateTextFile(file_03
, L
"123");
357 int64 computed_size
= file_util::ComputeDirectorySize(temp_dir_
.path());
358 EXPECT_EQ(size_f1
+ size_f2
+ 3, computed_size
);
361 file_util::ComputeFilesSize(temp_dir_
.path(), FPL("The file*"));
362 EXPECT_EQ(size_f1
, computed_size
);
364 computed_size
= file_util::ComputeFilesSize(temp_dir_
.path(), FPL("bla*"));
365 EXPECT_EQ(0, computed_size
);
368 TEST_F(FileUtilTest
, NormalizeFilePathBasic
) {
369 // Create a directory under the test dir. Because we create it,
370 // we know it is not a link.
371 FilePath file_a_path
= temp_dir_
.path().Append(FPL("file_a"));
372 FilePath dir_path
= temp_dir_
.path().Append(FPL("dir"));
373 FilePath file_b_path
= dir_path
.Append(FPL("file_b"));
374 file_util::CreateDirectory(dir_path
);
376 FilePath normalized_file_a_path
, normalized_file_b_path
;
377 ASSERT_FALSE(file_util::PathExists(file_a_path
));
378 ASSERT_FALSE(file_util::NormalizeFilePath(file_a_path
,
379 &normalized_file_a_path
))
380 << "NormalizeFilePath() should fail on nonexistent paths.";
382 CreateTextFile(file_a_path
, bogus_content
);
383 ASSERT_TRUE(file_util::PathExists(file_a_path
));
384 ASSERT_TRUE(file_util::NormalizeFilePath(file_a_path
,
385 &normalized_file_a_path
));
387 CreateTextFile(file_b_path
, bogus_content
);
388 ASSERT_TRUE(file_util::PathExists(file_b_path
));
389 ASSERT_TRUE(file_util::NormalizeFilePath(file_b_path
,
390 &normalized_file_b_path
));
392 // Beacuse this test created |dir_path|, we know it is not a link
393 // or junction. So, the real path of the directory holding file a
394 // must be the parent of the path holding file b.
395 ASSERT_TRUE(normalized_file_a_path
.DirName()
396 .IsParent(normalized_file_b_path
.DirName()));
401 TEST_F(FileUtilTest
, NormalizeFilePathReparsePoints
) {
402 // Build the following directory structure:
408 // | |-> long_name___... (Very long name.)
412 // |-> to_sub_a (reparse point to temp_dir\base_a\sub_a)
413 // |-> to_base_b (reparse point to temp_dir\base_b)
414 // |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long)
416 FilePath base_a
= temp_dir_
.path().Append(FPL("base_a"));
417 ASSERT_TRUE(file_util::CreateDirectory(base_a
));
419 FilePath sub_a
= base_a
.Append(FPL("sub_a"));
420 ASSERT_TRUE(file_util::CreateDirectory(sub_a
));
422 FilePath file_txt
= sub_a
.Append(FPL("file.txt"));
423 CreateTextFile(file_txt
, bogus_content
);
425 // Want a directory whose name is long enough to make the path to the file
426 // inside just under MAX_PATH chars. This will be used to test that when
427 // a junction expands to a path over MAX_PATH chars in length,
428 // NormalizeFilePath() fails without crashing.
429 FilePath
sub_long_rel(FPL("sub_long"));
430 FilePath
deep_txt(FPL("deep.txt"));
432 int target_length
= MAX_PATH
;
433 target_length
-= (sub_a
.value().length() + 1); // +1 for the sepperator '\'.
434 target_length
-= (sub_long_rel
.Append(deep_txt
).value().length() + 1);
435 // Without making the path a bit shorter, CreateDirectory() fails.
436 // the resulting path is still long enough to hit the failing case in
438 const int kCreateDirLimit
= 4;
439 target_length
-= kCreateDirLimit
;
440 FilePath::StringType long_name_str
= FPL("long_name_");
441 long_name_str
.resize(target_length
, '_');
443 FilePath long_name
= sub_a
.Append(FilePath(long_name_str
));
444 FilePath deep_file
= long_name
.Append(sub_long_rel
).Append(deep_txt
);
445 ASSERT_EQ(MAX_PATH
- kCreateDirLimit
, deep_file
.value().length());
447 FilePath sub_long
= deep_file
.DirName();
448 ASSERT_TRUE(file_util::CreateDirectory(sub_long
));
449 CreateTextFile(deep_file
, bogus_content
);
451 FilePath base_b
= temp_dir_
.path().Append(FPL("base_b"));
452 ASSERT_TRUE(file_util::CreateDirectory(base_b
));
454 FilePath to_sub_a
= base_b
.Append(FPL("to_sub_a"));
455 ASSERT_TRUE(file_util::CreateDirectory(to_sub_a
));
456 base::win::ScopedHandle
reparse_to_sub_a(
457 ::CreateFile(to_sub_a
.value().c_str(),
459 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
462 FILE_FLAG_BACKUP_SEMANTICS
, // Needed to open a directory.
464 ASSERT_TRUE(reparse_to_sub_a
.IsValid());
465 ASSERT_TRUE(SetReparsePoint(reparse_to_sub_a
, sub_a
));
467 FilePath to_base_b
= base_b
.Append(FPL("to_base_b"));
468 ASSERT_TRUE(file_util::CreateDirectory(to_base_b
));
469 base::win::ScopedHandle
reparse_to_base_b(
470 ::CreateFile(to_base_b
.value().c_str(),
472 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
475 FILE_FLAG_BACKUP_SEMANTICS
, // Needed to open a directory.
477 ASSERT_TRUE(reparse_to_base_b
.IsValid());
478 ASSERT_TRUE(SetReparsePoint(reparse_to_base_b
, base_b
));
480 FilePath to_sub_long
= base_b
.Append(FPL("to_sub_long"));
481 ASSERT_TRUE(file_util::CreateDirectory(to_sub_long
));
482 base::win::ScopedHandle
reparse_to_sub_long(
483 ::CreateFile(to_sub_long
.value().c_str(),
485 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
488 FILE_FLAG_BACKUP_SEMANTICS
, // Needed to open a directory.
490 ASSERT_TRUE(reparse_to_sub_long
.IsValid());
491 ASSERT_TRUE(SetReparsePoint(reparse_to_sub_long
, sub_long
));
493 // Normalize a junction free path: base_a\sub_a\file.txt .
494 FilePath normalized_path
;
495 ASSERT_TRUE(file_util::NormalizeFilePath(file_txt
, &normalized_path
));
496 ASSERT_STREQ(file_txt
.value().c_str(), normalized_path
.value().c_str());
498 // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude
499 // the junction to_sub_a.
500 ASSERT_TRUE(file_util::NormalizeFilePath(to_sub_a
.Append(FPL("file.txt")),
502 ASSERT_STREQ(file_txt
.value().c_str(), normalized_path
.value().c_str());
504 // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be
505 // normalized to exclude junctions to_base_b and to_sub_a .
506 ASSERT_TRUE(file_util::NormalizeFilePath(base_b
.Append(FPL("to_base_b"))
507 .Append(FPL("to_base_b"))
508 .Append(FPL("to_sub_a"))
509 .Append(FPL("file.txt")),
511 ASSERT_STREQ(file_txt
.value().c_str(), normalized_path
.value().c_str());
513 // A long enough path will cause NormalizeFilePath() to fail. Make a long
514 // path using to_base_b many times, and check that paths long enough to fail
515 // do not cause a crash.
516 FilePath long_path
= base_b
;
517 const int kLengthLimit
= MAX_PATH
+ 200;
518 while (long_path
.value().length() <= kLengthLimit
) {
519 long_path
= long_path
.Append(FPL("to_base_b"));
521 long_path
= long_path
.Append(FPL("to_sub_a"))
522 .Append(FPL("file.txt"));
524 ASSERT_FALSE(file_util::NormalizeFilePath(long_path
, &normalized_path
));
526 // Normalizing the junction to deep.txt should fail, because the expanded
527 // path to deep.txt is longer than MAX_PATH.
528 ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_long
.Append(deep_txt
),
531 // Delete the reparse points, and see that NormalizeFilePath() fails
533 ASSERT_TRUE(DeleteReparsePoint(reparse_to_sub_a
));
534 ASSERT_TRUE(DeleteReparsePoint(reparse_to_base_b
));
535 ASSERT_TRUE(DeleteReparsePoint(reparse_to_sub_long
));
537 ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_a
.Append(FPL("file.txt")),
541 TEST_F(FileUtilTest
, DevicePathToDriveLetter
) {
542 // Get a drive letter.
543 std::wstring real_drive_letter
= temp_dir_
.path().value().substr(0, 2);
544 if (!isalpha(real_drive_letter
[0]) || ':' != real_drive_letter
[1]) {
545 LOG(ERROR
) << "Can't get a drive letter to test with.";
549 // Get the NT style path to that drive.
550 wchar_t device_path
[MAX_PATH
] = {'\0'};
552 ::QueryDosDevice(real_drive_letter
.c_str(), device_path
, MAX_PATH
));
553 FilePath
actual_device_path(device_path
);
556 // Run DevicePathToDriveLetterPath() on the NT style path we got from
557 // QueryDosDevice(). Expect the drive letter we started with.
558 ASSERT_TRUE(file_util::DevicePathToDriveLetterPath(actual_device_path
,
560 ASSERT_EQ(real_drive_letter
, win32_path
.value());
562 // Add some directories to the path. Expect those extra path componenets
564 FilePath
kRelativePath(FPL("dir1\\dir2\\file.txt"));
565 ASSERT_TRUE(file_util::DevicePathToDriveLetterPath(
566 actual_device_path
.Append(kRelativePath
),
568 EXPECT_EQ(FilePath(real_drive_letter
+ L
"\\").Append(kRelativePath
).value(),
571 // Deform the real path so that it is invalid by removing the last four
572 // characters. The way windows names devices that are hard disks
573 // (\Device\HardDiskVolume${NUMBER}) guarantees that the string is longer
574 // than three characters. The only way the truncated string could be a
575 // real drive is if more than 10^3 disks are mounted:
576 // \Device\HardDiskVolume10000 would be truncated to \Device\HardDiskVolume1
577 // Check that DevicePathToDriveLetterPath fails.
578 int path_length
= actual_device_path
.value().length();
579 int new_length
= path_length
- 4;
580 ASSERT_LT(0, new_length
);
581 FilePath
prefix_of_real_device_path(
582 actual_device_path
.value().substr(0, new_length
));
583 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
584 prefix_of_real_device_path
,
587 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
588 prefix_of_real_device_path
.Append(kRelativePath
),
591 // Deform the real path so that it is invalid by adding some characters. For
592 // example, if C: maps to \Device\HardDiskVolume8, then we simulate a
593 // request for the drive letter whose native path is
594 // \Device\HardDiskVolume812345 . We assume such a device does not exist,
595 // because drives are numbered in order and mounting 112345 hard disks will
597 const FilePath::StringType kExtraChars
= FPL("12345");
599 FilePath
real_device_path_plus_numbers(
600 actual_device_path
.value() + kExtraChars
);
602 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
603 real_device_path_plus_numbers
,
606 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath(
607 real_device_path_plus_numbers
.Append(kRelativePath
),
611 TEST_F(FileUtilTest
, GetPlatformFileInfoForDirectory
) {
612 FilePath empty_dir
= temp_dir_
.path().Append(FPL("gpfi_test"));
613 ASSERT_TRUE(file_util::CreateDirectory(empty_dir
));
614 base::win::ScopedHandle
dir(
615 ::CreateFile(empty_dir
.value().c_str(),
617 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
620 FILE_FLAG_BACKUP_SEMANTICS
, // Needed to open a directory.
622 ASSERT_TRUE(dir
.IsValid());
623 base::PlatformFileInfo info
;
624 EXPECT_TRUE(base::GetPlatformFileInfo(dir
.Get(), &info
));
625 EXPECT_TRUE(info
.is_directory
);
626 EXPECT_FALSE(info
.is_symbolic_link
);
627 EXPECT_EQ(0, info
.size
);
630 TEST_F(FileUtilTest
, CreateTemporaryFileInDirLongPathTest
) {
631 // Test that CreateTemporaryFileInDir() creates a path and returns a long path
632 // if it is available. This test requires that:
633 // - the filesystem at |temp_dir_| supports long filenames.
634 // - the account has FILE_LIST_DIRECTORY permission for all ancestor
635 // directories of |temp_dir_|.
636 const FilePath::CharType kLongDirName
[] = FPL("A long path");
637 const FilePath::CharType kTestSubDirName
[] = FPL("test");
638 FilePath long_test_dir
= temp_dir_
.path().Append(kLongDirName
);
639 ASSERT_TRUE(file_util::CreateDirectory(long_test_dir
));
641 // kLongDirName is not a 8.3 component. So GetShortName() should give us a
642 // different short name.
643 WCHAR path_buffer
[MAX_PATH
];
644 DWORD path_buffer_length
= GetShortPathName(long_test_dir
.value().c_str(),
645 path_buffer
, MAX_PATH
);
646 ASSERT_LT(path_buffer_length
, DWORD(MAX_PATH
));
647 ASSERT_NE(DWORD(0), path_buffer_length
);
648 FilePath
short_test_dir(path_buffer
);
649 ASSERT_STRNE(kLongDirName
, short_test_dir
.BaseName().value().c_str());
652 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(short_test_dir
, &temp_file
));
653 EXPECT_STREQ(kLongDirName
, temp_file
.DirName().BaseName().value().c_str());
654 EXPECT_TRUE(file_util::PathExists(temp_file
));
656 // Create a subdirectory of |long_test_dir| and make |long_test_dir|
657 // unreadable. We should still be able to create a temp file in the
658 // subdirectory, but we won't be able to determine the long path for it. This
659 // mimics the environment that some users run where their user profiles reside
660 // in a location where the don't have full access to the higher level
661 // directories. (Note that this assumption is true for NTFS, but not for some
662 // network file systems. E.g. AFS).
663 FilePath access_test_dir
= long_test_dir
.Append(kTestSubDirName
);
664 ASSERT_TRUE(file_util::CreateDirectory(access_test_dir
));
665 file_util::PermissionRestorer
long_test_dir_restorer(long_test_dir
);
666 ASSERT_TRUE(file_util::MakeFileUnreadable(long_test_dir
));
668 // Use the short form of the directory to create a temporary filename.
669 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(
670 short_test_dir
.Append(kTestSubDirName
), &temp_file
));
671 EXPECT_TRUE(file_util::PathExists(temp_file
));
672 EXPECT_TRUE(short_test_dir
.IsParent(temp_file
.DirName()));
674 // Check that the long path can't be determined for |temp_file|.
675 path_buffer_length
= GetLongPathName(temp_file
.value().c_str(),
676 path_buffer
, MAX_PATH
);
677 EXPECT_EQ(DWORD(0), path_buffer_length
);
680 #endif // defined(OS_WIN)
682 #if defined(OS_POSIX)
684 TEST_F(FileUtilTest
, CreateAndReadSymlinks
) {
685 FilePath link_from
= temp_dir_
.path().Append(FPL("from_file"));
686 FilePath link_to
= temp_dir_
.path().Append(FPL("to_file"));
687 CreateTextFile(link_to
, bogus_content
);
689 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to
, link_from
))
690 << "Failed to create file symlink.";
692 // If we created the link properly, we should be able to read the
693 // contents through it.
694 std::wstring contents
= ReadTextFile(link_from
);
695 ASSERT_EQ(contents
, bogus_content
);
698 ASSERT_TRUE(file_util::ReadSymbolicLink(link_from
, &result
));
699 ASSERT_EQ(link_to
.value(), result
.value());
701 // Link to a directory.
702 link_from
= temp_dir_
.path().Append(FPL("from_dir"));
703 link_to
= temp_dir_
.path().Append(FPL("to_dir"));
704 file_util::CreateDirectory(link_to
);
706 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to
, link_from
))
707 << "Failed to create directory symlink.";
710 ASSERT_FALSE(file_util::CreateSymbolicLink(link_to
, link_to
));
711 ASSERT_FALSE(file_util::ReadSymbolicLink(link_to
, &result
));
712 FilePath missing
= temp_dir_
.path().Append(FPL("missing"));
713 ASSERT_FALSE(file_util::ReadSymbolicLink(missing
, &result
));
716 // The following test of NormalizeFilePath() require that we create a symlink.
717 // This can not be done on Windows before Vista. On Vista, creating a symlink
718 // requires privilege "SeCreateSymbolicLinkPrivilege".
719 // TODO(skerner): Investigate the possibility of giving base_unittests the
720 // privileges required to create a symlink.
721 TEST_F(FileUtilTest
, NormalizeFilePathSymlinks
) {
722 FilePath normalized_path
;
724 // Link one file to another.
725 FilePath link_from
= temp_dir_
.path().Append(FPL("from_file"));
726 FilePath link_to
= temp_dir_
.path().Append(FPL("to_file"));
727 CreateTextFile(link_to
, bogus_content
);
729 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to
, link_from
))
730 << "Failed to create file symlink.";
732 // Check that NormalizeFilePath sees the link.
733 ASSERT_TRUE(file_util::NormalizeFilePath(link_from
, &normalized_path
));
734 ASSERT_TRUE(link_to
!= link_from
);
735 ASSERT_EQ(link_to
.BaseName().value(), normalized_path
.BaseName().value());
736 ASSERT_EQ(link_to
.BaseName().value(), normalized_path
.BaseName().value());
738 // Link to a directory.
739 link_from
= temp_dir_
.path().Append(FPL("from_dir"));
740 link_to
= temp_dir_
.path().Append(FPL("to_dir"));
741 file_util::CreateDirectory(link_to
);
743 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to
, link_from
))
744 << "Failed to create directory symlink.";
746 ASSERT_FALSE(file_util::NormalizeFilePath(link_from
, &normalized_path
))
747 << "Links to directories should return false.";
749 // Test that a loop in the links causes NormalizeFilePath() to return false.
750 link_from
= temp_dir_
.path().Append(FPL("link_a"));
751 link_to
= temp_dir_
.path().Append(FPL("link_b"));
752 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to
, link_from
))
753 << "Failed to create loop symlink a.";
754 ASSERT_TRUE(file_util::CreateSymbolicLink(link_from
, link_to
))
755 << "Failed to create loop symlink b.";
758 ASSERT_FALSE(file_util::NormalizeFilePath(link_from
, &normalized_path
));
760 #endif // defined(OS_POSIX)
762 TEST_F(FileUtilTest
, DeleteNonExistent
) {
763 FilePath non_existent
= temp_dir_
.path().AppendASCII("bogus_file_dne.foobar");
764 ASSERT_FALSE(file_util::PathExists(non_existent
));
766 EXPECT_TRUE(file_util::Delete(non_existent
, false));
767 ASSERT_FALSE(file_util::PathExists(non_existent
));
768 EXPECT_TRUE(file_util::Delete(non_existent
, true));
769 ASSERT_FALSE(file_util::PathExists(non_existent
));
772 TEST_F(FileUtilTest
, DeleteFile
) {
774 FilePath file_name
= temp_dir_
.path().Append(FPL("Test DeleteFile 1.txt"));
775 CreateTextFile(file_name
, bogus_content
);
776 ASSERT_TRUE(file_util::PathExists(file_name
));
778 // Make sure it's deleted
779 EXPECT_TRUE(file_util::Delete(file_name
, false));
780 EXPECT_FALSE(file_util::PathExists(file_name
));
782 // Test recursive case, create a new file
783 file_name
= temp_dir_
.path().Append(FPL("Test DeleteFile 2.txt"));
784 CreateTextFile(file_name
, bogus_content
);
785 ASSERT_TRUE(file_util::PathExists(file_name
));
787 // Make sure it's deleted
788 EXPECT_TRUE(file_util::Delete(file_name
, true));
789 EXPECT_FALSE(file_util::PathExists(file_name
));
792 #if defined(OS_POSIX)
793 TEST_F(FileUtilTest
, DeleteSymlinkToExistentFile
) {
795 FilePath file_name
= temp_dir_
.path().Append(FPL("Test DeleteFile 2.txt"));
796 CreateTextFile(file_name
, bogus_content
);
797 ASSERT_TRUE(file_util::PathExists(file_name
));
799 // Create a symlink to the file.
800 FilePath file_link
= temp_dir_
.path().Append("file_link_2");
801 ASSERT_TRUE(file_util::CreateSymbolicLink(file_name
, file_link
))
802 << "Failed to create symlink.";
804 // Delete the symbolic link.
805 EXPECT_TRUE(file_util::Delete(file_link
, false));
807 // Make sure original file is not deleted.
808 EXPECT_FALSE(file_util::PathExists(file_link
));
809 EXPECT_TRUE(file_util::PathExists(file_name
));
812 TEST_F(FileUtilTest
, DeleteSymlinkToNonExistentFile
) {
813 // Create a non-existent file path.
814 FilePath non_existent
= temp_dir_
.path().Append(FPL("Test DeleteFile 3.txt"));
815 EXPECT_FALSE(file_util::PathExists(non_existent
));
817 // Create a symlink to the non-existent file.
818 FilePath file_link
= temp_dir_
.path().Append("file_link_3");
819 ASSERT_TRUE(file_util::CreateSymbolicLink(non_existent
, file_link
))
820 << "Failed to create symlink.";
822 // Make sure the symbolic link is exist.
823 EXPECT_TRUE(file_util::IsLink(file_link
));
824 EXPECT_FALSE(file_util::PathExists(file_link
));
826 // Delete the symbolic link.
827 EXPECT_TRUE(file_util::Delete(file_link
, false));
829 // Make sure the symbolic link is deleted.
830 EXPECT_FALSE(file_util::IsLink(file_link
));
833 TEST_F(FileUtilTest
, ChangeFilePermissionsAndRead
) {
834 // Create a file path.
835 FilePath file_name
= temp_dir_
.path().Append(FPL("Test Readable File.txt"));
836 EXPECT_FALSE(file_util::PathExists(file_name
));
838 const std::string
kData("hello");
840 int buffer_size
= kData
.length();
841 char* buffer
= new char[buffer_size
];
844 EXPECT_EQ(static_cast<int>(kData
.length()),
845 file_util::WriteFile(file_name
, kData
.data(), kData
.length()));
846 EXPECT_TRUE(file_util::PathExists(file_name
));
848 // Make sure the file is readable.
850 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name
, &mode
));
851 EXPECT_TRUE(mode
& file_util::FILE_PERMISSION_READ_BY_USER
);
853 // Get rid of the read permission.
854 EXPECT_TRUE(file_util::SetPosixFilePermissions(file_name
, 0u));
855 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name
, &mode
));
856 EXPECT_FALSE(mode
& file_util::FILE_PERMISSION_READ_BY_USER
);
857 // Make sure the file can't be read.
858 EXPECT_EQ(-1, file_util::ReadFile(file_name
, buffer
, buffer_size
));
860 // Give the read permission.
861 EXPECT_TRUE(file_util::SetPosixFilePermissions(
863 file_util::FILE_PERMISSION_READ_BY_USER
));
864 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name
, &mode
));
865 EXPECT_TRUE(mode
& file_util::FILE_PERMISSION_READ_BY_USER
);
866 // Make sure the file can be read.
867 EXPECT_EQ(static_cast<int>(kData
.length()),
868 file_util::ReadFile(file_name
, buffer
, buffer_size
));
871 EXPECT_TRUE(file_util::Delete(file_name
, false));
872 EXPECT_FALSE(file_util::PathExists(file_name
));
877 TEST_F(FileUtilTest
, ChangeFilePermissionsAndWrite
) {
878 // Create a file path.
879 FilePath file_name
= temp_dir_
.path().Append(FPL("Test Readable File.txt"));
880 EXPECT_FALSE(file_util::PathExists(file_name
));
882 const std::string
kData("hello");
885 EXPECT_EQ(static_cast<int>(kData
.length()),
886 file_util::WriteFile(file_name
, kData
.data(), kData
.length()));
887 EXPECT_TRUE(file_util::PathExists(file_name
));
889 // Make sure the file is writable.
891 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name
, &mode
));
892 EXPECT_TRUE(mode
& file_util::FILE_PERMISSION_WRITE_BY_USER
);
893 EXPECT_TRUE(file_util::PathIsWritable(file_name
));
895 // Get rid of the write permission.
896 EXPECT_TRUE(file_util::SetPosixFilePermissions(file_name
, 0u));
897 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name
, &mode
));
898 EXPECT_FALSE(mode
& file_util::FILE_PERMISSION_WRITE_BY_USER
);
899 // Make sure the file can't be write.
901 file_util::WriteFile(file_name
, kData
.data(), kData
.length()));
902 EXPECT_FALSE(file_util::PathIsWritable(file_name
));
904 // Give read permission.
905 EXPECT_TRUE(file_util::SetPosixFilePermissions(
907 file_util::FILE_PERMISSION_WRITE_BY_USER
));
908 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name
, &mode
));
909 EXPECT_TRUE(mode
& file_util::FILE_PERMISSION_WRITE_BY_USER
);
910 // Make sure the file can be write.
911 EXPECT_EQ(static_cast<int>(kData
.length()),
912 file_util::WriteFile(file_name
, kData
.data(), kData
.length()));
913 EXPECT_TRUE(file_util::PathIsWritable(file_name
));
916 EXPECT_TRUE(file_util::Delete(file_name
, false));
917 EXPECT_FALSE(file_util::PathExists(file_name
));
920 TEST_F(FileUtilTest
, ChangeDirectoryPermissionsAndEnumerate
) {
921 // Create a directory path.
922 FilePath subdir_path
=
923 temp_dir_
.path().Append(FPL("PermissionTest1"));
924 file_util::CreateDirectory(subdir_path
);
925 ASSERT_TRUE(file_util::PathExists(subdir_path
));
927 // Create a dummy file to enumerate.
928 FilePath file_name
= subdir_path
.Append(FPL("Test Readable File.txt"));
929 EXPECT_FALSE(file_util::PathExists(file_name
));
930 const std::string
kData("hello");
931 EXPECT_EQ(static_cast<int>(kData
.length()),
932 file_util::WriteFile(file_name
, kData
.data(), kData
.length()));
933 EXPECT_TRUE(file_util::PathExists(file_name
));
935 // Make sure the directory has the all permissions.
937 EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path
, &mode
));
938 EXPECT_EQ(file_util::FILE_PERMISSION_USER_MASK
,
939 mode
& file_util::FILE_PERMISSION_USER_MASK
);
941 // Get rid of the permissions from the directory.
942 EXPECT_TRUE(file_util::SetPosixFilePermissions(subdir_path
, 0u));
943 EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path
, &mode
));
944 EXPECT_FALSE(mode
& file_util::FILE_PERMISSION_USER_MASK
);
946 // Make sure the file in the directory can't be enumerated.
947 file_util::FileEnumerator
f1(subdir_path
, true,
948 file_util::FileEnumerator::FILES
);
949 EXPECT_TRUE(file_util::PathExists(subdir_path
));
950 FindResultCollector
c1(f1
);
951 EXPECT_EQ(c1
.size(), 0);
952 EXPECT_FALSE(file_util::GetPosixFilePermissions(file_name
, &mode
));
954 // Give the permissions to the directory.
955 EXPECT_TRUE(file_util::SetPosixFilePermissions(
957 file_util::FILE_PERMISSION_USER_MASK
));
958 EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path
, &mode
));
959 EXPECT_EQ(file_util::FILE_PERMISSION_USER_MASK
,
960 mode
& file_util::FILE_PERMISSION_USER_MASK
);
962 // Make sure the file in the directory can be enumerated.
963 file_util::FileEnumerator
f2(subdir_path
, true,
964 file_util::FileEnumerator::FILES
);
965 FindResultCollector
c2(f2
);
966 EXPECT_TRUE(c2
.HasFile(file_name
));
967 EXPECT_EQ(c2
.size(), 1);
970 EXPECT_TRUE(file_util::Delete(subdir_path
, true));
971 EXPECT_FALSE(file_util::PathExists(subdir_path
));
974 #endif // defined(OS_POSIX)
977 // Tests that the Delete function works for wild cards, especially
978 // with the recursion flag. Also coincidentally tests PathExists.
979 // TODO(erikkay): see if anyone's actually using this feature of the API
980 TEST_F(FileUtilTest
, DeleteWildCard
) {
981 // Create a file and a directory
982 FilePath file_name
= temp_dir_
.path().Append(FPL("Test DeleteWildCard.txt"));
983 CreateTextFile(file_name
, bogus_content
);
984 ASSERT_TRUE(file_util::PathExists(file_name
));
986 FilePath subdir_path
= temp_dir_
.path().Append(FPL("DeleteWildCardDir"));
987 file_util::CreateDirectory(subdir_path
);
988 ASSERT_TRUE(file_util::PathExists(subdir_path
));
990 // Create the wildcard path
991 FilePath directory_contents
= temp_dir_
.path();
992 directory_contents
= directory_contents
.Append(FPL("*"));
994 // Delete non-recursively and check that only the file is deleted
995 EXPECT_TRUE(file_util::Delete(directory_contents
, false));
996 EXPECT_FALSE(file_util::PathExists(file_name
));
997 EXPECT_TRUE(file_util::PathExists(subdir_path
));
999 // Delete recursively and make sure all contents are deleted
1000 EXPECT_TRUE(file_util::Delete(directory_contents
, true));
1001 EXPECT_FALSE(file_util::PathExists(file_name
));
1002 EXPECT_FALSE(file_util::PathExists(subdir_path
));
1005 // TODO(erikkay): see if anyone's actually using this feature of the API
1006 TEST_F(FileUtilTest
, DeleteNonExistantWildCard
) {
1007 // Create a file and a directory
1008 FilePath subdir_path
=
1009 temp_dir_
.path().Append(FPL("DeleteNonExistantWildCard"));
1010 file_util::CreateDirectory(subdir_path
);
1011 ASSERT_TRUE(file_util::PathExists(subdir_path
));
1013 // Create the wildcard path
1014 FilePath directory_contents
= subdir_path
;
1015 directory_contents
= directory_contents
.Append(FPL("*"));
1017 // Delete non-recursively and check nothing got deleted
1018 EXPECT_TRUE(file_util::Delete(directory_contents
, false));
1019 EXPECT_TRUE(file_util::PathExists(subdir_path
));
1021 // Delete recursively and check nothing got deleted
1022 EXPECT_TRUE(file_util::Delete(directory_contents
, true));
1023 EXPECT_TRUE(file_util::PathExists(subdir_path
));
1027 // Tests non-recursive Delete() for a directory.
1028 TEST_F(FileUtilTest
, DeleteDirNonRecursive
) {
1029 // Create a subdirectory and put a file and two directories inside.
1030 FilePath test_subdir
= temp_dir_
.path().Append(FPL("DeleteDirNonRecursive"));
1031 file_util::CreateDirectory(test_subdir
);
1032 ASSERT_TRUE(file_util::PathExists(test_subdir
));
1034 FilePath file_name
= test_subdir
.Append(FPL("Test DeleteDir.txt"));
1035 CreateTextFile(file_name
, bogus_content
);
1036 ASSERT_TRUE(file_util::PathExists(file_name
));
1038 FilePath subdir_path1
= test_subdir
.Append(FPL("TestSubDir1"));
1039 file_util::CreateDirectory(subdir_path1
);
1040 ASSERT_TRUE(file_util::PathExists(subdir_path1
));
1042 FilePath subdir_path2
= test_subdir
.Append(FPL("TestSubDir2"));
1043 file_util::CreateDirectory(subdir_path2
);
1044 ASSERT_TRUE(file_util::PathExists(subdir_path2
));
1046 // Delete non-recursively and check that the empty dir got deleted
1047 EXPECT_TRUE(file_util::Delete(subdir_path2
, false));
1048 EXPECT_FALSE(file_util::PathExists(subdir_path2
));
1050 // Delete non-recursively and check that nothing got deleted
1051 EXPECT_FALSE(file_util::Delete(test_subdir
, false));
1052 EXPECT_TRUE(file_util::PathExists(test_subdir
));
1053 EXPECT_TRUE(file_util::PathExists(file_name
));
1054 EXPECT_TRUE(file_util::PathExists(subdir_path1
));
1057 // Tests recursive Delete() for a directory.
1058 TEST_F(FileUtilTest
, DeleteDirRecursive
) {
1059 // Create a subdirectory and put a file and two directories inside.
1060 FilePath test_subdir
= temp_dir_
.path().Append(FPL("DeleteDirRecursive"));
1061 file_util::CreateDirectory(test_subdir
);
1062 ASSERT_TRUE(file_util::PathExists(test_subdir
));
1064 FilePath file_name
= test_subdir
.Append(FPL("Test DeleteDirRecursive.txt"));
1065 CreateTextFile(file_name
, bogus_content
);
1066 ASSERT_TRUE(file_util::PathExists(file_name
));
1068 FilePath subdir_path1
= test_subdir
.Append(FPL("TestSubDir1"));
1069 file_util::CreateDirectory(subdir_path1
);
1070 ASSERT_TRUE(file_util::PathExists(subdir_path1
));
1072 FilePath subdir_path2
= test_subdir
.Append(FPL("TestSubDir2"));
1073 file_util::CreateDirectory(subdir_path2
);
1074 ASSERT_TRUE(file_util::PathExists(subdir_path2
));
1076 // Delete recursively and check that the empty dir got deleted
1077 EXPECT_TRUE(file_util::Delete(subdir_path2
, true));
1078 EXPECT_FALSE(file_util::PathExists(subdir_path2
));
1080 // Delete recursively and check that everything got deleted
1081 EXPECT_TRUE(file_util::Delete(test_subdir
, true));
1082 EXPECT_FALSE(file_util::PathExists(file_name
));
1083 EXPECT_FALSE(file_util::PathExists(subdir_path1
));
1084 EXPECT_FALSE(file_util::PathExists(test_subdir
));
1087 TEST_F(FileUtilTest
, MoveFileNew
) {
1089 FilePath file_name_from
=
1090 temp_dir_
.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1091 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1092 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1095 FilePath file_name_to
= temp_dir_
.path().Append(
1096 FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
1097 ASSERT_FALSE(file_util::PathExists(file_name_to
));
1099 EXPECT_TRUE(file_util::Move(file_name_from
, file_name_to
));
1101 // Check everything has been moved.
1102 EXPECT_FALSE(file_util::PathExists(file_name_from
));
1103 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1106 TEST_F(FileUtilTest
, MoveFileExists
) {
1108 FilePath file_name_from
=
1109 temp_dir_
.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1110 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1111 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1113 // The destination name.
1114 FilePath file_name_to
= temp_dir_
.path().Append(
1115 FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
1116 CreateTextFile(file_name_to
, L
"Old file content");
1117 ASSERT_TRUE(file_util::PathExists(file_name_to
));
1119 EXPECT_TRUE(file_util::Move(file_name_from
, file_name_to
));
1121 // Check everything has been moved.
1122 EXPECT_FALSE(file_util::PathExists(file_name_from
));
1123 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1124 EXPECT_TRUE(L
"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to
));
1127 TEST_F(FileUtilTest
, MoveFileDirExists
) {
1129 FilePath file_name_from
=
1130 temp_dir_
.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1131 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1132 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1134 // The destination directory
1135 FilePath dir_name_to
=
1136 temp_dir_
.path().Append(FILE_PATH_LITERAL("Destination"));
1137 file_util::CreateDirectory(dir_name_to
);
1138 ASSERT_TRUE(file_util::PathExists(dir_name_to
));
1140 EXPECT_FALSE(file_util::Move(file_name_from
, dir_name_to
));
1144 TEST_F(FileUtilTest
, MoveNew
) {
1145 // Create a directory
1146 FilePath dir_name_from
=
1147 temp_dir_
.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1148 file_util::CreateDirectory(dir_name_from
);
1149 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1151 // Create a file under the directory
1152 FilePath file_name_from
=
1153 dir_name_from
.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1154 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1155 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1157 // Move the directory.
1158 FilePath dir_name_to
=
1159 temp_dir_
.path().Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1160 FilePath file_name_to
=
1161 dir_name_to
.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1163 ASSERT_FALSE(file_util::PathExists(dir_name_to
));
1165 EXPECT_TRUE(file_util::Move(dir_name_from
, dir_name_to
));
1167 // Check everything has been moved.
1168 EXPECT_FALSE(file_util::PathExists(dir_name_from
));
1169 EXPECT_FALSE(file_util::PathExists(file_name_from
));
1170 EXPECT_TRUE(file_util::PathExists(dir_name_to
));
1171 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1174 TEST_F(FileUtilTest
, MoveExist
) {
1175 // Create a directory
1176 FilePath dir_name_from
=
1177 temp_dir_
.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1178 file_util::CreateDirectory(dir_name_from
);
1179 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1181 // Create a file under the directory
1182 FilePath file_name_from
=
1183 dir_name_from
.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1184 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1185 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1187 // Move the directory
1188 FilePath dir_name_exists
=
1189 temp_dir_
.path().Append(FILE_PATH_LITERAL("Destination"));
1191 FilePath dir_name_to
=
1192 dir_name_exists
.Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1193 FilePath file_name_to
=
1194 dir_name_to
.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1196 // Create the destination directory.
1197 file_util::CreateDirectory(dir_name_exists
);
1198 ASSERT_TRUE(file_util::PathExists(dir_name_exists
));
1200 EXPECT_TRUE(file_util::Move(dir_name_from
, dir_name_to
));
1202 // Check everything has been moved.
1203 EXPECT_FALSE(file_util::PathExists(dir_name_from
));
1204 EXPECT_FALSE(file_util::PathExists(file_name_from
));
1205 EXPECT_TRUE(file_util::PathExists(dir_name_to
));
1206 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1209 TEST_F(FileUtilTest
, CopyDirectoryRecursivelyNew
) {
1210 // Create a directory.
1211 FilePath dir_name_from
=
1212 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1213 file_util::CreateDirectory(dir_name_from
);
1214 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1216 // Create a file under the directory.
1217 FilePath file_name_from
=
1218 dir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1219 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1220 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1222 // Create a subdirectory.
1223 FilePath subdir_name_from
=
1224 dir_name_from
.Append(FILE_PATH_LITERAL("Subdir"));
1225 file_util::CreateDirectory(subdir_name_from
);
1226 ASSERT_TRUE(file_util::PathExists(subdir_name_from
));
1228 // Create a file under the subdirectory.
1229 FilePath file_name2_from
=
1230 subdir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1231 CreateTextFile(file_name2_from
, L
"Gooooooooooooooooooooogle");
1232 ASSERT_TRUE(file_util::PathExists(file_name2_from
));
1234 // Copy the directory recursively.
1235 FilePath dir_name_to
=
1236 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1237 FilePath file_name_to
=
1238 dir_name_to
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1239 FilePath subdir_name_to
=
1240 dir_name_to
.Append(FILE_PATH_LITERAL("Subdir"));
1241 FilePath file_name2_to
=
1242 subdir_name_to
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1244 ASSERT_FALSE(file_util::PathExists(dir_name_to
));
1246 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from
, dir_name_to
, true));
1248 // Check everything has been copied.
1249 EXPECT_TRUE(file_util::PathExists(dir_name_from
));
1250 EXPECT_TRUE(file_util::PathExists(file_name_from
));
1251 EXPECT_TRUE(file_util::PathExists(subdir_name_from
));
1252 EXPECT_TRUE(file_util::PathExists(file_name2_from
));
1253 EXPECT_TRUE(file_util::PathExists(dir_name_to
));
1254 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1255 EXPECT_TRUE(file_util::PathExists(subdir_name_to
));
1256 EXPECT_TRUE(file_util::PathExists(file_name2_to
));
1259 TEST_F(FileUtilTest
, CopyDirectoryRecursivelyExists
) {
1260 // Create a directory.
1261 FilePath dir_name_from
=
1262 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1263 file_util::CreateDirectory(dir_name_from
);
1264 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1266 // Create a file under the directory.
1267 FilePath file_name_from
=
1268 dir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1269 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1270 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1272 // Create a subdirectory.
1273 FilePath subdir_name_from
=
1274 dir_name_from
.Append(FILE_PATH_LITERAL("Subdir"));
1275 file_util::CreateDirectory(subdir_name_from
);
1276 ASSERT_TRUE(file_util::PathExists(subdir_name_from
));
1278 // Create a file under the subdirectory.
1279 FilePath file_name2_from
=
1280 subdir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1281 CreateTextFile(file_name2_from
, L
"Gooooooooooooooooooooogle");
1282 ASSERT_TRUE(file_util::PathExists(file_name2_from
));
1284 // Copy the directory recursively.
1285 FilePath dir_name_exists
=
1286 temp_dir_
.path().Append(FILE_PATH_LITERAL("Destination"));
1288 FilePath dir_name_to
=
1289 dir_name_exists
.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1290 FilePath file_name_to
=
1291 dir_name_to
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1292 FilePath subdir_name_to
=
1293 dir_name_to
.Append(FILE_PATH_LITERAL("Subdir"));
1294 FilePath file_name2_to
=
1295 subdir_name_to
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1297 // Create the destination directory.
1298 file_util::CreateDirectory(dir_name_exists
);
1299 ASSERT_TRUE(file_util::PathExists(dir_name_exists
));
1301 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from
, dir_name_exists
, true));
1303 // Check everything has been copied.
1304 EXPECT_TRUE(file_util::PathExists(dir_name_from
));
1305 EXPECT_TRUE(file_util::PathExists(file_name_from
));
1306 EXPECT_TRUE(file_util::PathExists(subdir_name_from
));
1307 EXPECT_TRUE(file_util::PathExists(file_name2_from
));
1308 EXPECT_TRUE(file_util::PathExists(dir_name_to
));
1309 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1310 EXPECT_TRUE(file_util::PathExists(subdir_name_to
));
1311 EXPECT_TRUE(file_util::PathExists(file_name2_to
));
1314 TEST_F(FileUtilTest
, CopyDirectoryNew
) {
1315 // Create a directory.
1316 FilePath dir_name_from
=
1317 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1318 file_util::CreateDirectory(dir_name_from
);
1319 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1321 // Create a file under the directory.
1322 FilePath file_name_from
=
1323 dir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1324 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1325 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1327 // Create a subdirectory.
1328 FilePath subdir_name_from
=
1329 dir_name_from
.Append(FILE_PATH_LITERAL("Subdir"));
1330 file_util::CreateDirectory(subdir_name_from
);
1331 ASSERT_TRUE(file_util::PathExists(subdir_name_from
));
1333 // Create a file under the subdirectory.
1334 FilePath file_name2_from
=
1335 subdir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1336 CreateTextFile(file_name2_from
, L
"Gooooooooooooooooooooogle");
1337 ASSERT_TRUE(file_util::PathExists(file_name2_from
));
1339 // Copy the directory not recursively.
1340 FilePath dir_name_to
=
1341 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1342 FilePath file_name_to
=
1343 dir_name_to
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1344 FilePath subdir_name_to
=
1345 dir_name_to
.Append(FILE_PATH_LITERAL("Subdir"));
1347 ASSERT_FALSE(file_util::PathExists(dir_name_to
));
1349 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from
, dir_name_to
, false));
1351 // Check everything has been copied.
1352 EXPECT_TRUE(file_util::PathExists(dir_name_from
));
1353 EXPECT_TRUE(file_util::PathExists(file_name_from
));
1354 EXPECT_TRUE(file_util::PathExists(subdir_name_from
));
1355 EXPECT_TRUE(file_util::PathExists(file_name2_from
));
1356 EXPECT_TRUE(file_util::PathExists(dir_name_to
));
1357 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1358 EXPECT_FALSE(file_util::PathExists(subdir_name_to
));
1361 TEST_F(FileUtilTest
, CopyDirectoryExists
) {
1362 // Create a directory.
1363 FilePath dir_name_from
=
1364 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1365 file_util::CreateDirectory(dir_name_from
);
1366 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1368 // Create a file under the directory.
1369 FilePath file_name_from
=
1370 dir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1371 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1372 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1374 // Create a subdirectory.
1375 FilePath subdir_name_from
=
1376 dir_name_from
.Append(FILE_PATH_LITERAL("Subdir"));
1377 file_util::CreateDirectory(subdir_name_from
);
1378 ASSERT_TRUE(file_util::PathExists(subdir_name_from
));
1380 // Create a file under the subdirectory.
1381 FilePath file_name2_from
=
1382 subdir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1383 CreateTextFile(file_name2_from
, L
"Gooooooooooooooooooooogle");
1384 ASSERT_TRUE(file_util::PathExists(file_name2_from
));
1386 // Copy the directory not recursively.
1387 FilePath dir_name_to
=
1388 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1389 FilePath file_name_to
=
1390 dir_name_to
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1391 FilePath subdir_name_to
=
1392 dir_name_to
.Append(FILE_PATH_LITERAL("Subdir"));
1394 // Create the destination directory.
1395 file_util::CreateDirectory(dir_name_to
);
1396 ASSERT_TRUE(file_util::PathExists(dir_name_to
));
1398 EXPECT_TRUE(file_util::CopyDirectory(dir_name_from
, dir_name_to
, false));
1400 // Check everything has been copied.
1401 EXPECT_TRUE(file_util::PathExists(dir_name_from
));
1402 EXPECT_TRUE(file_util::PathExists(file_name_from
));
1403 EXPECT_TRUE(file_util::PathExists(subdir_name_from
));
1404 EXPECT_TRUE(file_util::PathExists(file_name2_from
));
1405 EXPECT_TRUE(file_util::PathExists(dir_name_to
));
1406 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1407 EXPECT_FALSE(file_util::PathExists(subdir_name_to
));
1410 TEST_F(FileUtilTest
, CopyFileWithCopyDirectoryRecursiveToNew
) {
1412 FilePath file_name_from
=
1413 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1414 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1415 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1417 // The destination name
1418 FilePath file_name_to
= temp_dir_
.path().Append(
1419 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1420 ASSERT_FALSE(file_util::PathExists(file_name_to
));
1422 EXPECT_TRUE(file_util::CopyDirectory(file_name_from
, file_name_to
, true));
1424 // Check the has been copied
1425 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1428 TEST_F(FileUtilTest
, CopyFileWithCopyDirectoryRecursiveToExisting
) {
1430 FilePath file_name_from
=
1431 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1432 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1433 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1435 // The destination name
1436 FilePath file_name_to
= temp_dir_
.path().Append(
1437 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1438 CreateTextFile(file_name_to
, L
"Old file content");
1439 ASSERT_TRUE(file_util::PathExists(file_name_to
));
1441 EXPECT_TRUE(file_util::CopyDirectory(file_name_from
, file_name_to
, true));
1443 // Check the has been copied
1444 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1445 EXPECT_TRUE(L
"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to
));
1448 TEST_F(FileUtilTest
, CopyFileWithCopyDirectoryRecursiveToExistingDirectory
) {
1450 FilePath file_name_from
=
1451 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1452 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1453 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1456 FilePath dir_name_to
=
1457 temp_dir_
.path().Append(FILE_PATH_LITERAL("Destination"));
1458 file_util::CreateDirectory(dir_name_to
);
1459 ASSERT_TRUE(file_util::PathExists(dir_name_to
));
1460 FilePath file_name_to
=
1461 dir_name_to
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1463 EXPECT_TRUE(file_util::CopyDirectory(file_name_from
, dir_name_to
, true));
1465 // Check the has been copied
1466 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1469 TEST_F(FileUtilTest
, CopyFile
) {
1470 // Create a directory
1471 FilePath dir_name_from
=
1472 temp_dir_
.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1473 file_util::CreateDirectory(dir_name_from
);
1474 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1476 // Create a file under the directory
1477 FilePath file_name_from
=
1478 dir_name_from
.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1479 const std::wstring
file_contents(L
"Gooooooooooooooooooooogle");
1480 CreateTextFile(file_name_from
, file_contents
);
1481 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1484 FilePath dest_file
= dir_name_from
.Append(FILE_PATH_LITERAL("DestFile.txt"));
1485 ASSERT_TRUE(file_util::CopyFile(file_name_from
, dest_file
));
1487 // Copy the file to another location using '..' in the path.
1488 FilePath
dest_file2(dir_name_from
);
1489 dest_file2
= dest_file2
.AppendASCII("..");
1490 dest_file2
= dest_file2
.AppendASCII("DestFile.txt");
1491 ASSERT_TRUE(file_util::CopyFile(file_name_from
, dest_file2
));
1493 FilePath
dest_file2_test(dir_name_from
);
1494 dest_file2_test
= dest_file2_test
.DirName();
1495 dest_file2_test
= dest_file2_test
.AppendASCII("DestFile.txt");
1497 // Check everything has been copied.
1498 EXPECT_TRUE(file_util::PathExists(file_name_from
));
1499 EXPECT_TRUE(file_util::PathExists(dest_file
));
1500 const std::wstring read_contents
= ReadTextFile(dest_file
);
1501 EXPECT_EQ(file_contents
, read_contents
);
1502 EXPECT_TRUE(file_util::PathExists(dest_file2_test
));
1503 EXPECT_TRUE(file_util::PathExists(dest_file2
));
1506 // TODO(erikkay): implement
1508 TEST_F(FileUtilTest
, GetFileCreationLocalTime
) {
1509 FilePath file_name
= temp_dir_
.path().Append(L
"Test File.txt");
1511 SYSTEMTIME start_time
;
1512 GetLocalTime(&start_time
);
1513 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
1514 CreateTextFile(file_name
, L
"New file!");
1515 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
1516 SYSTEMTIME end_time
;
1517 GetLocalTime(&end_time
);
1519 SYSTEMTIME file_creation_time
;
1520 file_util::GetFileCreationLocalTime(file_name
.value(), &file_creation_time
);
1522 FILETIME start_filetime
;
1523 SystemTimeToFileTime(&start_time
, &start_filetime
);
1524 FILETIME end_filetime
;
1525 SystemTimeToFileTime(&end_time
, &end_filetime
);
1526 FILETIME file_creation_filetime
;
1527 SystemTimeToFileTime(&file_creation_time
, &file_creation_filetime
);
1529 EXPECT_EQ(-1, CompareFileTime(&start_filetime
, &file_creation_filetime
)) <<
1530 "start time: " << FileTimeAsUint64(start_filetime
) << ", " <<
1531 "creation time: " << FileTimeAsUint64(file_creation_filetime
);
1533 EXPECT_EQ(-1, CompareFileTime(&file_creation_filetime
, &end_filetime
)) <<
1534 "creation time: " << FileTimeAsUint64(file_creation_filetime
) << ", " <<
1535 "end time: " << FileTimeAsUint64(end_filetime
);
1537 ASSERT_TRUE(DeleteFile(file_name
.value().c_str()));
1541 // file_util winds up using autoreleased objects on the Mac, so this needs
1542 // to be a PlatformTest.
1543 typedef PlatformTest ReadOnlyFileUtilTest
;
1545 TEST_F(ReadOnlyFileUtilTest
, ContentsEqual
) {
1547 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &data_dir
));
1548 data_dir
= data_dir
.Append(FILE_PATH_LITERAL("base"))
1549 .Append(FILE_PATH_LITERAL("data"))
1550 .Append(FILE_PATH_LITERAL("file_util_unittest"));
1551 ASSERT_TRUE(file_util::PathExists(data_dir
));
1553 FilePath original_file
=
1554 data_dir
.Append(FILE_PATH_LITERAL("original.txt"));
1555 FilePath same_file
=
1556 data_dir
.Append(FILE_PATH_LITERAL("same.txt"));
1557 FilePath same_length_file
=
1558 data_dir
.Append(FILE_PATH_LITERAL("same_length.txt"));
1559 FilePath different_file
=
1560 data_dir
.Append(FILE_PATH_LITERAL("different.txt"));
1561 FilePath different_first_file
=
1562 data_dir
.Append(FILE_PATH_LITERAL("different_first.txt"));
1563 FilePath different_last_file
=
1564 data_dir
.Append(FILE_PATH_LITERAL("different_last.txt"));
1565 FilePath empty1_file
=
1566 data_dir
.Append(FILE_PATH_LITERAL("empty1.txt"));
1567 FilePath empty2_file
=
1568 data_dir
.Append(FILE_PATH_LITERAL("empty2.txt"));
1569 FilePath shortened_file
=
1570 data_dir
.Append(FILE_PATH_LITERAL("shortened.txt"));
1571 FilePath binary_file
=
1572 data_dir
.Append(FILE_PATH_LITERAL("binary_file.bin"));
1573 FilePath binary_file_same
=
1574 data_dir
.Append(FILE_PATH_LITERAL("binary_file_same.bin"));
1575 FilePath binary_file_diff
=
1576 data_dir
.Append(FILE_PATH_LITERAL("binary_file_diff.bin"));
1578 EXPECT_TRUE(file_util::ContentsEqual(original_file
, original_file
));
1579 EXPECT_TRUE(file_util::ContentsEqual(original_file
, same_file
));
1580 EXPECT_FALSE(file_util::ContentsEqual(original_file
, same_length_file
));
1581 EXPECT_FALSE(file_util::ContentsEqual(original_file
, different_file
));
1582 EXPECT_FALSE(file_util::ContentsEqual(
1583 FilePath(FILE_PATH_LITERAL("bogusname")),
1584 FilePath(FILE_PATH_LITERAL("bogusname"))));
1585 EXPECT_FALSE(file_util::ContentsEqual(original_file
, different_first_file
));
1586 EXPECT_FALSE(file_util::ContentsEqual(original_file
, different_last_file
));
1587 EXPECT_TRUE(file_util::ContentsEqual(empty1_file
, empty2_file
));
1588 EXPECT_FALSE(file_util::ContentsEqual(original_file
, shortened_file
));
1589 EXPECT_FALSE(file_util::ContentsEqual(shortened_file
, original_file
));
1590 EXPECT_TRUE(file_util::ContentsEqual(binary_file
, binary_file_same
));
1591 EXPECT_FALSE(file_util::ContentsEqual(binary_file
, binary_file_diff
));
1594 TEST_F(ReadOnlyFileUtilTest
, TextContentsEqual
) {
1596 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &data_dir
));
1597 data_dir
= data_dir
.Append(FILE_PATH_LITERAL("base"))
1598 .Append(FILE_PATH_LITERAL("data"))
1599 .Append(FILE_PATH_LITERAL("file_util_unittest"));
1600 ASSERT_TRUE(file_util::PathExists(data_dir
));
1602 FilePath original_file
=
1603 data_dir
.Append(FILE_PATH_LITERAL("original.txt"));
1604 FilePath same_file
=
1605 data_dir
.Append(FILE_PATH_LITERAL("same.txt"));
1606 FilePath crlf_file
=
1607 data_dir
.Append(FILE_PATH_LITERAL("crlf.txt"));
1608 FilePath shortened_file
=
1609 data_dir
.Append(FILE_PATH_LITERAL("shortened.txt"));
1610 FilePath different_file
=
1611 data_dir
.Append(FILE_PATH_LITERAL("different.txt"));
1612 FilePath different_first_file
=
1613 data_dir
.Append(FILE_PATH_LITERAL("different_first.txt"));
1614 FilePath different_last_file
=
1615 data_dir
.Append(FILE_PATH_LITERAL("different_last.txt"));
1616 FilePath first1_file
=
1617 data_dir
.Append(FILE_PATH_LITERAL("first1.txt"));
1618 FilePath first2_file
=
1619 data_dir
.Append(FILE_PATH_LITERAL("first2.txt"));
1620 FilePath empty1_file
=
1621 data_dir
.Append(FILE_PATH_LITERAL("empty1.txt"));
1622 FilePath empty2_file
=
1623 data_dir
.Append(FILE_PATH_LITERAL("empty2.txt"));
1624 FilePath blank_line_file
=
1625 data_dir
.Append(FILE_PATH_LITERAL("blank_line.txt"));
1626 FilePath blank_line_crlf_file
=
1627 data_dir
.Append(FILE_PATH_LITERAL("blank_line_crlf.txt"));
1629 EXPECT_TRUE(file_util::TextContentsEqual(original_file
, same_file
));
1630 EXPECT_TRUE(file_util::TextContentsEqual(original_file
, crlf_file
));
1631 EXPECT_FALSE(file_util::TextContentsEqual(original_file
, shortened_file
));
1632 EXPECT_FALSE(file_util::TextContentsEqual(original_file
, different_file
));
1633 EXPECT_FALSE(file_util::TextContentsEqual(original_file
,
1634 different_first_file
));
1635 EXPECT_FALSE(file_util::TextContentsEqual(original_file
,
1636 different_last_file
));
1637 EXPECT_FALSE(file_util::TextContentsEqual(first1_file
, first2_file
));
1638 EXPECT_TRUE(file_util::TextContentsEqual(empty1_file
, empty2_file
));
1639 EXPECT_FALSE(file_util::TextContentsEqual(original_file
, empty1_file
));
1640 EXPECT_TRUE(file_util::TextContentsEqual(blank_line_file
,
1641 blank_line_crlf_file
));
1644 // We don't need equivalent functionality outside of Windows.
1646 TEST_F(FileUtilTest
, CopyAndDeleteDirectoryTest
) {
1647 // Create a directory
1648 FilePath dir_name_from
=
1649 temp_dir_
.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir"));
1650 file_util::CreateDirectory(dir_name_from
);
1651 ASSERT_TRUE(file_util::PathExists(dir_name_from
));
1653 // Create a file under the directory
1654 FilePath file_name_from
=
1655 dir_name_from
.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
1656 CreateTextFile(file_name_from
, L
"Gooooooooooooooooooooogle");
1657 ASSERT_TRUE(file_util::PathExists(file_name_from
));
1659 // Move the directory by using CopyAndDeleteDirectory
1660 FilePath dir_name_to
= temp_dir_
.path().Append(
1661 FILE_PATH_LITERAL("CopyAndDelete_To_Subdir"));
1662 FilePath file_name_to
=
1663 dir_name_to
.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
1665 ASSERT_FALSE(file_util::PathExists(dir_name_to
));
1667 EXPECT_TRUE(file_util::CopyAndDeleteDirectory(dir_name_from
, dir_name_to
));
1669 // Check everything has been moved.
1670 EXPECT_FALSE(file_util::PathExists(dir_name_from
));
1671 EXPECT_FALSE(file_util::PathExists(file_name_from
));
1672 EXPECT_TRUE(file_util::PathExists(dir_name_to
));
1673 EXPECT_TRUE(file_util::PathExists(file_name_to
));
1676 TEST_F(FileUtilTest
, GetTempDirTest
) {
1677 static const TCHAR
* kTmpKey
= _T("TMP");
1678 static const TCHAR
* kTmpValues
[] = {
1679 _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\")
1681 // Save the original $TMP.
1682 size_t original_tmp_size
;
1683 TCHAR
* original_tmp
;
1684 ASSERT_EQ(0, ::_tdupenv_s(&original_tmp
, &original_tmp_size
, kTmpKey
));
1685 // original_tmp may be NULL.
1687 for (unsigned int i
= 0; i
< arraysize(kTmpValues
); ++i
) {
1689 ::_tputenv_s(kTmpKey
, kTmpValues
[i
]);
1690 file_util::GetTempDir(&path
);
1691 EXPECT_TRUE(path
.IsAbsolute()) << "$TMP=" << kTmpValues
[i
] <<
1692 " result=" << path
.value();
1695 // Restore the original $TMP.
1697 ::_tputenv_s(kTmpKey
, original_tmp
);
1700 ::_tputenv_s(kTmpKey
, _T(""));
1705 TEST_F(FileUtilTest
, CreateTemporaryFileTest
) {
1706 FilePath temp_files
[3];
1707 for (int i
= 0; i
< 3; i
++) {
1708 ASSERT_TRUE(file_util::CreateTemporaryFile(&(temp_files
[i
])));
1709 EXPECT_TRUE(file_util::PathExists(temp_files
[i
]));
1710 EXPECT_FALSE(file_util::DirectoryExists(temp_files
[i
]));
1712 for (int i
= 0; i
< 3; i
++)
1713 EXPECT_FALSE(temp_files
[i
] == temp_files
[(i
+1)%3]);
1714 for (int i
= 0; i
< 3; i
++)
1715 EXPECT_TRUE(file_util::Delete(temp_files
[i
], false));
1718 TEST_F(FileUtilTest
, CreateAndOpenTemporaryFileTest
) {
1723 // Create; make sure they are open and exist.
1724 for (i
= 0; i
< 3; ++i
) {
1725 fps
[i
] = file_util::CreateAndOpenTemporaryFile(&(names
[i
]));
1726 ASSERT_TRUE(fps
[i
]);
1727 EXPECT_TRUE(file_util::PathExists(names
[i
]));
1730 // Make sure all names are unique.
1731 for (i
= 0; i
< 3; ++i
) {
1732 EXPECT_FALSE(names
[i
] == names
[(i
+1)%3]);
1735 // Close and delete.
1736 for (i
= 0; i
< 3; ++i
) {
1737 EXPECT_TRUE(file_util::CloseFile(fps
[i
]));
1738 EXPECT_TRUE(file_util::Delete(names
[i
], false));
1742 TEST_F(FileUtilTest
, CreateNewTempDirectoryTest
) {
1744 ASSERT_TRUE(file_util::CreateNewTempDirectory(FilePath::StringType(),
1746 EXPECT_TRUE(file_util::PathExists(temp_dir
));
1747 EXPECT_TRUE(file_util::Delete(temp_dir
, false));
1750 TEST_F(FileUtilTest
, CreateNewTemporaryDirInDirTest
) {
1752 ASSERT_TRUE(file_util::CreateTemporaryDirInDir(
1754 FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"),
1756 EXPECT_TRUE(file_util::PathExists(new_dir
));
1757 EXPECT_TRUE(temp_dir_
.path().IsParent(new_dir
));
1758 EXPECT_TRUE(file_util::Delete(new_dir
, false));
1761 TEST_F(FileUtilTest
, GetShmemTempDirTest
) {
1763 EXPECT_TRUE(file_util::GetShmemTempDir(&dir
, false));
1764 EXPECT_TRUE(file_util::DirectoryExists(dir
));
1767 TEST_F(FileUtilTest
, CreateDirectoryTest
) {
1768 FilePath test_root
=
1769 temp_dir_
.path().Append(FILE_PATH_LITERAL("create_directory_test"));
1771 FilePath test_path
=
1772 test_root
.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\"));
1773 #elif defined(OS_POSIX)
1774 FilePath test_path
=
1775 test_root
.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/"));
1778 EXPECT_FALSE(file_util::PathExists(test_path
));
1779 EXPECT_TRUE(file_util::CreateDirectory(test_path
));
1780 EXPECT_TRUE(file_util::PathExists(test_path
));
1781 // CreateDirectory returns true if the DirectoryExists returns true.
1782 EXPECT_TRUE(file_util::CreateDirectory(test_path
));
1784 // Doesn't work to create it on top of a non-dir
1785 test_path
= test_path
.Append(FILE_PATH_LITERAL("foobar.txt"));
1786 EXPECT_FALSE(file_util::PathExists(test_path
));
1787 CreateTextFile(test_path
, L
"test file");
1788 EXPECT_TRUE(file_util::PathExists(test_path
));
1789 EXPECT_FALSE(file_util::CreateDirectory(test_path
));
1791 EXPECT_TRUE(file_util::Delete(test_root
, true));
1792 EXPECT_FALSE(file_util::PathExists(test_root
));
1793 EXPECT_FALSE(file_util::PathExists(test_path
));
1795 // Verify assumptions made by the Windows implementation:
1796 // 1. The current directory always exists.
1797 // 2. The root directory always exists.
1798 ASSERT_TRUE(file_util::DirectoryExists(
1799 FilePath(FilePath::kCurrentDirectory
)));
1800 FilePath top_level
= test_root
;
1801 while (top_level
!= top_level
.DirName()) {
1802 top_level
= top_level
.DirName();
1804 ASSERT_TRUE(file_util::DirectoryExists(top_level
));
1806 // Given these assumptions hold, it should be safe to
1807 // test that "creating" these directories succeeds.
1808 EXPECT_TRUE(file_util::CreateDirectory(
1809 FilePath(FilePath::kCurrentDirectory
)));
1810 EXPECT_TRUE(file_util::CreateDirectory(top_level
));
1813 FilePath
invalid_drive(FILE_PATH_LITERAL("o:\\"));
1814 FilePath invalid_path
=
1815 invalid_drive
.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir"));
1816 if (!file_util::PathExists(invalid_drive
)) {
1817 EXPECT_FALSE(file_util::CreateDirectory(invalid_path
));
1822 TEST_F(FileUtilTest
, DetectDirectoryTest
) {
1823 // Check a directory
1824 FilePath test_root
=
1825 temp_dir_
.path().Append(FILE_PATH_LITERAL("detect_directory_test"));
1826 EXPECT_FALSE(file_util::PathExists(test_root
));
1827 EXPECT_TRUE(file_util::CreateDirectory(test_root
));
1828 EXPECT_TRUE(file_util::PathExists(test_root
));
1829 EXPECT_TRUE(file_util::DirectoryExists(test_root
));
1831 FilePath test_path
=
1832 test_root
.Append(FILE_PATH_LITERAL("foobar.txt"));
1833 EXPECT_FALSE(file_util::PathExists(test_path
));
1834 CreateTextFile(test_path
, L
"test file");
1835 EXPECT_TRUE(file_util::PathExists(test_path
));
1836 EXPECT_FALSE(file_util::DirectoryExists(test_path
));
1837 EXPECT_TRUE(file_util::Delete(test_path
, false));
1839 EXPECT_TRUE(file_util::Delete(test_root
, true));
1842 TEST_F(FileUtilTest
, FileEnumeratorTest
) {
1843 // Test an empty directory.
1844 file_util::FileEnumerator
f0(temp_dir_
.path(), true, FILES_AND_DIRECTORIES
);
1845 EXPECT_EQ(f0
.Next().value(), FILE_PATH_LITERAL(""));
1846 EXPECT_EQ(f0
.Next().value(), FILE_PATH_LITERAL(""));
1848 // Test an empty directory, non-recursively, including "..".
1849 file_util::FileEnumerator
f0_dotdot(temp_dir_
.path(), false,
1850 FILES_AND_DIRECTORIES
| file_util::FileEnumerator::INCLUDE_DOT_DOT
);
1851 EXPECT_EQ(temp_dir_
.path().Append(FILE_PATH_LITERAL("..")).value(),
1852 f0_dotdot
.Next().value());
1853 EXPECT_EQ(FILE_PATH_LITERAL(""),
1854 f0_dotdot
.Next().value());
1856 // create the directories
1857 FilePath dir1
= temp_dir_
.path().Append(FILE_PATH_LITERAL("dir1"));
1858 EXPECT_TRUE(file_util::CreateDirectory(dir1
));
1859 FilePath dir2
= temp_dir_
.path().Append(FILE_PATH_LITERAL("dir2"));
1860 EXPECT_TRUE(file_util::CreateDirectory(dir2
));
1861 FilePath dir2inner
= dir2
.Append(FILE_PATH_LITERAL("inner"));
1862 EXPECT_TRUE(file_util::CreateDirectory(dir2inner
));
1865 FilePath dir2file
= dir2
.Append(FILE_PATH_LITERAL("dir2file.txt"));
1866 CreateTextFile(dir2file
, L
"");
1867 FilePath dir2innerfile
= dir2inner
.Append(FILE_PATH_LITERAL("innerfile.txt"));
1868 CreateTextFile(dir2innerfile
, L
"");
1869 FilePath file1
= temp_dir_
.path().Append(FILE_PATH_LITERAL("file1.txt"));
1870 CreateTextFile(file1
, L
"");
1871 FilePath file2_rel
=
1872 dir2
.Append(FilePath::kParentDirectory
)
1873 .Append(FILE_PATH_LITERAL("file2.txt"));
1874 CreateTextFile(file2_rel
, L
"");
1875 FilePath file2_abs
= temp_dir_
.path().Append(FILE_PATH_LITERAL("file2.txt"));
1877 // Only enumerate files.
1878 file_util::FileEnumerator
f1(temp_dir_
.path(), true,
1879 file_util::FileEnumerator::FILES
);
1880 FindResultCollector
c1(f1
);
1881 EXPECT_TRUE(c1
.HasFile(file1
));
1882 EXPECT_TRUE(c1
.HasFile(file2_abs
));
1883 EXPECT_TRUE(c1
.HasFile(dir2file
));
1884 EXPECT_TRUE(c1
.HasFile(dir2innerfile
));
1885 EXPECT_EQ(c1
.size(), 4);
1887 // Only enumerate directories.
1888 file_util::FileEnumerator
f2(temp_dir_
.path(), true,
1889 file_util::FileEnumerator::DIRECTORIES
);
1890 FindResultCollector
c2(f2
);
1891 EXPECT_TRUE(c2
.HasFile(dir1
));
1892 EXPECT_TRUE(c2
.HasFile(dir2
));
1893 EXPECT_TRUE(c2
.HasFile(dir2inner
));
1894 EXPECT_EQ(c2
.size(), 3);
1896 // Only enumerate directories non-recursively.
1897 file_util::FileEnumerator
f2_non_recursive(
1898 temp_dir_
.path(), false, file_util::FileEnumerator::DIRECTORIES
);
1899 FindResultCollector
c2_non_recursive(f2_non_recursive
);
1900 EXPECT_TRUE(c2_non_recursive
.HasFile(dir1
));
1901 EXPECT_TRUE(c2_non_recursive
.HasFile(dir2
));
1902 EXPECT_EQ(c2_non_recursive
.size(), 2);
1904 // Only enumerate directories, non-recursively, including "..".
1905 file_util::FileEnumerator
f2_dotdot(temp_dir_
.path(), false,
1906 file_util::FileEnumerator::DIRECTORIES
|
1907 file_util::FileEnumerator::INCLUDE_DOT_DOT
);
1908 FindResultCollector
c2_dotdot(f2_dotdot
);
1909 EXPECT_TRUE(c2_dotdot
.HasFile(dir1
));
1910 EXPECT_TRUE(c2_dotdot
.HasFile(dir2
));
1911 EXPECT_TRUE(c2_dotdot
.HasFile(
1912 temp_dir_
.path().Append(FILE_PATH_LITERAL(".."))));
1913 EXPECT_EQ(c2_dotdot
.size(), 3);
1915 // Enumerate files and directories.
1916 file_util::FileEnumerator
f3(temp_dir_
.path(), true, FILES_AND_DIRECTORIES
);
1917 FindResultCollector
c3(f3
);
1918 EXPECT_TRUE(c3
.HasFile(dir1
));
1919 EXPECT_TRUE(c3
.HasFile(dir2
));
1920 EXPECT_TRUE(c3
.HasFile(file1
));
1921 EXPECT_TRUE(c3
.HasFile(file2_abs
));
1922 EXPECT_TRUE(c3
.HasFile(dir2file
));
1923 EXPECT_TRUE(c3
.HasFile(dir2inner
));
1924 EXPECT_TRUE(c3
.HasFile(dir2innerfile
));
1925 EXPECT_EQ(c3
.size(), 7);
1927 // Non-recursive operation.
1928 file_util::FileEnumerator
f4(temp_dir_
.path(), false, FILES_AND_DIRECTORIES
);
1929 FindResultCollector
c4(f4
);
1930 EXPECT_TRUE(c4
.HasFile(dir2
));
1931 EXPECT_TRUE(c4
.HasFile(dir2
));
1932 EXPECT_TRUE(c4
.HasFile(file1
));
1933 EXPECT_TRUE(c4
.HasFile(file2_abs
));
1934 EXPECT_EQ(c4
.size(), 4);
1936 // Enumerate with a pattern.
1937 file_util::FileEnumerator
f5(temp_dir_
.path(), true, FILES_AND_DIRECTORIES
,
1938 FILE_PATH_LITERAL("dir*"));
1939 FindResultCollector
c5(f5
);
1940 EXPECT_TRUE(c5
.HasFile(dir1
));
1941 EXPECT_TRUE(c5
.HasFile(dir2
));
1942 EXPECT_TRUE(c5
.HasFile(dir2file
));
1943 EXPECT_TRUE(c5
.HasFile(dir2inner
));
1944 EXPECT_TRUE(c5
.HasFile(dir2innerfile
));
1945 EXPECT_EQ(c5
.size(), 5);
1947 // Make sure the destructor closes the find handle while in the middle of a
1948 // query to allow TearDown to delete the directory.
1949 file_util::FileEnumerator
f6(temp_dir_
.path(), true, FILES_AND_DIRECTORIES
);
1950 EXPECT_FALSE(f6
.Next().value().empty()); // Should have found something
1951 // (we don't care what).
1954 TEST_F(FileUtilTest
, AppendToFile
) {
1956 temp_dir_
.path().Append(FILE_PATH_LITERAL("FilePathTest"));
1958 // Create a fresh, empty copy of this directory.
1959 if (file_util::PathExists(data_dir
)) {
1960 ASSERT_TRUE(file_util::Delete(data_dir
, true));
1962 ASSERT_TRUE(file_util::CreateDirectory(data_dir
));
1964 // Create a fresh, empty copy of this directory.
1965 if (file_util::PathExists(data_dir
)) {
1966 ASSERT_TRUE(file_util::Delete(data_dir
, true));
1968 ASSERT_TRUE(file_util::CreateDirectory(data_dir
));
1969 FilePath
foobar(data_dir
.Append(FILE_PATH_LITERAL("foobar.txt")));
1971 std::string
data("hello");
1972 EXPECT_EQ(-1, file_util::AppendToFile(foobar
, data
.c_str(), data
.length()));
1973 EXPECT_EQ(static_cast<int>(data
.length()),
1974 file_util::WriteFile(foobar
, data
.c_str(), data
.length()));
1975 EXPECT_EQ(static_cast<int>(data
.length()),
1976 file_util::AppendToFile(foobar
, data
.c_str(), data
.length()));
1978 const std::wstring read_content
= ReadTextFile(foobar
);
1979 EXPECT_EQ(L
"hellohello", read_content
);
1982 TEST_F(FileUtilTest
, Contains
) {
1984 temp_dir_
.path().Append(FILE_PATH_LITERAL("FilePathTest"));
1986 // Create a fresh, empty copy of this directory.
1987 if (file_util::PathExists(data_dir
)) {
1988 ASSERT_TRUE(file_util::Delete(data_dir
, true));
1990 ASSERT_TRUE(file_util::CreateDirectory(data_dir
));
1992 FilePath
foo(data_dir
.Append(FILE_PATH_LITERAL("foo")));
1993 FilePath
bar(foo
.Append(FILE_PATH_LITERAL("bar.txt")));
1994 FilePath
baz(data_dir
.Append(FILE_PATH_LITERAL("baz.txt")));
1995 FilePath
foobar(data_dir
.Append(FILE_PATH_LITERAL("foobar.txt")));
1997 // Annoyingly, the directories must actually exist in order for realpath(),
1998 // which Contains() relies on in posix, to work.
1999 ASSERT_TRUE(file_util::CreateDirectory(foo
));
2000 std::string
data("hello");
2001 ASSERT_TRUE(file_util::WriteFile(bar
, data
.c_str(), data
.length()));
2002 ASSERT_TRUE(file_util::WriteFile(baz
, data
.c_str(), data
.length()));
2003 ASSERT_TRUE(file_util::WriteFile(foobar
, data
.c_str(), data
.length()));
2005 EXPECT_TRUE(file_util::ContainsPath(foo
, bar
));
2006 EXPECT_FALSE(file_util::ContainsPath(foo
, baz
));
2007 EXPECT_FALSE(file_util::ContainsPath(foo
, foobar
));
2008 EXPECT_FALSE(file_util::ContainsPath(foo
, foo
));
2010 // Platform-specific concerns.
2011 FilePath
foo_caps(data_dir
.Append(FILE_PATH_LITERAL("FOO")));
2013 EXPECT_TRUE(file_util::ContainsPath(foo
,
2014 foo_caps
.Append(FILE_PATH_LITERAL("bar.txt"))));
2015 EXPECT_TRUE(file_util::ContainsPath(foo
,
2016 FilePath(foo
.value() + FILE_PATH_LITERAL("/bar.txt"))));
2017 #elif defined(OS_MACOSX)
2018 // We can't really do this test on OS X since the case-sensitivity of the
2019 // filesystem is configurable.
2020 #elif defined(OS_POSIX)
2021 EXPECT_FALSE(file_util::ContainsPath(foo
,
2022 foo_caps
.Append(FILE_PATH_LITERAL("bar.txt"))));
2026 TEST_F(FileUtilTest
, TouchFile
) {
2028 temp_dir_
.path().Append(FILE_PATH_LITERAL("FilePathTest"));
2030 // Create a fresh, empty copy of this directory.
2031 if (file_util::PathExists(data_dir
)) {
2032 ASSERT_TRUE(file_util::Delete(data_dir
, true));
2034 ASSERT_TRUE(file_util::CreateDirectory(data_dir
));
2036 FilePath
foobar(data_dir
.Append(FILE_PATH_LITERAL("foobar.txt")));
2037 std::string
data("hello");
2038 ASSERT_TRUE(file_util::WriteFile(foobar
, data
.c_str(), data
.length()));
2040 base::Time access_time
;
2041 // This timestamp is divisible by one day (in local timezone),
2042 // to make it work on FAT too.
2043 ASSERT_TRUE(base::Time::FromString("Wed, 16 Nov 1994, 00:00:00",
2046 base::Time modification_time
;
2047 // Note that this timestamp is divisible by two (seconds) - FAT stores
2048 // modification times with 2s resolution.
2049 ASSERT_TRUE(base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT",
2050 &modification_time
));
2052 ASSERT_TRUE(file_util::TouchFile(foobar
, access_time
, modification_time
));
2053 base::PlatformFileInfo file_info
;
2054 ASSERT_TRUE(file_util::GetFileInfo(foobar
, &file_info
));
2055 EXPECT_EQ(file_info
.last_accessed
.ToInternalValue(),
2056 access_time
.ToInternalValue());
2057 EXPECT_EQ(file_info
.last_modified
.ToInternalValue(),
2058 modification_time
.ToInternalValue());
2061 TEST_F(FileUtilTest
, IsDirectoryEmpty
) {
2062 FilePath empty_dir
= temp_dir_
.path().Append(FILE_PATH_LITERAL("EmptyDir"));
2064 ASSERT_FALSE(file_util::PathExists(empty_dir
));
2066 ASSERT_TRUE(file_util::CreateDirectory(empty_dir
));
2068 EXPECT_TRUE(file_util::IsDirectoryEmpty(empty_dir
));
2070 FilePath
foo(empty_dir
.Append(FILE_PATH_LITERAL("foo.txt")));
2071 std::string
bar("baz");
2072 ASSERT_TRUE(file_util::WriteFile(foo
, bar
.c_str(), bar
.length()));
2074 EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir
));
2077 #if defined(OS_POSIX)
2079 // Testing VerifyPathControlledByAdmin() is hard, because there is no
2080 // way a test can make a file owned by root, or change file paths
2081 // at the root of the file system. VerifyPathControlledByAdmin()
2082 // is implemented as a call to VerifyPathControlledByUser, which gives
2083 // us the ability to test with paths under the test's temp directory,
2084 // using a user id we control.
2085 // Pull tests of VerifyPathControlledByUserTest() into a separate test class
2086 // with a common SetUp() method.
2087 class VerifyPathControlledByUserTest
: public FileUtilTest
{
2089 virtual void SetUp() OVERRIDE
{
2090 FileUtilTest::SetUp();
2092 // Create a basic structure used by each test.
2097 base_dir_
= temp_dir_
.path().AppendASCII("base_dir");
2098 ASSERT_TRUE(file_util::CreateDirectory(base_dir_
));
2100 sub_dir_
= base_dir_
.AppendASCII("sub_dir");
2101 ASSERT_TRUE(file_util::CreateDirectory(sub_dir_
));
2103 text_file_
= sub_dir_
.AppendASCII("file.txt");
2104 CreateTextFile(text_file_
, L
"This text file has some text in it.");
2106 // Get the user and group files are created with from |base_dir_|.
2107 struct stat stat_buf
;
2108 ASSERT_EQ(0, stat(base_dir_
.value().c_str(), &stat_buf
));
2109 uid_
= stat_buf
.st_uid
;
2110 ok_gids_
.insert(stat_buf
.st_gid
);
2111 bad_gids_
.insert(stat_buf
.st_gid
+ 1);
2113 ASSERT_EQ(uid_
, getuid()); // This process should be the owner.
2115 // To ensure that umask settings do not cause the initial state
2116 // of permissions to be different from what we expect, explicitly
2117 // set permissions on the directories we create.
2118 // Make all files and directories non-world-writable.
2120 // Users and group can read, write, traverse
2121 int enabled_permissions
=
2122 file_util::FILE_PERMISSION_USER_MASK
|
2123 file_util::FILE_PERMISSION_GROUP_MASK
;
2124 // Other users can't read, write, traverse
2125 int disabled_permissions
=
2126 file_util::FILE_PERMISSION_OTHERS_MASK
;
2128 ASSERT_NO_FATAL_FAILURE(
2129 ChangePosixFilePermissions(
2130 base_dir_
, enabled_permissions
, disabled_permissions
));
2131 ASSERT_NO_FATAL_FAILURE(
2132 ChangePosixFilePermissions(
2133 sub_dir_
, enabled_permissions
, disabled_permissions
));
2138 FilePath text_file_
;
2141 std::set
<gid_t
> ok_gids_
;
2142 std::set
<gid_t
> bad_gids_
;
2145 TEST_F(VerifyPathControlledByUserTest
, BadPaths
) {
2146 // File does not exist.
2147 FilePath does_not_exist
= base_dir_
.AppendASCII("does")
2149 .AppendASCII("exist");
2151 file_util::VerifyPathControlledByUser(
2152 base_dir_
, does_not_exist
, uid_
, ok_gids_
));
2154 // |base| not a subpath of |path|.
2156 file_util::VerifyPathControlledByUser(
2157 sub_dir_
, base_dir_
, uid_
, ok_gids_
));
2159 // An empty base path will fail to be a prefix for any path.
2162 file_util::VerifyPathControlledByUser(
2163 empty
, base_dir_
, uid_
, ok_gids_
));
2165 // Finding that a bad call fails proves nothing unless a good call succeeds.
2167 file_util::VerifyPathControlledByUser(
2168 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2171 TEST_F(VerifyPathControlledByUserTest
, Symlinks
) {
2172 // Symlinks in the path should cause failure.
2174 // Symlink to the file at the end of the path.
2175 FilePath file_link
= base_dir_
.AppendASCII("file_link");
2176 ASSERT_TRUE(file_util::CreateSymbolicLink(text_file_
, file_link
))
2177 << "Failed to create symlink.";
2180 file_util::VerifyPathControlledByUser(
2181 base_dir_
, file_link
, uid_
, ok_gids_
));
2183 file_util::VerifyPathControlledByUser(
2184 file_link
, file_link
, uid_
, ok_gids_
));
2186 // Symlink from one directory to another within the path.
2187 FilePath link_to_sub_dir
= base_dir_
.AppendASCII("link_to_sub_dir");
2188 ASSERT_TRUE(file_util::CreateSymbolicLink(sub_dir_
, link_to_sub_dir
))
2189 << "Failed to create symlink.";
2191 FilePath file_path_with_link
= link_to_sub_dir
.AppendASCII("file.txt");
2192 ASSERT_TRUE(file_util::PathExists(file_path_with_link
));
2195 file_util::VerifyPathControlledByUser(
2196 base_dir_
, file_path_with_link
, uid_
, ok_gids_
));
2199 file_util::VerifyPathControlledByUser(
2200 link_to_sub_dir
, file_path_with_link
, uid_
, ok_gids_
));
2202 // Symlinks in parents of base path are allowed.
2204 file_util::VerifyPathControlledByUser(
2205 file_path_with_link
, file_path_with_link
, uid_
, ok_gids_
));
2208 TEST_F(VerifyPathControlledByUserTest
, OwnershipChecks
) {
2209 // Get a uid that is not the uid of files we create.
2210 uid_t bad_uid
= uid_
+ 1;
2212 // Make all files and directories non-world-writable.
2213 ASSERT_NO_FATAL_FAILURE(
2214 ChangePosixFilePermissions(base_dir_
, 0u, S_IWOTH
));
2215 ASSERT_NO_FATAL_FAILURE(
2216 ChangePosixFilePermissions(sub_dir_
, 0u, S_IWOTH
));
2217 ASSERT_NO_FATAL_FAILURE(
2218 ChangePosixFilePermissions(text_file_
, 0u, S_IWOTH
));
2220 // We control these paths.
2222 file_util::VerifyPathControlledByUser(
2223 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2225 file_util::VerifyPathControlledByUser(
2226 base_dir_
, text_file_
, uid_
, ok_gids_
));
2228 file_util::VerifyPathControlledByUser(
2229 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2231 // Another user does not control these paths.
2233 file_util::VerifyPathControlledByUser(
2234 base_dir_
, sub_dir_
, bad_uid
, ok_gids_
));
2236 file_util::VerifyPathControlledByUser(
2237 base_dir_
, text_file_
, bad_uid
, ok_gids_
));
2239 file_util::VerifyPathControlledByUser(
2240 sub_dir_
, text_file_
, bad_uid
, ok_gids_
));
2242 // Another group does not control the paths.
2244 file_util::VerifyPathControlledByUser(
2245 base_dir_
, sub_dir_
, uid_
, bad_gids_
));
2247 file_util::VerifyPathControlledByUser(
2248 base_dir_
, text_file_
, uid_
, bad_gids_
));
2250 file_util::VerifyPathControlledByUser(
2251 sub_dir_
, text_file_
, uid_
, bad_gids_
));
2254 TEST_F(VerifyPathControlledByUserTest
, GroupWriteTest
) {
2255 // Make all files and directories writable only by their owner.
2256 ASSERT_NO_FATAL_FAILURE(
2257 ChangePosixFilePermissions(base_dir_
, 0u, S_IWOTH
|S_IWGRP
));
2258 ASSERT_NO_FATAL_FAILURE(
2259 ChangePosixFilePermissions(sub_dir_
, 0u, S_IWOTH
|S_IWGRP
));
2260 ASSERT_NO_FATAL_FAILURE(
2261 ChangePosixFilePermissions(text_file_
, 0u, S_IWOTH
|S_IWGRP
));
2263 // Any group is okay because the path is not group-writable.
2265 file_util::VerifyPathControlledByUser(
2266 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2268 file_util::VerifyPathControlledByUser(
2269 base_dir_
, text_file_
, uid_
, ok_gids_
));
2271 file_util::VerifyPathControlledByUser(
2272 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2275 file_util::VerifyPathControlledByUser(
2276 base_dir_
, sub_dir_
, uid_
, bad_gids_
));
2278 file_util::VerifyPathControlledByUser(
2279 base_dir_
, text_file_
, uid_
, bad_gids_
));
2281 file_util::VerifyPathControlledByUser(
2282 sub_dir_
, text_file_
, uid_
, bad_gids_
));
2284 // No group is okay, because we don't check the group
2285 // if no group can write.
2286 std::set
<gid_t
> no_gids
; // Empty set of gids.
2288 file_util::VerifyPathControlledByUser(
2289 base_dir_
, sub_dir_
, uid_
, no_gids
));
2291 file_util::VerifyPathControlledByUser(
2292 base_dir_
, text_file_
, uid_
, no_gids
));
2294 file_util::VerifyPathControlledByUser(
2295 sub_dir_
, text_file_
, uid_
, no_gids
));
2298 // Make all files and directories writable by their group.
2299 ASSERT_NO_FATAL_FAILURE(
2300 ChangePosixFilePermissions(base_dir_
, S_IWGRP
, 0u));
2301 ASSERT_NO_FATAL_FAILURE(
2302 ChangePosixFilePermissions(sub_dir_
, S_IWGRP
, 0u));
2303 ASSERT_NO_FATAL_FAILURE(
2304 ChangePosixFilePermissions(text_file_
, S_IWGRP
, 0u));
2306 // Now |ok_gids_| works, but |bad_gids_| fails.
2308 file_util::VerifyPathControlledByUser(
2309 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2311 file_util::VerifyPathControlledByUser(
2312 base_dir_
, text_file_
, uid_
, ok_gids_
));
2314 file_util::VerifyPathControlledByUser(
2315 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2318 file_util::VerifyPathControlledByUser(
2319 base_dir_
, sub_dir_
, uid_
, bad_gids_
));
2321 file_util::VerifyPathControlledByUser(
2322 base_dir_
, text_file_
, uid_
, bad_gids_
));
2324 file_util::VerifyPathControlledByUser(
2325 sub_dir_
, text_file_
, uid_
, bad_gids_
));
2327 // Because any group in the group set is allowed,
2328 // the union of good and bad gids passes.
2330 std::set
<gid_t
> multiple_gids
;
2332 ok_gids_
.begin(), ok_gids_
.end(),
2333 bad_gids_
.begin(), bad_gids_
.end(),
2334 std::inserter(multiple_gids
, multiple_gids
.begin()));
2337 file_util::VerifyPathControlledByUser(
2338 base_dir_
, sub_dir_
, uid_
, multiple_gids
));
2340 file_util::VerifyPathControlledByUser(
2341 base_dir_
, text_file_
, uid_
, multiple_gids
));
2343 file_util::VerifyPathControlledByUser(
2344 sub_dir_
, text_file_
, uid_
, multiple_gids
));
2347 TEST_F(VerifyPathControlledByUserTest
, WriteBitChecks
) {
2348 // Make all files and directories non-world-writable.
2349 ASSERT_NO_FATAL_FAILURE(
2350 ChangePosixFilePermissions(base_dir_
, 0u, S_IWOTH
));
2351 ASSERT_NO_FATAL_FAILURE(
2352 ChangePosixFilePermissions(sub_dir_
, 0u, S_IWOTH
));
2353 ASSERT_NO_FATAL_FAILURE(
2354 ChangePosixFilePermissions(text_file_
, 0u, S_IWOTH
));
2356 // Initialy, we control all parts of the path.
2358 file_util::VerifyPathControlledByUser(
2359 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2361 file_util::VerifyPathControlledByUser(
2362 base_dir_
, text_file_
, uid_
, ok_gids_
));
2364 file_util::VerifyPathControlledByUser(
2365 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2367 // Make base_dir_ world-writable.
2368 ASSERT_NO_FATAL_FAILURE(
2369 ChangePosixFilePermissions(base_dir_
, S_IWOTH
, 0u));
2371 file_util::VerifyPathControlledByUser(
2372 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2374 file_util::VerifyPathControlledByUser(
2375 base_dir_
, text_file_
, uid_
, ok_gids_
));
2377 file_util::VerifyPathControlledByUser(
2378 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2380 // Make sub_dir_ world writable.
2381 ASSERT_NO_FATAL_FAILURE(
2382 ChangePosixFilePermissions(sub_dir_
, S_IWOTH
, 0u));
2384 file_util::VerifyPathControlledByUser(
2385 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2387 file_util::VerifyPathControlledByUser(
2388 base_dir_
, text_file_
, uid_
, ok_gids_
));
2390 file_util::VerifyPathControlledByUser(
2391 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2393 // Make text_file_ world writable.
2394 ASSERT_NO_FATAL_FAILURE(
2395 ChangePosixFilePermissions(text_file_
, S_IWOTH
, 0u));
2397 file_util::VerifyPathControlledByUser(
2398 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2400 file_util::VerifyPathControlledByUser(
2401 base_dir_
, text_file_
, uid_
, ok_gids_
));
2403 file_util::VerifyPathControlledByUser(
2404 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2406 // Make sub_dir_ non-world writable.
2407 ASSERT_NO_FATAL_FAILURE(
2408 ChangePosixFilePermissions(sub_dir_
, 0u, S_IWOTH
));
2410 file_util::VerifyPathControlledByUser(
2411 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2413 file_util::VerifyPathControlledByUser(
2414 base_dir_
, text_file_
, uid_
, ok_gids_
));
2416 file_util::VerifyPathControlledByUser(
2417 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2419 // Make base_dir_ non-world-writable.
2420 ASSERT_NO_FATAL_FAILURE(
2421 ChangePosixFilePermissions(base_dir_
, 0u, S_IWOTH
));
2423 file_util::VerifyPathControlledByUser(
2424 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2426 file_util::VerifyPathControlledByUser(
2427 base_dir_
, text_file_
, uid_
, ok_gids_
));
2429 file_util::VerifyPathControlledByUser(
2430 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2432 // Back to the initial state: Nothing is writable, so every path
2434 ASSERT_NO_FATAL_FAILURE(
2435 ChangePosixFilePermissions(text_file_
, 0u, S_IWOTH
));
2437 file_util::VerifyPathControlledByUser(
2438 base_dir_
, sub_dir_
, uid_
, ok_gids_
));
2440 file_util::VerifyPathControlledByUser(
2441 base_dir_
, text_file_
, uid_
, ok_gids_
));
2443 file_util::VerifyPathControlledByUser(
2444 sub_dir_
, text_file_
, uid_
, ok_gids_
));
2447 #endif // defined(OS_POSIX)