Passwords PSL Matching on Gnome: overwrite realm and origin
[chromium-blink-merge.git] / base / file_util_unittest.cc
blob0d793918d681fafeaa2e52a289cd4ebbb8a7e94d
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"
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
15 #if defined(OS_POSIX)
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #endif
21 #include <algorithm>
22 #include <fstream>
23 #include <set>
24 #include <vector>
26 #include "base/base_paths.h"
27 #include "base/file_util.h"
28 #include "base/files/file_enumerator.h"
29 #include "base/files/file_path.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"
39 #if defined(OS_WIN)
40 #include "base/win/scoped_handle.h"
41 #include "base/win/windows_version.h"
42 #endif
44 #if defined(OS_ANDROID)
45 #include "base/android/content_uri_utils.h"
46 #endif
48 // This macro helps avoid wrapped lines in the test structs.
49 #define FPL(x) FILE_PATH_LITERAL(x)
51 namespace base {
53 namespace {
55 // To test that file_util::Normalize FilePath() deals with NTFS reparse points
56 // correctly, 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;
82 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
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;
98 REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer);
100 data->ReparseTag = 0xa0000003;
101 memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2);
103 data->MountPointReparseBuffer.SubstituteNameLength = size_target;
104 data->MountPointReparseBuffer.PrintNameOffset = size_target + 2;
105 data->ReparseDataLength = size_target + 4 + 8;
107 int data_size = data->ReparseDataLength + 8;
109 if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size,
110 NULL, 0, &returned, NULL)) {
111 return false;
113 return true;
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;
126 return true;
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_, target);
145 ~ReparsePoint() {
146 if (created_)
147 DeleteReparsePoint(dir_);
150 bool IsValid() { return created_; }
152 private:
153 win::ScopedHandle dir_;
154 bool created_;
155 DISALLOW_COPY_AND_ASSIGN(ReparsePoint);
158 #endif
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.";
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));
176 #endif // defined(OS_POSIX)
178 const wchar_t bogus_content[] = L"I'm cannon fodder.";
180 const int FILES_AND_DIRECTORIES =
181 FileEnumerator::FILES | FileEnumerator::DIRECTORIES;
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());
192 ScopedTempDir temp_dir_;
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";
207 // Save for later.
208 files_.insert(path);
212 // Returns true if the enumerator found the file.
213 bool HasFile(const FilePath& file) const {
214 return files_.find(file.value()) != files_.end();
217 int size() {
218 return static_cast<int>(files_.size());
221 private:
222 std::set<FilePath::StringType> files_;
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();
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);
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;
253 #endif
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);
264 FilePath subdir_path = temp_dir_.path().Append(FPL("Level2"));
265 CreateDirectory(subdir_path);
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);
273 FilePath subsubdir_path = subdir_path.Append(FPL("Level3"));
274 CreateDirectory(subsubdir_path);
276 FilePath file_03 = subsubdir_path.Append(FPL("The file 03.txt"));
277 CreateTextFile(file_03, L"123");
279 int64 computed_size = ComputeDirectorySize(temp_dir_.path());
280 EXPECT_EQ(size_f1 + size_f2 + 3, computed_size);
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);
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.";
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));
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));
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()));
311 #if defined(OS_WIN)
313 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) {
314 // Build the following directory structure:
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)
328 FilePath base_a = temp_dir_.path().Append(FPL("base_a"));
329 ASSERT_TRUE(CreateDirectory(base_a));
331 FilePath sub_a = base_a.Append(FPL("sub_a"));
332 ASSERT_TRUE(CreateDirectory(sub_a));
334 FilePath file_txt = sub_a.Append(FPL("file.txt"));
335 CreateTextFile(file_txt, bogus_content);
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"));
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, '_');
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());
359 FilePath sub_long = deep_file.DirName();
360 ASSERT_TRUE(CreateDirectory(sub_long));
361 CreateTextFile(deep_file, bogus_content);
363 FilePath base_b = temp_dir_.path().Append(FPL("base_b"));
364 ASSERT_TRUE(CreateDirectory(base_b));
366 FilePath to_sub_a = base_b.Append(FPL("to_sub_a"));
367 ASSERT_TRUE(CreateDirectory(to_sub_a));
368 FilePath normalized_path;
370 ReparsePoint reparse_to_sub_a(to_sub_a, sub_a);
371 ASSERT_TRUE(reparse_to_sub_a.IsValid());
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());
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());
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());
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());
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());
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"));
410 long_path = long_path.Append(FPL("to_sub_a"))
411 .Append(FPL("file.txt"));
413 ASSERT_FALSE(NormalizeFilePath(long_path, &normalized_path));
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));
420 // Delete the reparse points, and see that NormalizeFilePath() fails
421 // to traverse them.
424 ASSERT_FALSE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")),
425 &normalized_path));
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;
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;
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());
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());
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));
472 ASSERT_FALSE(DevicePathToDriveLetterPath(
473 prefix_of_real_device_path.Append(kRelativePath),
474 &win32_path));
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");
484 FilePath real_device_path_plus_numbers(
485 actual_device_path.value() + kExtraChars);
487 ASSERT_FALSE(DevicePathToDriveLetterPath(
488 real_device_path_plus_numbers,
489 &win32_path));
491 ASSERT_FALSE(DevicePathToDriveLetterPath(
492 real_device_path_plus_numbers.Append(kRelativePath),
493 &win32_path));
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));
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());
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));
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 file_util::PermissionRestorer long_test_dir_restorer(long_test_dir);
532 ASSERT_TRUE(file_util::MakeFileUnreadable(long_test_dir));
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()));
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);
546 #endif // defined(OS_WIN)
548 #if defined(OS_POSIX)
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);
555 ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
556 << "Failed to create file symlink.";
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);
563 FilePath result;
564 ASSERT_TRUE(ReadSymbolicLink(link_from, &result));
565 EXPECT_EQ(link_to.value(), result.value());
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.";
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));
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);
592 ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
593 << "Failed to create file symlink.";
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());
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.";
609 EXPECT_FALSE(NormalizeFilePath(link_from, &normalized_path))
610 << "Links to directories should return false.";
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.";
620 // Infinite loop!
621 EXPECT_FALSE(NormalizeFilePath(link_from, &normalized_path));
623 #endif // defined(OS_POSIX)
625 TEST_F(FileUtilTest, DeleteNonExistent) {
626 FilePath non_existent = temp_dir_.path().AppendASCII("bogus_file_dne.foobar");
627 ASSERT_FALSE(PathExists(non_existent));
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));
635 TEST_F(FileUtilTest, DeleteFile) {
636 // Create a file
637 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 1.txt"));
638 CreateTextFile(file_name, bogus_content);
639 ASSERT_TRUE(PathExists(file_name));
641 // Make sure it's deleted
642 EXPECT_TRUE(DeleteFile(file_name, false));
643 EXPECT_FALSE(PathExists(file_name));
645 // Test recursive case, create a new file
646 file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt"));
647 CreateTextFile(file_name, bogus_content);
648 ASSERT_TRUE(PathExists(file_name));
650 // Make sure it's deleted
651 EXPECT_TRUE(DeleteFile(file_name, true));
652 EXPECT_FALSE(PathExists(file_name));
655 #if defined(OS_POSIX)
656 TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) {
657 // Create a file.
658 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt"));
659 CreateTextFile(file_name, bogus_content);
660 ASSERT_TRUE(PathExists(file_name));
662 // Create a symlink to the file.
663 FilePath file_link = temp_dir_.path().Append("file_link_2");
664 ASSERT_TRUE(CreateSymbolicLink(file_name, file_link))
665 << "Failed to create symlink.";
667 // Delete the symbolic link.
668 EXPECT_TRUE(DeleteFile(file_link, false));
670 // Make sure original file is not deleted.
671 EXPECT_FALSE(PathExists(file_link));
672 EXPECT_TRUE(PathExists(file_name));
675 TEST_F(FileUtilTest, DeleteSymlinkToNonExistentFile) {
676 // Create a non-existent file path.
677 FilePath non_existent = temp_dir_.path().Append(FPL("Test DeleteFile 3.txt"));
678 EXPECT_FALSE(PathExists(non_existent));
680 // Create a symlink to the non-existent file.
681 FilePath file_link = temp_dir_.path().Append("file_link_3");
682 ASSERT_TRUE(CreateSymbolicLink(non_existent, file_link))
683 << "Failed to create symlink.";
685 // Make sure the symbolic link is exist.
686 EXPECT_TRUE(IsLink(file_link));
687 EXPECT_FALSE(PathExists(file_link));
689 // Delete the symbolic link.
690 EXPECT_TRUE(DeleteFile(file_link, false));
692 // Make sure the symbolic link is deleted.
693 EXPECT_FALSE(IsLink(file_link));
696 TEST_F(FileUtilTest, ChangeFilePermissionsAndRead) {
697 // Create a file path.
698 FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt"));
699 EXPECT_FALSE(PathExists(file_name));
701 const std::string kData("hello");
703 int buffer_size = kData.length();
704 char* buffer = new char[buffer_size];
706 // Write file.
707 EXPECT_EQ(static_cast<int>(kData.length()),
708 WriteFile(file_name, kData.data(), kData.length()));
709 EXPECT_TRUE(PathExists(file_name));
711 // Make sure the file is readable.
712 int32 mode = 0;
713 EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
714 EXPECT_TRUE(mode & FILE_PERMISSION_READ_BY_USER);
716 // Get rid of the read permission.
717 EXPECT_TRUE(SetPosixFilePermissions(file_name, 0u));
718 EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
719 EXPECT_FALSE(mode & FILE_PERMISSION_READ_BY_USER);
720 // Make sure the file can't be read.
721 EXPECT_EQ(-1, ReadFile(file_name, buffer, buffer_size));
723 // Give the read permission.
724 EXPECT_TRUE(SetPosixFilePermissions(file_name, FILE_PERMISSION_READ_BY_USER));
725 EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
726 EXPECT_TRUE(mode & FILE_PERMISSION_READ_BY_USER);
727 // Make sure the file can be read.
728 EXPECT_EQ(static_cast<int>(kData.length()),
729 ReadFile(file_name, buffer, buffer_size));
731 // Delete the file.
732 EXPECT_TRUE(DeleteFile(file_name, false));
733 EXPECT_FALSE(PathExists(file_name));
735 delete[] buffer;
738 TEST_F(FileUtilTest, ChangeFilePermissionsAndWrite) {
739 // Create a file path.
740 FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt"));
741 EXPECT_FALSE(PathExists(file_name));
743 const std::string kData("hello");
745 // Write file.
746 EXPECT_EQ(static_cast<int>(kData.length()),
747 WriteFile(file_name, kData.data(), kData.length()));
748 EXPECT_TRUE(PathExists(file_name));
750 // Make sure the file is writable.
751 int mode = 0;
752 EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
753 EXPECT_TRUE(mode & FILE_PERMISSION_WRITE_BY_USER);
754 EXPECT_TRUE(PathIsWritable(file_name));
756 // Get rid of the write permission.
757 EXPECT_TRUE(SetPosixFilePermissions(file_name, 0u));
758 EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
759 EXPECT_FALSE(mode & FILE_PERMISSION_WRITE_BY_USER);
760 // Make sure the file can't be write.
761 EXPECT_EQ(-1, WriteFile(file_name, kData.data(), kData.length()));
762 EXPECT_FALSE(PathIsWritable(file_name));
764 // Give read permission.
765 EXPECT_TRUE(SetPosixFilePermissions(file_name,
766 FILE_PERMISSION_WRITE_BY_USER));
767 EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
768 EXPECT_TRUE(mode & FILE_PERMISSION_WRITE_BY_USER);
769 // Make sure the file can be write.
770 EXPECT_EQ(static_cast<int>(kData.length()),
771 WriteFile(file_name, kData.data(), kData.length()));
772 EXPECT_TRUE(PathIsWritable(file_name));
774 // Delete the file.
775 EXPECT_TRUE(DeleteFile(file_name, false));
776 EXPECT_FALSE(PathExists(file_name));
779 TEST_F(FileUtilTest, ChangeDirectoryPermissionsAndEnumerate) {
780 // Create a directory path.
781 FilePath subdir_path =
782 temp_dir_.path().Append(FPL("PermissionTest1"));
783 CreateDirectory(subdir_path);
784 ASSERT_TRUE(PathExists(subdir_path));
786 // Create a dummy file to enumerate.
787 FilePath file_name = subdir_path.Append(FPL("Test Readable File.txt"));
788 EXPECT_FALSE(PathExists(file_name));
789 const std::string kData("hello");
790 EXPECT_EQ(static_cast<int>(kData.length()),
791 WriteFile(file_name, kData.data(), kData.length()));
792 EXPECT_TRUE(PathExists(file_name));
794 // Make sure the directory has the all permissions.
795 int mode = 0;
796 EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
797 EXPECT_EQ(FILE_PERMISSION_USER_MASK, mode & FILE_PERMISSION_USER_MASK);
799 // Get rid of the permissions from the directory.
800 EXPECT_TRUE(SetPosixFilePermissions(subdir_path, 0u));
801 EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
802 EXPECT_FALSE(mode & FILE_PERMISSION_USER_MASK);
804 // Make sure the file in the directory can't be enumerated.
805 FileEnumerator f1(subdir_path, true, FileEnumerator::FILES);
806 EXPECT_TRUE(PathExists(subdir_path));
807 FindResultCollector c1(f1);
808 EXPECT_EQ(c1.size(), 0);
809 EXPECT_FALSE(GetPosixFilePermissions(file_name, &mode));
811 // Give the permissions to the directory.
812 EXPECT_TRUE(SetPosixFilePermissions(subdir_path, FILE_PERMISSION_USER_MASK));
813 EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
814 EXPECT_EQ(FILE_PERMISSION_USER_MASK, mode & FILE_PERMISSION_USER_MASK);
816 // Make sure the file in the directory can be enumerated.
817 FileEnumerator f2(subdir_path, true, FileEnumerator::FILES);
818 FindResultCollector c2(f2);
819 EXPECT_TRUE(c2.HasFile(file_name));
820 EXPECT_EQ(c2.size(), 1);
822 // Delete the file.
823 EXPECT_TRUE(DeleteFile(subdir_path, true));
824 EXPECT_FALSE(PathExists(subdir_path));
827 #endif // defined(OS_POSIX)
829 #if defined(OS_WIN)
830 // Tests that the Delete function works for wild cards, especially
831 // with the recursion flag. Also coincidentally tests PathExists.
832 // TODO(erikkay): see if anyone's actually using this feature of the API
833 TEST_F(FileUtilTest, DeleteWildCard) {
834 // Create a file and a directory
835 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteWildCard.txt"));
836 CreateTextFile(file_name, bogus_content);
837 ASSERT_TRUE(PathExists(file_name));
839 FilePath subdir_path = temp_dir_.path().Append(FPL("DeleteWildCardDir"));
840 CreateDirectory(subdir_path);
841 ASSERT_TRUE(PathExists(subdir_path));
843 // Create the wildcard path
844 FilePath directory_contents = temp_dir_.path();
845 directory_contents = directory_contents.Append(FPL("*"));
847 // Delete non-recursively and check that only the file is deleted
848 EXPECT_TRUE(DeleteFile(directory_contents, false));
849 EXPECT_FALSE(PathExists(file_name));
850 EXPECT_TRUE(PathExists(subdir_path));
852 // Delete recursively and make sure all contents are deleted
853 EXPECT_TRUE(DeleteFile(directory_contents, true));
854 EXPECT_FALSE(PathExists(file_name));
855 EXPECT_FALSE(PathExists(subdir_path));
858 // TODO(erikkay): see if anyone's actually using this feature of the API
859 TEST_F(FileUtilTest, DeleteNonExistantWildCard) {
860 // Create a file and a directory
861 FilePath subdir_path =
862 temp_dir_.path().Append(FPL("DeleteNonExistantWildCard"));
863 CreateDirectory(subdir_path);
864 ASSERT_TRUE(PathExists(subdir_path));
866 // Create the wildcard path
867 FilePath directory_contents = subdir_path;
868 directory_contents = directory_contents.Append(FPL("*"));
870 // Delete non-recursively and check nothing got deleted
871 EXPECT_TRUE(DeleteFile(directory_contents, false));
872 EXPECT_TRUE(PathExists(subdir_path));
874 // Delete recursively and check nothing got deleted
875 EXPECT_TRUE(DeleteFile(directory_contents, true));
876 EXPECT_TRUE(PathExists(subdir_path));
878 #endif
880 // Tests non-recursive Delete() for a directory.
881 TEST_F(FileUtilTest, DeleteDirNonRecursive) {
882 // Create a subdirectory and put a file and two directories inside.
883 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive"));
884 CreateDirectory(test_subdir);
885 ASSERT_TRUE(PathExists(test_subdir));
887 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt"));
888 CreateTextFile(file_name, bogus_content);
889 ASSERT_TRUE(PathExists(file_name));
891 FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
892 CreateDirectory(subdir_path1);
893 ASSERT_TRUE(PathExists(subdir_path1));
895 FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
896 CreateDirectory(subdir_path2);
897 ASSERT_TRUE(PathExists(subdir_path2));
899 // Delete non-recursively and check that the empty dir got deleted
900 EXPECT_TRUE(DeleteFile(subdir_path2, false));
901 EXPECT_FALSE(PathExists(subdir_path2));
903 // Delete non-recursively and check that nothing got deleted
904 EXPECT_FALSE(DeleteFile(test_subdir, false));
905 EXPECT_TRUE(PathExists(test_subdir));
906 EXPECT_TRUE(PathExists(file_name));
907 EXPECT_TRUE(PathExists(subdir_path1));
910 // Tests recursive Delete() for a directory.
911 TEST_F(FileUtilTest, DeleteDirRecursive) {
912 // Create a subdirectory and put a file and two directories inside.
913 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirRecursive"));
914 CreateDirectory(test_subdir);
915 ASSERT_TRUE(PathExists(test_subdir));
917 FilePath file_name = test_subdir.Append(FPL("Test DeleteDirRecursive.txt"));
918 CreateTextFile(file_name, bogus_content);
919 ASSERT_TRUE(PathExists(file_name));
921 FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
922 CreateDirectory(subdir_path1);
923 ASSERT_TRUE(PathExists(subdir_path1));
925 FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
926 CreateDirectory(subdir_path2);
927 ASSERT_TRUE(PathExists(subdir_path2));
929 // Delete recursively and check that the empty dir got deleted
930 EXPECT_TRUE(DeleteFile(subdir_path2, true));
931 EXPECT_FALSE(PathExists(subdir_path2));
933 // Delete recursively and check that everything got deleted
934 EXPECT_TRUE(DeleteFile(test_subdir, true));
935 EXPECT_FALSE(PathExists(file_name));
936 EXPECT_FALSE(PathExists(subdir_path1));
937 EXPECT_FALSE(PathExists(test_subdir));
940 TEST_F(FileUtilTest, MoveFileNew) {
941 // Create a file
942 FilePath file_name_from =
943 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
944 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
945 ASSERT_TRUE(PathExists(file_name_from));
947 // The destination.
948 FilePath file_name_to = temp_dir_.path().Append(
949 FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
950 ASSERT_FALSE(PathExists(file_name_to));
952 EXPECT_TRUE(Move(file_name_from, file_name_to));
954 // Check everything has been moved.
955 EXPECT_FALSE(PathExists(file_name_from));
956 EXPECT_TRUE(PathExists(file_name_to));
959 TEST_F(FileUtilTest, MoveFileExists) {
960 // Create a file
961 FilePath file_name_from =
962 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
963 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
964 ASSERT_TRUE(PathExists(file_name_from));
966 // The destination name.
967 FilePath file_name_to = temp_dir_.path().Append(
968 FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
969 CreateTextFile(file_name_to, L"Old file content");
970 ASSERT_TRUE(PathExists(file_name_to));
972 EXPECT_TRUE(Move(file_name_from, file_name_to));
974 // Check everything has been moved.
975 EXPECT_FALSE(PathExists(file_name_from));
976 EXPECT_TRUE(PathExists(file_name_to));
977 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
980 TEST_F(FileUtilTest, MoveFileDirExists) {
981 // Create a file
982 FilePath file_name_from =
983 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
984 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
985 ASSERT_TRUE(PathExists(file_name_from));
987 // The destination directory
988 FilePath dir_name_to =
989 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
990 CreateDirectory(dir_name_to);
991 ASSERT_TRUE(PathExists(dir_name_to));
993 EXPECT_FALSE(Move(file_name_from, dir_name_to));
997 TEST_F(FileUtilTest, MoveNew) {
998 // Create a directory
999 FilePath dir_name_from =
1000 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1001 CreateDirectory(dir_name_from);
1002 ASSERT_TRUE(PathExists(dir_name_from));
1004 // Create a file under the directory
1005 FilePath txt_file_name(FILE_PATH_LITERAL("Move_Test_File.txt"));
1006 FilePath file_name_from = dir_name_from.Append(txt_file_name);
1007 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1008 ASSERT_TRUE(PathExists(file_name_from));
1010 // Move the directory.
1011 FilePath dir_name_to =
1012 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1013 FilePath file_name_to =
1014 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1016 ASSERT_FALSE(PathExists(dir_name_to));
1018 EXPECT_TRUE(Move(dir_name_from, dir_name_to));
1020 // Check everything has been moved.
1021 EXPECT_FALSE(PathExists(dir_name_from));
1022 EXPECT_FALSE(PathExists(file_name_from));
1023 EXPECT_TRUE(PathExists(dir_name_to));
1024 EXPECT_TRUE(PathExists(file_name_to));
1026 // Test path traversal.
1027 file_name_from = dir_name_to.Append(txt_file_name);
1028 file_name_to = dir_name_to.Append(FILE_PATH_LITERAL(".."));
1029 file_name_to = file_name_to.Append(txt_file_name);
1030 EXPECT_FALSE(Move(file_name_from, file_name_to));
1031 EXPECT_TRUE(PathExists(file_name_from));
1032 EXPECT_FALSE(PathExists(file_name_to));
1033 EXPECT_TRUE(internal::MoveUnsafe(file_name_from, file_name_to));
1034 EXPECT_FALSE(PathExists(file_name_from));
1035 EXPECT_TRUE(PathExists(file_name_to));
1038 TEST_F(FileUtilTest, MoveExist) {
1039 // Create a directory
1040 FilePath dir_name_from =
1041 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1042 CreateDirectory(dir_name_from);
1043 ASSERT_TRUE(PathExists(dir_name_from));
1045 // Create a file under the directory
1046 FilePath file_name_from =
1047 dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1048 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1049 ASSERT_TRUE(PathExists(file_name_from));
1051 // Move the directory
1052 FilePath dir_name_exists =
1053 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1055 FilePath dir_name_to =
1056 dir_name_exists.Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1057 FilePath file_name_to =
1058 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1060 // Create the destination directory.
1061 CreateDirectory(dir_name_exists);
1062 ASSERT_TRUE(PathExists(dir_name_exists));
1064 EXPECT_TRUE(Move(dir_name_from, dir_name_to));
1066 // Check everything has been moved.
1067 EXPECT_FALSE(PathExists(dir_name_from));
1068 EXPECT_FALSE(PathExists(file_name_from));
1069 EXPECT_TRUE(PathExists(dir_name_to));
1070 EXPECT_TRUE(PathExists(file_name_to));
1073 TEST_F(FileUtilTest, CopyDirectoryRecursivelyNew) {
1074 // Create a directory.
1075 FilePath dir_name_from =
1076 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1077 CreateDirectory(dir_name_from);
1078 ASSERT_TRUE(PathExists(dir_name_from));
1080 // Create a file under the directory.
1081 FilePath file_name_from =
1082 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1083 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1084 ASSERT_TRUE(PathExists(file_name_from));
1086 // Create a subdirectory.
1087 FilePath subdir_name_from =
1088 dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1089 CreateDirectory(subdir_name_from);
1090 ASSERT_TRUE(PathExists(subdir_name_from));
1092 // Create a file under the subdirectory.
1093 FilePath file_name2_from =
1094 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1095 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1096 ASSERT_TRUE(PathExists(file_name2_from));
1098 // Copy the directory recursively.
1099 FilePath dir_name_to =
1100 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1101 FilePath file_name_to =
1102 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1103 FilePath subdir_name_to =
1104 dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1105 FilePath file_name2_to =
1106 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1108 ASSERT_FALSE(PathExists(dir_name_to));
1110 EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, true));
1112 // Check everything has been copied.
1113 EXPECT_TRUE(PathExists(dir_name_from));
1114 EXPECT_TRUE(PathExists(file_name_from));
1115 EXPECT_TRUE(PathExists(subdir_name_from));
1116 EXPECT_TRUE(PathExists(file_name2_from));
1117 EXPECT_TRUE(PathExists(dir_name_to));
1118 EXPECT_TRUE(PathExists(file_name_to));
1119 EXPECT_TRUE(PathExists(subdir_name_to));
1120 EXPECT_TRUE(PathExists(file_name2_to));
1123 TEST_F(FileUtilTest, CopyDirectoryRecursivelyExists) {
1124 // Create a directory.
1125 FilePath dir_name_from =
1126 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1127 CreateDirectory(dir_name_from);
1128 ASSERT_TRUE(PathExists(dir_name_from));
1130 // Create a file under the directory.
1131 FilePath file_name_from =
1132 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1133 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1134 ASSERT_TRUE(PathExists(file_name_from));
1136 // Create a subdirectory.
1137 FilePath subdir_name_from =
1138 dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1139 CreateDirectory(subdir_name_from);
1140 ASSERT_TRUE(PathExists(subdir_name_from));
1142 // Create a file under the subdirectory.
1143 FilePath file_name2_from =
1144 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1145 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1146 ASSERT_TRUE(PathExists(file_name2_from));
1148 // Copy the directory recursively.
1149 FilePath dir_name_exists =
1150 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1152 FilePath dir_name_to =
1153 dir_name_exists.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1154 FilePath file_name_to =
1155 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1156 FilePath subdir_name_to =
1157 dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1158 FilePath file_name2_to =
1159 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1161 // Create the destination directory.
1162 CreateDirectory(dir_name_exists);
1163 ASSERT_TRUE(PathExists(dir_name_exists));
1165 EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_exists, true));
1167 // Check everything has been copied.
1168 EXPECT_TRUE(PathExists(dir_name_from));
1169 EXPECT_TRUE(PathExists(file_name_from));
1170 EXPECT_TRUE(PathExists(subdir_name_from));
1171 EXPECT_TRUE(PathExists(file_name2_from));
1172 EXPECT_TRUE(PathExists(dir_name_to));
1173 EXPECT_TRUE(PathExists(file_name_to));
1174 EXPECT_TRUE(PathExists(subdir_name_to));
1175 EXPECT_TRUE(PathExists(file_name2_to));
1178 TEST_F(FileUtilTest, CopyDirectoryNew) {
1179 // Create a directory.
1180 FilePath dir_name_from =
1181 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1182 CreateDirectory(dir_name_from);
1183 ASSERT_TRUE(PathExists(dir_name_from));
1185 // Create a file under the directory.
1186 FilePath file_name_from =
1187 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1188 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1189 ASSERT_TRUE(PathExists(file_name_from));
1191 // Create a subdirectory.
1192 FilePath subdir_name_from =
1193 dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1194 CreateDirectory(subdir_name_from);
1195 ASSERT_TRUE(PathExists(subdir_name_from));
1197 // Create a file under the subdirectory.
1198 FilePath file_name2_from =
1199 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1200 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1201 ASSERT_TRUE(PathExists(file_name2_from));
1203 // Copy the directory not recursively.
1204 FilePath dir_name_to =
1205 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1206 FilePath file_name_to =
1207 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1208 FilePath subdir_name_to =
1209 dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1211 ASSERT_FALSE(PathExists(dir_name_to));
1213 EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
1215 // Check everything has been copied.
1216 EXPECT_TRUE(PathExists(dir_name_from));
1217 EXPECT_TRUE(PathExists(file_name_from));
1218 EXPECT_TRUE(PathExists(subdir_name_from));
1219 EXPECT_TRUE(PathExists(file_name2_from));
1220 EXPECT_TRUE(PathExists(dir_name_to));
1221 EXPECT_TRUE(PathExists(file_name_to));
1222 EXPECT_FALSE(PathExists(subdir_name_to));
1225 TEST_F(FileUtilTest, CopyDirectoryExists) {
1226 // Create a directory.
1227 FilePath dir_name_from =
1228 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1229 CreateDirectory(dir_name_from);
1230 ASSERT_TRUE(PathExists(dir_name_from));
1232 // Create a file under the directory.
1233 FilePath file_name_from =
1234 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1235 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1236 ASSERT_TRUE(PathExists(file_name_from));
1238 // Create a subdirectory.
1239 FilePath subdir_name_from =
1240 dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1241 CreateDirectory(subdir_name_from);
1242 ASSERT_TRUE(PathExists(subdir_name_from));
1244 // Create a file under the subdirectory.
1245 FilePath file_name2_from =
1246 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1247 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1248 ASSERT_TRUE(PathExists(file_name2_from));
1250 // Copy the directory not recursively.
1251 FilePath dir_name_to =
1252 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1253 FilePath file_name_to =
1254 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1255 FilePath subdir_name_to =
1256 dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1258 // Create the destination directory.
1259 CreateDirectory(dir_name_to);
1260 ASSERT_TRUE(PathExists(dir_name_to));
1262 EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
1264 // Check everything has been copied.
1265 EXPECT_TRUE(PathExists(dir_name_from));
1266 EXPECT_TRUE(PathExists(file_name_from));
1267 EXPECT_TRUE(PathExists(subdir_name_from));
1268 EXPECT_TRUE(PathExists(file_name2_from));
1269 EXPECT_TRUE(PathExists(dir_name_to));
1270 EXPECT_TRUE(PathExists(file_name_to));
1271 EXPECT_FALSE(PathExists(subdir_name_to));
1274 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToNew) {
1275 // Create a file
1276 FilePath file_name_from =
1277 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1278 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1279 ASSERT_TRUE(PathExists(file_name_from));
1281 // The destination name
1282 FilePath file_name_to = temp_dir_.path().Append(
1283 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1284 ASSERT_FALSE(PathExists(file_name_to));
1286 EXPECT_TRUE(CopyDirectory(file_name_from, file_name_to, true));
1288 // Check the has been copied
1289 EXPECT_TRUE(PathExists(file_name_to));
1292 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExisting) {
1293 // Create a file
1294 FilePath file_name_from =
1295 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1296 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1297 ASSERT_TRUE(PathExists(file_name_from));
1299 // The destination name
1300 FilePath file_name_to = temp_dir_.path().Append(
1301 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1302 CreateTextFile(file_name_to, L"Old file content");
1303 ASSERT_TRUE(PathExists(file_name_to));
1305 EXPECT_TRUE(CopyDirectory(file_name_from, file_name_to, true));
1307 // Check the has been copied
1308 EXPECT_TRUE(PathExists(file_name_to));
1309 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
1312 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExistingDirectory) {
1313 // Create a file
1314 FilePath file_name_from =
1315 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1316 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1317 ASSERT_TRUE(PathExists(file_name_from));
1319 // The destination
1320 FilePath dir_name_to =
1321 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1322 CreateDirectory(dir_name_to);
1323 ASSERT_TRUE(PathExists(dir_name_to));
1324 FilePath file_name_to =
1325 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1327 EXPECT_TRUE(CopyDirectory(file_name_from, dir_name_to, true));
1329 // Check the has been copied
1330 EXPECT_TRUE(PathExists(file_name_to));
1333 TEST_F(FileUtilTest, CopyDirectoryWithTrailingSeparators) {
1334 // Create a directory.
1335 FilePath dir_name_from =
1336 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1337 CreateDirectory(dir_name_from);
1338 ASSERT_TRUE(PathExists(dir_name_from));
1340 // Create a file under the directory.
1341 FilePath file_name_from =
1342 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1343 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1344 ASSERT_TRUE(PathExists(file_name_from));
1346 // Copy the directory recursively.
1347 FilePath dir_name_to =
1348 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1349 FilePath file_name_to =
1350 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1352 // Create from path with trailing separators.
1353 #if defined(OS_WIN)
1354 FilePath from_path =
1355 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir\\\\\\"));
1356 #elif defined (OS_POSIX)
1357 FilePath from_path =
1358 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///"));
1359 #endif
1361 EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true));
1363 // Check everything has been copied.
1364 EXPECT_TRUE(PathExists(dir_name_from));
1365 EXPECT_TRUE(PathExists(file_name_from));
1366 EXPECT_TRUE(PathExists(dir_name_to));
1367 EXPECT_TRUE(PathExists(file_name_to));
1370 // Sets the source file to read-only.
1371 void SetReadOnly(const FilePath& path) {
1372 #if defined(OS_WIN)
1373 // On Windows, it involves setting a bit.
1374 DWORD attrs = GetFileAttributes(path.value().c_str());
1375 ASSERT_NE(INVALID_FILE_ATTRIBUTES, attrs);
1376 ASSERT_TRUE(SetFileAttributes(
1377 path.value().c_str(), attrs | FILE_ATTRIBUTE_READONLY));
1378 attrs = GetFileAttributes(path.value().c_str());
1379 // Files in the temporary directory should not be indexed ever. If this
1380 // assumption change, fix this unit test accordingly.
1381 // FILE_ATTRIBUTE_NOT_CONTENT_INDEXED doesn't exist on XP.
1382 DWORD expected = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY;
1383 if (win::GetVersion() >= win::VERSION_VISTA)
1384 expected |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
1385 ASSERT_EQ(expected, attrs);
1386 #else
1387 // On all other platforms, it involves removing the write bit.
1388 EXPECT_TRUE(SetPosixFilePermissions(path, S_IRUSR));
1389 #endif
1392 bool IsReadOnly(const FilePath& path) {
1393 #if defined(OS_WIN)
1394 DWORD attrs = GetFileAttributes(path.value().c_str());
1395 EXPECT_NE(INVALID_FILE_ATTRIBUTES, attrs);
1396 return attrs & FILE_ATTRIBUTE_READONLY;
1397 #else
1398 int mode = 0;
1399 EXPECT_TRUE(GetPosixFilePermissions(path, &mode));
1400 return !(mode & S_IWUSR);
1401 #endif
1404 TEST_F(FileUtilTest, CopyDirectoryACL) {
1405 // Create a directory.
1406 FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src"));
1407 CreateDirectory(src);
1408 ASSERT_TRUE(PathExists(src));
1410 // Create a file under the directory.
1411 FilePath src_file = src.Append(FILE_PATH_LITERAL("src.txt"));
1412 CreateTextFile(src_file, L"Gooooooooooooooooooooogle");
1413 SetReadOnly(src_file);
1414 ASSERT_TRUE(IsReadOnly(src_file));
1416 // Copy the directory recursively.
1417 FilePath dst = temp_dir_.path().Append(FILE_PATH_LITERAL("dst"));
1418 FilePath dst_file = dst.Append(FILE_PATH_LITERAL("src.txt"));
1419 EXPECT_TRUE(CopyDirectory(src, dst, true));
1421 ASSERT_FALSE(IsReadOnly(dst_file));
1424 TEST_F(FileUtilTest, CopyFile) {
1425 // Create a directory
1426 FilePath dir_name_from =
1427 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1428 CreateDirectory(dir_name_from);
1429 ASSERT_TRUE(PathExists(dir_name_from));
1431 // Create a file under the directory
1432 FilePath file_name_from =
1433 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1434 const std::wstring file_contents(L"Gooooooooooooooooooooogle");
1435 CreateTextFile(file_name_from, file_contents);
1436 ASSERT_TRUE(PathExists(file_name_from));
1438 // Copy the file.
1439 FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt"));
1440 ASSERT_TRUE(CopyFile(file_name_from, dest_file));
1442 // Copy the file to another location using '..' in the path.
1443 FilePath dest_file2(dir_name_from);
1444 dest_file2 = dest_file2.AppendASCII("..");
1445 dest_file2 = dest_file2.AppendASCII("DestFile.txt");
1446 ASSERT_FALSE(CopyFile(file_name_from, dest_file2));
1447 ASSERT_TRUE(internal::CopyFileUnsafe(file_name_from, dest_file2));
1449 FilePath dest_file2_test(dir_name_from);
1450 dest_file2_test = dest_file2_test.DirName();
1451 dest_file2_test = dest_file2_test.AppendASCII("DestFile.txt");
1453 // Check everything has been copied.
1454 EXPECT_TRUE(PathExists(file_name_from));
1455 EXPECT_TRUE(PathExists(dest_file));
1456 const std::wstring read_contents = ReadTextFile(dest_file);
1457 EXPECT_EQ(file_contents, read_contents);
1458 EXPECT_TRUE(PathExists(dest_file2_test));
1459 EXPECT_TRUE(PathExists(dest_file2));
1462 TEST_F(FileUtilTest, CopyFileACL) {
1463 // While FileUtilTest.CopyFile asserts the content is correctly copied over,
1464 // this test case asserts the access control bits are meeting expectations in
1465 // CopyFileUnsafe().
1466 FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src.txt"));
1467 const std::wstring file_contents(L"Gooooooooooooooooooooogle");
1468 CreateTextFile(src, file_contents);
1470 // Set the source file to read-only.
1471 ASSERT_FALSE(IsReadOnly(src));
1472 SetReadOnly(src);
1473 ASSERT_TRUE(IsReadOnly(src));
1475 // Copy the file.
1476 FilePath dst = temp_dir_.path().Append(FILE_PATH_LITERAL("dst.txt"));
1477 ASSERT_TRUE(CopyFile(src, dst));
1478 EXPECT_EQ(file_contents, ReadTextFile(dst));
1480 ASSERT_FALSE(IsReadOnly(dst));
1483 // file_util winds up using autoreleased objects on the Mac, so this needs
1484 // to be a PlatformTest.
1485 typedef PlatformTest ReadOnlyFileUtilTest;
1487 TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
1488 FilePath data_dir;
1489 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
1490 data_dir = data_dir.AppendASCII("file_util");
1491 ASSERT_TRUE(PathExists(data_dir));
1493 FilePath original_file =
1494 data_dir.Append(FILE_PATH_LITERAL("original.txt"));
1495 FilePath same_file =
1496 data_dir.Append(FILE_PATH_LITERAL("same.txt"));
1497 FilePath same_length_file =
1498 data_dir.Append(FILE_PATH_LITERAL("same_length.txt"));
1499 FilePath different_file =
1500 data_dir.Append(FILE_PATH_LITERAL("different.txt"));
1501 FilePath different_first_file =
1502 data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
1503 FilePath different_last_file =
1504 data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
1505 FilePath empty1_file =
1506 data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
1507 FilePath empty2_file =
1508 data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
1509 FilePath shortened_file =
1510 data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
1511 FilePath binary_file =
1512 data_dir.Append(FILE_PATH_LITERAL("binary_file.bin"));
1513 FilePath binary_file_same =
1514 data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin"));
1515 FilePath binary_file_diff =
1516 data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin"));
1518 EXPECT_TRUE(ContentsEqual(original_file, original_file));
1519 EXPECT_TRUE(ContentsEqual(original_file, same_file));
1520 EXPECT_FALSE(ContentsEqual(original_file, same_length_file));
1521 EXPECT_FALSE(ContentsEqual(original_file, different_file));
1522 EXPECT_FALSE(ContentsEqual(FilePath(FILE_PATH_LITERAL("bogusname")),
1523 FilePath(FILE_PATH_LITERAL("bogusname"))));
1524 EXPECT_FALSE(ContentsEqual(original_file, different_first_file));
1525 EXPECT_FALSE(ContentsEqual(original_file, different_last_file));
1526 EXPECT_TRUE(ContentsEqual(empty1_file, empty2_file));
1527 EXPECT_FALSE(ContentsEqual(original_file, shortened_file));
1528 EXPECT_FALSE(ContentsEqual(shortened_file, original_file));
1529 EXPECT_TRUE(ContentsEqual(binary_file, binary_file_same));
1530 EXPECT_FALSE(ContentsEqual(binary_file, binary_file_diff));
1533 TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) {
1534 FilePath data_dir;
1535 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
1536 data_dir = data_dir.AppendASCII("file_util");
1537 ASSERT_TRUE(PathExists(data_dir));
1539 FilePath original_file =
1540 data_dir.Append(FILE_PATH_LITERAL("original.txt"));
1541 FilePath same_file =
1542 data_dir.Append(FILE_PATH_LITERAL("same.txt"));
1543 FilePath crlf_file =
1544 data_dir.Append(FILE_PATH_LITERAL("crlf.txt"));
1545 FilePath shortened_file =
1546 data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
1547 FilePath different_file =
1548 data_dir.Append(FILE_PATH_LITERAL("different.txt"));
1549 FilePath different_first_file =
1550 data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
1551 FilePath different_last_file =
1552 data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
1553 FilePath first1_file =
1554 data_dir.Append(FILE_PATH_LITERAL("first1.txt"));
1555 FilePath first2_file =
1556 data_dir.Append(FILE_PATH_LITERAL("first2.txt"));
1557 FilePath empty1_file =
1558 data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
1559 FilePath empty2_file =
1560 data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
1561 FilePath blank_line_file =
1562 data_dir.Append(FILE_PATH_LITERAL("blank_line.txt"));
1563 FilePath blank_line_crlf_file =
1564 data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt"));
1566 EXPECT_TRUE(TextContentsEqual(original_file, same_file));
1567 EXPECT_TRUE(TextContentsEqual(original_file, crlf_file));
1568 EXPECT_FALSE(TextContentsEqual(original_file, shortened_file));
1569 EXPECT_FALSE(TextContentsEqual(original_file, different_file));
1570 EXPECT_FALSE(TextContentsEqual(original_file, different_first_file));
1571 EXPECT_FALSE(TextContentsEqual(original_file, different_last_file));
1572 EXPECT_FALSE(TextContentsEqual(first1_file, first2_file));
1573 EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file));
1574 EXPECT_FALSE(TextContentsEqual(original_file, empty1_file));
1575 EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file));
1578 // We don't need equivalent functionality outside of Windows.
1579 #if defined(OS_WIN)
1580 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) {
1581 // Create a directory
1582 FilePath dir_name_from =
1583 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir"));
1584 CreateDirectory(dir_name_from);
1585 ASSERT_TRUE(PathExists(dir_name_from));
1587 // Create a file under the directory
1588 FilePath file_name_from =
1589 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
1590 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1591 ASSERT_TRUE(PathExists(file_name_from));
1593 // Move the directory by using CopyAndDeleteDirectory
1594 FilePath dir_name_to = temp_dir_.path().Append(
1595 FILE_PATH_LITERAL("CopyAndDelete_To_Subdir"));
1596 FilePath file_name_to =
1597 dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
1599 ASSERT_FALSE(PathExists(dir_name_to));
1601 EXPECT_TRUE(internal::CopyAndDeleteDirectory(dir_name_from,
1602 dir_name_to));
1604 // Check everything has been moved.
1605 EXPECT_FALSE(PathExists(dir_name_from));
1606 EXPECT_FALSE(PathExists(file_name_from));
1607 EXPECT_TRUE(PathExists(dir_name_to));
1608 EXPECT_TRUE(PathExists(file_name_to));
1611 TEST_F(FileUtilTest, GetTempDirTest) {
1612 static const TCHAR* kTmpKey = _T("TMP");
1613 static const TCHAR* kTmpValues[] = {
1614 _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\")
1616 // Save the original $TMP.
1617 size_t original_tmp_size;
1618 TCHAR* original_tmp;
1619 ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey));
1620 // original_tmp may be NULL.
1622 for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) {
1623 FilePath path;
1624 ::_tputenv_s(kTmpKey, kTmpValues[i]);
1625 GetTempDir(&path);
1626 EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] <<
1627 " result=" << path.value();
1630 // Restore the original $TMP.
1631 if (original_tmp) {
1632 ::_tputenv_s(kTmpKey, original_tmp);
1633 free(original_tmp);
1634 } else {
1635 ::_tputenv_s(kTmpKey, _T(""));
1638 #endif // OS_WIN
1640 TEST_F(FileUtilTest, CreateTemporaryFileTest) {
1641 FilePath temp_files[3];
1642 for (int i = 0; i < 3; i++) {
1643 ASSERT_TRUE(CreateTemporaryFile(&(temp_files[i])));
1644 EXPECT_TRUE(PathExists(temp_files[i]));
1645 EXPECT_FALSE(DirectoryExists(temp_files[i]));
1647 for (int i = 0; i < 3; i++)
1648 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]);
1649 for (int i = 0; i < 3; i++)
1650 EXPECT_TRUE(DeleteFile(temp_files[i], false));
1653 TEST_F(FileUtilTest, CreateAndOpenTemporaryFileTest) {
1654 FilePath names[3];
1655 FILE* fps[3];
1656 int i;
1658 // Create; make sure they are open and exist.
1659 for (i = 0; i < 3; ++i) {
1660 fps[i] = CreateAndOpenTemporaryFile(&(names[i]));
1661 ASSERT_TRUE(fps[i]);
1662 EXPECT_TRUE(PathExists(names[i]));
1665 // Make sure all names are unique.
1666 for (i = 0; i < 3; ++i) {
1667 EXPECT_FALSE(names[i] == names[(i+1)%3]);
1670 // Close and delete.
1671 for (i = 0; i < 3; ++i) {
1672 EXPECT_TRUE(CloseFile(fps[i]));
1673 EXPECT_TRUE(DeleteFile(names[i], false));
1677 TEST_F(FileUtilTest, CreateNewTempDirectoryTest) {
1678 FilePath temp_dir;
1679 ASSERT_TRUE(CreateNewTempDirectory(FilePath::StringType(), &temp_dir));
1680 EXPECT_TRUE(PathExists(temp_dir));
1681 EXPECT_TRUE(DeleteFile(temp_dir, false));
1684 TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) {
1685 FilePath new_dir;
1686 ASSERT_TRUE(CreateTemporaryDirInDir(
1687 temp_dir_.path(),
1688 FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"),
1689 &new_dir));
1690 EXPECT_TRUE(PathExists(new_dir));
1691 EXPECT_TRUE(temp_dir_.path().IsParent(new_dir));
1692 EXPECT_TRUE(DeleteFile(new_dir, false));
1695 #if defined(OS_POSIX)
1696 TEST_F(FileUtilTest, GetShmemTempDirTest) {
1697 FilePath dir;
1698 EXPECT_TRUE(GetShmemTempDir(false, &dir));
1699 EXPECT_TRUE(DirectoryExists(dir));
1701 #endif
1703 TEST_F(FileUtilTest, GetHomeDirTest) {
1704 #if !defined(OS_ANDROID) // Not implemented on Android.
1705 // We don't actually know what the home directory is supposed to be without
1706 // calling some OS functions which would just duplicate the implementation.
1707 // So here we just test that it returns something "reasonable".
1708 FilePath home = GetHomeDir();
1709 ASSERT_FALSE(home.empty());
1710 ASSERT_TRUE(home.IsAbsolute());
1711 #endif
1714 TEST_F(FileUtilTest, CreateDirectoryTest) {
1715 FilePath test_root =
1716 temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test"));
1717 #if defined(OS_WIN)
1718 FilePath test_path =
1719 test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\"));
1720 #elif defined(OS_POSIX)
1721 FilePath test_path =
1722 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/"));
1723 #endif
1725 EXPECT_FALSE(PathExists(test_path));
1726 EXPECT_TRUE(CreateDirectory(test_path));
1727 EXPECT_TRUE(PathExists(test_path));
1728 // CreateDirectory returns true if the DirectoryExists returns true.
1729 EXPECT_TRUE(CreateDirectory(test_path));
1731 // Doesn't work to create it on top of a non-dir
1732 test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt"));
1733 EXPECT_FALSE(PathExists(test_path));
1734 CreateTextFile(test_path, L"test file");
1735 EXPECT_TRUE(PathExists(test_path));
1736 EXPECT_FALSE(CreateDirectory(test_path));
1738 EXPECT_TRUE(DeleteFile(test_root, true));
1739 EXPECT_FALSE(PathExists(test_root));
1740 EXPECT_FALSE(PathExists(test_path));
1742 // Verify assumptions made by the Windows implementation:
1743 // 1. The current directory always exists.
1744 // 2. The root directory always exists.
1745 ASSERT_TRUE(DirectoryExists(FilePath(FilePath::kCurrentDirectory)));
1746 FilePath top_level = test_root;
1747 while (top_level != top_level.DirName()) {
1748 top_level = top_level.DirName();
1750 ASSERT_TRUE(DirectoryExists(top_level));
1752 // Given these assumptions hold, it should be safe to
1753 // test that "creating" these directories succeeds.
1754 EXPECT_TRUE(CreateDirectory(
1755 FilePath(FilePath::kCurrentDirectory)));
1756 EXPECT_TRUE(CreateDirectory(top_level));
1758 #if defined(OS_WIN)
1759 FilePath invalid_drive(FILE_PATH_LITERAL("o:\\"));
1760 FilePath invalid_path =
1761 invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir"));
1762 if (!PathExists(invalid_drive)) {
1763 EXPECT_FALSE(CreateDirectory(invalid_path));
1765 #endif
1768 TEST_F(FileUtilTest, DetectDirectoryTest) {
1769 // Check a directory
1770 FilePath test_root =
1771 temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test"));
1772 EXPECT_FALSE(PathExists(test_root));
1773 EXPECT_TRUE(CreateDirectory(test_root));
1774 EXPECT_TRUE(PathExists(test_root));
1775 EXPECT_TRUE(DirectoryExists(test_root));
1776 // Check a file
1777 FilePath test_path =
1778 test_root.Append(FILE_PATH_LITERAL("foobar.txt"));
1779 EXPECT_FALSE(PathExists(test_path));
1780 CreateTextFile(test_path, L"test file");
1781 EXPECT_TRUE(PathExists(test_path));
1782 EXPECT_FALSE(DirectoryExists(test_path));
1783 EXPECT_TRUE(DeleteFile(test_path, false));
1785 EXPECT_TRUE(DeleteFile(test_root, true));
1788 TEST_F(FileUtilTest, FileEnumeratorTest) {
1789 // Test an empty directory.
1790 FileEnumerator f0(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1791 EXPECT_EQ(f0.Next().value(), FPL(""));
1792 EXPECT_EQ(f0.Next().value(), FPL(""));
1794 // Test an empty directory, non-recursively, including "..".
1795 FileEnumerator f0_dotdot(temp_dir_.path(), false,
1796 FILES_AND_DIRECTORIES | FileEnumerator::INCLUDE_DOT_DOT);
1797 EXPECT_EQ(temp_dir_.path().Append(FPL("..")).value(),
1798 f0_dotdot.Next().value());
1799 EXPECT_EQ(FPL(""), f0_dotdot.Next().value());
1801 // create the directories
1802 FilePath dir1 = temp_dir_.path().Append(FPL("dir1"));
1803 EXPECT_TRUE(CreateDirectory(dir1));
1804 FilePath dir2 = temp_dir_.path().Append(FPL("dir2"));
1805 EXPECT_TRUE(CreateDirectory(dir2));
1806 FilePath dir2inner = dir2.Append(FPL("inner"));
1807 EXPECT_TRUE(CreateDirectory(dir2inner));
1809 // create the files
1810 FilePath dir2file = dir2.Append(FPL("dir2file.txt"));
1811 CreateTextFile(dir2file, std::wstring());
1812 FilePath dir2innerfile = dir2inner.Append(FPL("innerfile.txt"));
1813 CreateTextFile(dir2innerfile, std::wstring());
1814 FilePath file1 = temp_dir_.path().Append(FPL("file1.txt"));
1815 CreateTextFile(file1, std::wstring());
1816 FilePath file2_rel = dir2.Append(FilePath::kParentDirectory)
1817 .Append(FPL("file2.txt"));
1818 CreateTextFile(file2_rel, std::wstring());
1819 FilePath file2_abs = temp_dir_.path().Append(FPL("file2.txt"));
1821 // Only enumerate files.
1822 FileEnumerator f1(temp_dir_.path(), true, FileEnumerator::FILES);
1823 FindResultCollector c1(f1);
1824 EXPECT_TRUE(c1.HasFile(file1));
1825 EXPECT_TRUE(c1.HasFile(file2_abs));
1826 EXPECT_TRUE(c1.HasFile(dir2file));
1827 EXPECT_TRUE(c1.HasFile(dir2innerfile));
1828 EXPECT_EQ(c1.size(), 4);
1830 // Only enumerate directories.
1831 FileEnumerator f2(temp_dir_.path(), true, FileEnumerator::DIRECTORIES);
1832 FindResultCollector c2(f2);
1833 EXPECT_TRUE(c2.HasFile(dir1));
1834 EXPECT_TRUE(c2.HasFile(dir2));
1835 EXPECT_TRUE(c2.HasFile(dir2inner));
1836 EXPECT_EQ(c2.size(), 3);
1838 // Only enumerate directories non-recursively.
1839 FileEnumerator f2_non_recursive(
1840 temp_dir_.path(), false, FileEnumerator::DIRECTORIES);
1841 FindResultCollector c2_non_recursive(f2_non_recursive);
1842 EXPECT_TRUE(c2_non_recursive.HasFile(dir1));
1843 EXPECT_TRUE(c2_non_recursive.HasFile(dir2));
1844 EXPECT_EQ(c2_non_recursive.size(), 2);
1846 // Only enumerate directories, non-recursively, including "..".
1847 FileEnumerator f2_dotdot(temp_dir_.path(), false,
1848 FileEnumerator::DIRECTORIES |
1849 FileEnumerator::INCLUDE_DOT_DOT);
1850 FindResultCollector c2_dotdot(f2_dotdot);
1851 EXPECT_TRUE(c2_dotdot.HasFile(dir1));
1852 EXPECT_TRUE(c2_dotdot.HasFile(dir2));
1853 EXPECT_TRUE(c2_dotdot.HasFile(temp_dir_.path().Append(FPL(".."))));
1854 EXPECT_EQ(c2_dotdot.size(), 3);
1856 // Enumerate files and directories.
1857 FileEnumerator f3(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1858 FindResultCollector c3(f3);
1859 EXPECT_TRUE(c3.HasFile(dir1));
1860 EXPECT_TRUE(c3.HasFile(dir2));
1861 EXPECT_TRUE(c3.HasFile(file1));
1862 EXPECT_TRUE(c3.HasFile(file2_abs));
1863 EXPECT_TRUE(c3.HasFile(dir2file));
1864 EXPECT_TRUE(c3.HasFile(dir2inner));
1865 EXPECT_TRUE(c3.HasFile(dir2innerfile));
1866 EXPECT_EQ(c3.size(), 7);
1868 // Non-recursive operation.
1869 FileEnumerator f4(temp_dir_.path(), false, FILES_AND_DIRECTORIES);
1870 FindResultCollector c4(f4);
1871 EXPECT_TRUE(c4.HasFile(dir2));
1872 EXPECT_TRUE(c4.HasFile(dir2));
1873 EXPECT_TRUE(c4.HasFile(file1));
1874 EXPECT_TRUE(c4.HasFile(file2_abs));
1875 EXPECT_EQ(c4.size(), 4);
1877 // Enumerate with a pattern.
1878 FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*"));
1879 FindResultCollector c5(f5);
1880 EXPECT_TRUE(c5.HasFile(dir1));
1881 EXPECT_TRUE(c5.HasFile(dir2));
1882 EXPECT_TRUE(c5.HasFile(dir2file));
1883 EXPECT_TRUE(c5.HasFile(dir2inner));
1884 EXPECT_TRUE(c5.HasFile(dir2innerfile));
1885 EXPECT_EQ(c5.size(), 5);
1887 #if defined(OS_WIN)
1889 // Make dir1 point to dir2.
1890 ReparsePoint reparse_point(dir1, dir2);
1891 EXPECT_TRUE(reparse_point.IsValid());
1893 if ((win::GetVersion() >= win::VERSION_VISTA)) {
1894 // There can be a delay for the enumeration code to see the change on
1895 // the file system so skip this test for XP.
1896 // Enumerate the reparse point.
1897 FileEnumerator f6(dir1, true, FILES_AND_DIRECTORIES);
1898 FindResultCollector c6(f6);
1899 FilePath inner2 = dir1.Append(FPL("inner"));
1900 EXPECT_TRUE(c6.HasFile(inner2));
1901 EXPECT_TRUE(c6.HasFile(inner2.Append(FPL("innerfile.txt"))));
1902 EXPECT_TRUE(c6.HasFile(dir1.Append(FPL("dir2file.txt"))));
1903 EXPECT_EQ(c6.size(), 3);
1906 // No changes for non recursive operation.
1907 FileEnumerator f7(temp_dir_.path(), false, FILES_AND_DIRECTORIES);
1908 FindResultCollector c7(f7);
1909 EXPECT_TRUE(c7.HasFile(dir2));
1910 EXPECT_TRUE(c7.HasFile(dir2));
1911 EXPECT_TRUE(c7.HasFile(file1));
1912 EXPECT_TRUE(c7.HasFile(file2_abs));
1913 EXPECT_EQ(c7.size(), 4);
1915 // Should not enumerate inside dir1 when using recursion.
1916 FileEnumerator f8(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1917 FindResultCollector c8(f8);
1918 EXPECT_TRUE(c8.HasFile(dir1));
1919 EXPECT_TRUE(c8.HasFile(dir2));
1920 EXPECT_TRUE(c8.HasFile(file1));
1921 EXPECT_TRUE(c8.HasFile(file2_abs));
1922 EXPECT_TRUE(c8.HasFile(dir2file));
1923 EXPECT_TRUE(c8.HasFile(dir2inner));
1924 EXPECT_TRUE(c8.HasFile(dir2innerfile));
1925 EXPECT_EQ(c8.size(), 7);
1927 #endif
1929 // Make sure the destructor closes the find handle while in the middle of a
1930 // query to allow TearDown to delete the directory.
1931 FileEnumerator f9(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1932 EXPECT_FALSE(f9.Next().value().empty()); // Should have found something
1933 // (we don't care what).
1936 TEST_F(FileUtilTest, AppendToFile) {
1937 FilePath data_dir =
1938 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
1940 // Create a fresh, empty copy of this directory.
1941 if (PathExists(data_dir)) {
1942 ASSERT_TRUE(DeleteFile(data_dir, true));
1944 ASSERT_TRUE(CreateDirectory(data_dir));
1946 // Create a fresh, empty copy of this directory.
1947 if (PathExists(data_dir)) {
1948 ASSERT_TRUE(DeleteFile(data_dir, true));
1950 ASSERT_TRUE(CreateDirectory(data_dir));
1951 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
1953 std::string data("hello");
1954 EXPECT_EQ(-1, AppendToFile(foobar, data.c_str(), data.length()));
1955 EXPECT_EQ(static_cast<int>(data.length()),
1956 WriteFile(foobar, data.c_str(), data.length()));
1957 EXPECT_EQ(static_cast<int>(data.length()),
1958 AppendToFile(foobar, data.c_str(), data.length()));
1960 const std::wstring read_content = ReadTextFile(foobar);
1961 EXPECT_EQ(L"hellohello", read_content);
1964 TEST_F(FileUtilTest, ReadFile) {
1965 // Create a test file to be read.
1966 const std::string kTestData("The quick brown fox jumps over the lazy dog.");
1967 FilePath file_path =
1968 temp_dir_.path().Append(FILE_PATH_LITERAL("ReadFileTest"));
1970 ASSERT_EQ(static_cast<int>(kTestData.size()),
1971 WriteFile(file_path, kTestData.data(), kTestData.size()));
1973 // Make buffers with various size.
1974 std::vector<char> small_buffer(kTestData.size() / 2);
1975 std::vector<char> exact_buffer(kTestData.size());
1976 std::vector<char> large_buffer(kTestData.size() * 2);
1978 // Read the file with smaller buffer.
1979 int bytes_read_small = ReadFile(
1980 file_path, &small_buffer[0], static_cast<int>(small_buffer.size()));
1981 EXPECT_EQ(bytes_read_small, static_cast<int>(small_buffer.size()));
1982 EXPECT_EQ(
1983 std::string(small_buffer.begin(), small_buffer.end()),
1984 std::string(kTestData.begin(), kTestData.begin() + small_buffer.size()));
1986 // Read the file with buffer which have exactly same size.
1987 int bytes_read_exact = ReadFile(
1988 file_path, &exact_buffer[0], static_cast<int>(exact_buffer.size()));
1989 EXPECT_EQ(bytes_read_exact, static_cast<int>(kTestData.size()));
1990 EXPECT_EQ(std::string(exact_buffer.begin(), exact_buffer.end()), kTestData);
1992 // Read the file with larger buffer.
1993 int bytes_read_large = ReadFile(
1994 file_path, &large_buffer[0], static_cast<int>(large_buffer.size()));
1995 EXPECT_EQ(bytes_read_large, static_cast<int>(kTestData.size()));
1996 EXPECT_EQ(std::string(large_buffer.begin(),
1997 large_buffer.begin() + kTestData.size()),
1998 kTestData);
2000 // Make sure the return value is -1 if the file doesn't exist.
2001 FilePath file_path_not_exist =
2002 temp_dir_.path().Append(FILE_PATH_LITERAL("ReadFileNotExistTest"));
2003 EXPECT_EQ(-1,
2004 ReadFile(file_path_not_exist,
2005 &exact_buffer[0],
2006 static_cast<int>(exact_buffer.size())));
2009 TEST_F(FileUtilTest, ReadFileToString) {
2010 const char kTestData[] = "0123";
2011 std::string data;
2013 FilePath file_path =
2014 temp_dir_.path().Append(FILE_PATH_LITERAL("ReadFileToStringTest"));
2016 ASSERT_EQ(4, WriteFile(file_path, kTestData, 4));
2018 EXPECT_TRUE(ReadFileToString(file_path, &data));
2019 EXPECT_EQ(kTestData, data);
2021 data = "temp";
2022 EXPECT_FALSE(ReadFileToString(file_path, &data, 0));
2023 EXPECT_EQ(data.length(), 0u);
2025 data = "temp";
2026 EXPECT_FALSE(ReadFileToString(file_path, &data, 2));
2027 EXPECT_EQ("01", data);
2029 data.clear();
2030 EXPECT_FALSE(ReadFileToString(file_path, &data, 3));
2031 EXPECT_EQ("012", data);
2033 data.clear();
2034 EXPECT_TRUE(ReadFileToString(file_path, &data, 4));
2035 EXPECT_EQ("0123", data);
2037 data.clear();
2038 EXPECT_TRUE(ReadFileToString(file_path, &data, 6));
2039 EXPECT_EQ("0123", data);
2041 EXPECT_TRUE(ReadFileToString(file_path, NULL, 6));
2043 EXPECT_TRUE(ReadFileToString(file_path, NULL));
2045 EXPECT_TRUE(base::DeleteFile(file_path, false));
2047 data = "temp";
2048 EXPECT_FALSE(ReadFileToString(file_path, &data));
2049 EXPECT_EQ(data.length(), 0u);
2051 data = "temp";
2052 EXPECT_FALSE(ReadFileToString(file_path, &data, 6));
2053 EXPECT_EQ(data.length(), 0u);
2056 TEST_F(FileUtilTest, TouchFile) {
2057 FilePath data_dir =
2058 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
2060 // Create a fresh, empty copy of this directory.
2061 if (PathExists(data_dir)) {
2062 ASSERT_TRUE(DeleteFile(data_dir, true));
2064 ASSERT_TRUE(CreateDirectory(data_dir));
2066 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
2067 std::string data("hello");
2068 ASSERT_TRUE(WriteFile(foobar, data.c_str(), data.length()));
2070 Time access_time;
2071 // This timestamp is divisible by one day (in local timezone),
2072 // to make it work on FAT too.
2073 ASSERT_TRUE(Time::FromString("Wed, 16 Nov 1994, 00:00:00",
2074 &access_time));
2076 Time modification_time;
2077 // Note that this timestamp is divisible by two (seconds) - FAT stores
2078 // modification times with 2s resolution.
2079 ASSERT_TRUE(Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT",
2080 &modification_time));
2082 ASSERT_TRUE(TouchFile(foobar, access_time, modification_time));
2083 File::Info file_info;
2084 ASSERT_TRUE(GetFileInfo(foobar, &file_info));
2085 EXPECT_EQ(file_info.last_accessed.ToInternalValue(),
2086 access_time.ToInternalValue());
2087 EXPECT_EQ(file_info.last_modified.ToInternalValue(),
2088 modification_time.ToInternalValue());
2091 TEST_F(FileUtilTest, IsDirectoryEmpty) {
2092 FilePath empty_dir = temp_dir_.path().Append(FILE_PATH_LITERAL("EmptyDir"));
2094 ASSERT_FALSE(PathExists(empty_dir));
2096 ASSERT_TRUE(CreateDirectory(empty_dir));
2098 EXPECT_TRUE(IsDirectoryEmpty(empty_dir));
2100 FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt")));
2101 std::string bar("baz");
2102 ASSERT_TRUE(WriteFile(foo, bar.c_str(), bar.length()));
2104 EXPECT_FALSE(IsDirectoryEmpty(empty_dir));
2107 #if defined(OS_POSIX)
2109 // Testing VerifyPathControlledByAdmin() is hard, because there is no
2110 // way a test can make a file owned by root, or change file paths
2111 // at the root of the file system. VerifyPathControlledByAdmin()
2112 // is implemented as a call to VerifyPathControlledByUser, which gives
2113 // us the ability to test with paths under the test's temp directory,
2114 // using a user id we control.
2115 // Pull tests of VerifyPathControlledByUserTest() into a separate test class
2116 // with a common SetUp() method.
2117 class VerifyPathControlledByUserTest : public FileUtilTest {
2118 protected:
2119 virtual void SetUp() OVERRIDE {
2120 FileUtilTest::SetUp();
2122 // Create a basic structure used by each test.
2123 // base_dir_
2124 // |-> sub_dir_
2125 // |-> text_file_
2127 base_dir_ = temp_dir_.path().AppendASCII("base_dir");
2128 ASSERT_TRUE(CreateDirectory(base_dir_));
2130 sub_dir_ = base_dir_.AppendASCII("sub_dir");
2131 ASSERT_TRUE(CreateDirectory(sub_dir_));
2133 text_file_ = sub_dir_.AppendASCII("file.txt");
2134 CreateTextFile(text_file_, L"This text file has some text in it.");
2136 // Get the user and group files are created with from |base_dir_|.
2137 struct stat stat_buf;
2138 ASSERT_EQ(0, stat(base_dir_.value().c_str(), &stat_buf));
2139 uid_ = stat_buf.st_uid;
2140 ok_gids_.insert(stat_buf.st_gid);
2141 bad_gids_.insert(stat_buf.st_gid + 1);
2143 ASSERT_EQ(uid_, getuid()); // This process should be the owner.
2145 // To ensure that umask settings do not cause the initial state
2146 // of permissions to be different from what we expect, explicitly
2147 // set permissions on the directories we create.
2148 // Make all files and directories non-world-writable.
2150 // Users and group can read, write, traverse
2151 int enabled_permissions =
2152 FILE_PERMISSION_USER_MASK | FILE_PERMISSION_GROUP_MASK;
2153 // Other users can't read, write, traverse
2154 int disabled_permissions = FILE_PERMISSION_OTHERS_MASK;
2156 ASSERT_NO_FATAL_FAILURE(
2157 ChangePosixFilePermissions(
2158 base_dir_, enabled_permissions, disabled_permissions));
2159 ASSERT_NO_FATAL_FAILURE(
2160 ChangePosixFilePermissions(
2161 sub_dir_, enabled_permissions, disabled_permissions));
2164 FilePath base_dir_;
2165 FilePath sub_dir_;
2166 FilePath text_file_;
2167 uid_t uid_;
2169 std::set<gid_t> ok_gids_;
2170 std::set<gid_t> bad_gids_;
2173 TEST_F(VerifyPathControlledByUserTest, BadPaths) {
2174 // File does not exist.
2175 FilePath does_not_exist = base_dir_.AppendASCII("does")
2176 .AppendASCII("not")
2177 .AppendASCII("exist");
2178 EXPECT_FALSE(
2179 base::VerifyPathControlledByUser(
2180 base_dir_, does_not_exist, uid_, ok_gids_));
2182 // |base| not a subpath of |path|.
2183 EXPECT_FALSE(
2184 base::VerifyPathControlledByUser(
2185 sub_dir_, base_dir_, uid_, ok_gids_));
2187 // An empty base path will fail to be a prefix for any path.
2188 FilePath empty;
2189 EXPECT_FALSE(
2190 base::VerifyPathControlledByUser(
2191 empty, base_dir_, uid_, ok_gids_));
2193 // Finding that a bad call fails proves nothing unless a good call succeeds.
2194 EXPECT_TRUE(
2195 base::VerifyPathControlledByUser(
2196 base_dir_, sub_dir_, uid_, ok_gids_));
2199 TEST_F(VerifyPathControlledByUserTest, Symlinks) {
2200 // Symlinks in the path should cause failure.
2202 // Symlink to the file at the end of the path.
2203 FilePath file_link = base_dir_.AppendASCII("file_link");
2204 ASSERT_TRUE(CreateSymbolicLink(text_file_, file_link))
2205 << "Failed to create symlink.";
2207 EXPECT_FALSE(
2208 base::VerifyPathControlledByUser(
2209 base_dir_, file_link, uid_, ok_gids_));
2210 EXPECT_FALSE(
2211 base::VerifyPathControlledByUser(
2212 file_link, file_link, uid_, ok_gids_));
2214 // Symlink from one directory to another within the path.
2215 FilePath link_to_sub_dir = base_dir_.AppendASCII("link_to_sub_dir");
2216 ASSERT_TRUE(CreateSymbolicLink(sub_dir_, link_to_sub_dir))
2217 << "Failed to create symlink.";
2219 FilePath file_path_with_link = link_to_sub_dir.AppendASCII("file.txt");
2220 ASSERT_TRUE(PathExists(file_path_with_link));
2222 EXPECT_FALSE(
2223 base::VerifyPathControlledByUser(
2224 base_dir_, file_path_with_link, uid_, ok_gids_));
2226 EXPECT_FALSE(
2227 base::VerifyPathControlledByUser(
2228 link_to_sub_dir, file_path_with_link, uid_, ok_gids_));
2230 // Symlinks in parents of base path are allowed.
2231 EXPECT_TRUE(
2232 base::VerifyPathControlledByUser(
2233 file_path_with_link, file_path_with_link, uid_, ok_gids_));
2236 TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) {
2237 // Get a uid that is not the uid of files we create.
2238 uid_t bad_uid = uid_ + 1;
2240 // Make all files and directories non-world-writable.
2241 ASSERT_NO_FATAL_FAILURE(
2242 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
2243 ASSERT_NO_FATAL_FAILURE(
2244 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
2245 ASSERT_NO_FATAL_FAILURE(
2246 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
2248 // We control these paths.
2249 EXPECT_TRUE(
2250 base::VerifyPathControlledByUser(
2251 base_dir_, sub_dir_, uid_, ok_gids_));
2252 EXPECT_TRUE(
2253 base::VerifyPathControlledByUser(
2254 base_dir_, text_file_, uid_, ok_gids_));
2255 EXPECT_TRUE(
2256 base::VerifyPathControlledByUser(
2257 sub_dir_, text_file_, uid_, ok_gids_));
2259 // Another user does not control these paths.
2260 EXPECT_FALSE(
2261 base::VerifyPathControlledByUser(
2262 base_dir_, sub_dir_, bad_uid, ok_gids_));
2263 EXPECT_FALSE(
2264 base::VerifyPathControlledByUser(
2265 base_dir_, text_file_, bad_uid, ok_gids_));
2266 EXPECT_FALSE(
2267 base::VerifyPathControlledByUser(
2268 sub_dir_, text_file_, bad_uid, ok_gids_));
2270 // Another group does not control the paths.
2271 EXPECT_FALSE(
2272 base::VerifyPathControlledByUser(
2273 base_dir_, sub_dir_, uid_, bad_gids_));
2274 EXPECT_FALSE(
2275 base::VerifyPathControlledByUser(
2276 base_dir_, text_file_, uid_, bad_gids_));
2277 EXPECT_FALSE(
2278 base::VerifyPathControlledByUser(
2279 sub_dir_, text_file_, uid_, bad_gids_));
2282 TEST_F(VerifyPathControlledByUserTest, GroupWriteTest) {
2283 // Make all files and directories writable only by their owner.
2284 ASSERT_NO_FATAL_FAILURE(
2285 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH|S_IWGRP));
2286 ASSERT_NO_FATAL_FAILURE(
2287 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH|S_IWGRP));
2288 ASSERT_NO_FATAL_FAILURE(
2289 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH|S_IWGRP));
2291 // Any group is okay because the path is not group-writable.
2292 EXPECT_TRUE(
2293 base::VerifyPathControlledByUser(
2294 base_dir_, sub_dir_, uid_, ok_gids_));
2295 EXPECT_TRUE(
2296 base::VerifyPathControlledByUser(
2297 base_dir_, text_file_, uid_, ok_gids_));
2298 EXPECT_TRUE(
2299 base::VerifyPathControlledByUser(
2300 sub_dir_, text_file_, uid_, ok_gids_));
2302 EXPECT_TRUE(
2303 base::VerifyPathControlledByUser(
2304 base_dir_, sub_dir_, uid_, bad_gids_));
2305 EXPECT_TRUE(
2306 base::VerifyPathControlledByUser(
2307 base_dir_, text_file_, uid_, bad_gids_));
2308 EXPECT_TRUE(
2309 base::VerifyPathControlledByUser(
2310 sub_dir_, text_file_, uid_, bad_gids_));
2312 // No group is okay, because we don't check the group
2313 // if no group can write.
2314 std::set<gid_t> no_gids; // Empty set of gids.
2315 EXPECT_TRUE(
2316 base::VerifyPathControlledByUser(
2317 base_dir_, sub_dir_, uid_, no_gids));
2318 EXPECT_TRUE(
2319 base::VerifyPathControlledByUser(
2320 base_dir_, text_file_, uid_, no_gids));
2321 EXPECT_TRUE(
2322 base::VerifyPathControlledByUser(
2323 sub_dir_, text_file_, uid_, no_gids));
2326 // Make all files and directories writable by their group.
2327 ASSERT_NO_FATAL_FAILURE(
2328 ChangePosixFilePermissions(base_dir_, S_IWGRP, 0u));
2329 ASSERT_NO_FATAL_FAILURE(
2330 ChangePosixFilePermissions(sub_dir_, S_IWGRP, 0u));
2331 ASSERT_NO_FATAL_FAILURE(
2332 ChangePosixFilePermissions(text_file_, S_IWGRP, 0u));
2334 // Now |ok_gids_| works, but |bad_gids_| fails.
2335 EXPECT_TRUE(
2336 base::VerifyPathControlledByUser(
2337 base_dir_, sub_dir_, uid_, ok_gids_));
2338 EXPECT_TRUE(
2339 base::VerifyPathControlledByUser(
2340 base_dir_, text_file_, uid_, ok_gids_));
2341 EXPECT_TRUE(
2342 base::VerifyPathControlledByUser(
2343 sub_dir_, text_file_, uid_, ok_gids_));
2345 EXPECT_FALSE(
2346 base::VerifyPathControlledByUser(
2347 base_dir_, sub_dir_, uid_, bad_gids_));
2348 EXPECT_FALSE(
2349 base::VerifyPathControlledByUser(
2350 base_dir_, text_file_, uid_, bad_gids_));
2351 EXPECT_FALSE(
2352 base::VerifyPathControlledByUser(
2353 sub_dir_, text_file_, uid_, bad_gids_));
2355 // Because any group in the group set is allowed,
2356 // the union of good and bad gids passes.
2358 std::set<gid_t> multiple_gids;
2359 std::set_union(
2360 ok_gids_.begin(), ok_gids_.end(),
2361 bad_gids_.begin(), bad_gids_.end(),
2362 std::inserter(multiple_gids, multiple_gids.begin()));
2364 EXPECT_TRUE(
2365 base::VerifyPathControlledByUser(
2366 base_dir_, sub_dir_, uid_, multiple_gids));
2367 EXPECT_TRUE(
2368 base::VerifyPathControlledByUser(
2369 base_dir_, text_file_, uid_, multiple_gids));
2370 EXPECT_TRUE(
2371 base::VerifyPathControlledByUser(
2372 sub_dir_, text_file_, uid_, multiple_gids));
2375 TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) {
2376 // Make all files and directories non-world-writable.
2377 ASSERT_NO_FATAL_FAILURE(
2378 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
2379 ASSERT_NO_FATAL_FAILURE(
2380 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
2381 ASSERT_NO_FATAL_FAILURE(
2382 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
2384 // Initialy, we control all parts of the path.
2385 EXPECT_TRUE(
2386 base::VerifyPathControlledByUser(
2387 base_dir_, sub_dir_, uid_, ok_gids_));
2388 EXPECT_TRUE(
2389 base::VerifyPathControlledByUser(
2390 base_dir_, text_file_, uid_, ok_gids_));
2391 EXPECT_TRUE(
2392 base::VerifyPathControlledByUser(
2393 sub_dir_, text_file_, uid_, ok_gids_));
2395 // Make base_dir_ world-writable.
2396 ASSERT_NO_FATAL_FAILURE(
2397 ChangePosixFilePermissions(base_dir_, S_IWOTH, 0u));
2398 EXPECT_FALSE(
2399 base::VerifyPathControlledByUser(
2400 base_dir_, sub_dir_, uid_, ok_gids_));
2401 EXPECT_FALSE(
2402 base::VerifyPathControlledByUser(
2403 base_dir_, text_file_, uid_, ok_gids_));
2404 EXPECT_TRUE(
2405 base::VerifyPathControlledByUser(
2406 sub_dir_, text_file_, uid_, ok_gids_));
2408 // Make sub_dir_ world writable.
2409 ASSERT_NO_FATAL_FAILURE(
2410 ChangePosixFilePermissions(sub_dir_, S_IWOTH, 0u));
2411 EXPECT_FALSE(
2412 base::VerifyPathControlledByUser(
2413 base_dir_, sub_dir_, uid_, ok_gids_));
2414 EXPECT_FALSE(
2415 base::VerifyPathControlledByUser(
2416 base_dir_, text_file_, uid_, ok_gids_));
2417 EXPECT_FALSE(
2418 base::VerifyPathControlledByUser(
2419 sub_dir_, text_file_, uid_, ok_gids_));
2421 // Make text_file_ world writable.
2422 ASSERT_NO_FATAL_FAILURE(
2423 ChangePosixFilePermissions(text_file_, S_IWOTH, 0u));
2424 EXPECT_FALSE(
2425 base::VerifyPathControlledByUser(
2426 base_dir_, sub_dir_, uid_, ok_gids_));
2427 EXPECT_FALSE(
2428 base::VerifyPathControlledByUser(
2429 base_dir_, text_file_, uid_, ok_gids_));
2430 EXPECT_FALSE(
2431 base::VerifyPathControlledByUser(
2432 sub_dir_, text_file_, uid_, ok_gids_));
2434 // Make sub_dir_ non-world writable.
2435 ASSERT_NO_FATAL_FAILURE(
2436 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
2437 EXPECT_FALSE(
2438 base::VerifyPathControlledByUser(
2439 base_dir_, sub_dir_, uid_, ok_gids_));
2440 EXPECT_FALSE(
2441 base::VerifyPathControlledByUser(
2442 base_dir_, text_file_, uid_, ok_gids_));
2443 EXPECT_FALSE(
2444 base::VerifyPathControlledByUser(
2445 sub_dir_, text_file_, uid_, ok_gids_));
2447 // Make base_dir_ non-world-writable.
2448 ASSERT_NO_FATAL_FAILURE(
2449 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
2450 EXPECT_TRUE(
2451 base::VerifyPathControlledByUser(
2452 base_dir_, sub_dir_, uid_, ok_gids_));
2453 EXPECT_FALSE(
2454 base::VerifyPathControlledByUser(
2455 base_dir_, text_file_, uid_, ok_gids_));
2456 EXPECT_FALSE(
2457 base::VerifyPathControlledByUser(
2458 sub_dir_, text_file_, uid_, ok_gids_));
2460 // Back to the initial state: Nothing is writable, so every path
2461 // should pass.
2462 ASSERT_NO_FATAL_FAILURE(
2463 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
2464 EXPECT_TRUE(
2465 base::VerifyPathControlledByUser(
2466 base_dir_, sub_dir_, uid_, ok_gids_));
2467 EXPECT_TRUE(
2468 base::VerifyPathControlledByUser(
2469 base_dir_, text_file_, uid_, ok_gids_));
2470 EXPECT_TRUE(
2471 base::VerifyPathControlledByUser(
2472 sub_dir_, text_file_, uid_, ok_gids_));
2475 #if defined(OS_ANDROID)
2476 TEST_F(FileUtilTest, ValidContentUriTest) {
2477 // Get the test image path.
2478 FilePath data_dir;
2479 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
2480 data_dir = data_dir.AppendASCII("file_util");
2481 ASSERT_TRUE(PathExists(data_dir));
2482 FilePath image_file = data_dir.Append(FILE_PATH_LITERAL("red.png"));
2483 int64 image_size;
2484 GetFileSize(image_file, &image_size);
2485 EXPECT_LT(0, image_size);
2487 // Insert the image into MediaStore. MediaStore will do some conversions, and
2488 // return the content URI.
2489 FilePath path = file_util::InsertImageIntoMediaStore(image_file);
2490 EXPECT_TRUE(path.IsContentUri());
2491 EXPECT_TRUE(PathExists(path));
2492 // The file size may not equal to the input image as MediaStore may convert
2493 // the image.
2494 int64 content_uri_size;
2495 GetFileSize(path, &content_uri_size);
2496 EXPECT_EQ(image_size, content_uri_size);
2498 // We should be able to read the file.
2499 char* buffer = new char[image_size];
2500 File file = OpenContentUriForRead(path);
2501 EXPECT_TRUE(file.IsValid());
2502 EXPECT_TRUE(file.ReadAtCurrentPos(buffer, image_size));
2503 delete[] buffer;
2506 TEST_F(FileUtilTest, NonExistentContentUriTest) {
2507 FilePath path("content://foo.bar");
2508 EXPECT_TRUE(path.IsContentUri());
2509 EXPECT_FALSE(PathExists(path));
2510 // Size should be smaller than 0.
2511 int64 size;
2512 EXPECT_FALSE(GetFileSize(path, &size));
2514 // We should not be able to read the file.
2515 File file = OpenContentUriForRead(path);
2516 EXPECT_FALSE(file.IsValid());
2518 #endif
2520 TEST(ScopedFD, ScopedFDDoesClose) {
2521 int fds[2];
2522 char c = 0;
2523 ASSERT_EQ(0, pipe(fds));
2524 const int write_end = fds[1];
2525 base::ScopedFD read_end_closer(fds[0]);
2527 base::ScopedFD write_end_closer(fds[1]);
2529 // This is the only thread. This file descriptor should no longer be valid.
2530 int ret = close(write_end);
2531 EXPECT_EQ(-1, ret);
2532 EXPECT_EQ(EBADF, errno);
2533 // Make sure read(2) won't block.
2534 ASSERT_EQ(0, fcntl(fds[0], F_SETFL, O_NONBLOCK));
2535 // Reading the pipe should EOF.
2536 EXPECT_EQ(0, read(fds[0], &c, 1));
2539 #if defined(GTEST_HAS_DEATH_TEST)
2540 void CloseWithScopedFD(int fd) {
2541 base::ScopedFD fd_closer(fd);
2543 #endif
2545 TEST(ScopedFD, ScopedFDCrashesOnCloseFailure) {
2546 int fds[2];
2547 ASSERT_EQ(0, pipe(fds));
2548 base::ScopedFD read_end_closer(fds[0]);
2549 EXPECT_EQ(0, IGNORE_EINTR(close(fds[1])));
2550 #if defined(GTEST_HAS_DEATH_TEST)
2551 // This is the only thread. This file descriptor should no longer be valid.
2552 // Trying to close it should crash. This is important for security.
2553 EXPECT_DEATH(CloseWithScopedFD(fds[1]), "");
2554 #endif
2557 #endif // defined(OS_POSIX)
2559 } // namespace
2561 } // namespace base