OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #if defined(OS_WIN) | |
8 #include <windows.h> | |
9 #include <shellapi.h> | |
10 #include <shlobj.h> | |
11 #include <tchar.h> | |
12 #include <winioctl.h> | |
13 #endif | |
14 | |
15 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
16 #include <errno.h> | 8 #include <errno.h> |
17 #include <fcntl.h> | 9 #include <fcntl.h> |
18 #include <unistd.h> | 10 #include <unistd.h> |
19 #endif | 11 #endif |
20 | 12 |
21 #include <algorithm> | 13 #include <algorithm> |
22 #include <fstream> | 14 #include <fstream> |
23 #include <set> | 15 #include <set> |
24 #include <vector> | 16 #include <vector> |
25 | 17 |
26 #include "base/base_paths.h" | 18 #include "base/base_paths.h" |
27 #include "base/files/file_enumerator.h" | 19 #include "base/files/file_enumerator.h" |
28 #include "base/files/file_path.h" | 20 #include "base/files/file_path.h" |
29 #include "base/files/file_util.h" | 21 #include "base/files/file_util.h" |
30 #include "base/files/scoped_file.h" | 22 #include "base/files/scoped_file.h" |
31 #include "base/files/scoped_temp_dir.h" | 23 #include "base/files/scoped_temp_dir.h" |
32 #include "base/path_service.h" | 24 #include "base/path_service.h" |
33 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
34 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
35 #include "base/test/test_file_util.h" | 27 #include "base/test/test_file_util.h" |
36 #include "base/threading/platform_thread.h" | 28 #include "base/threading/platform_thread.h" |
37 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
38 #include "testing/platform_test.h" | 30 #include "testing/platform_test.h" |
39 | 31 |
40 #if defined(OS_WIN) | |
41 #include "base/win/scoped_handle.h" | |
42 #include "base/win/windows_version.h" | |
43 #endif | |
44 | |
45 #if defined(OS_ANDROID) | 32 #if defined(OS_ANDROID) |
46 #include "base/android/content_uri_utils.h" | 33 #include "base/android/content_uri_utils.h" |
47 #endif | 34 #endif |
48 | 35 |
49 // This macro helps avoid wrapped lines in the test structs. | 36 // This macro helps avoid wrapped lines in the test structs. |
50 #define FPL(x) FILE_PATH_LITERAL(x) | 37 #define FPL(x) FILE_PATH_LITERAL(x) |
51 | 38 |
52 namespace base { | 39 namespace base { |
53 | 40 |
54 namespace { | 41 namespace { |
55 | 42 |
56 // To test that NormalizeFilePath() deals with NTFS reparse points correctly, | 43 // To test that NormalizeFilePath() deals with NTFS reparse points correctly, |
57 // we need functions to create and delete reparse points. | 44 // we need functions to create and delete reparse points. |
58 #if defined(OS_WIN) | |
59 typedef struct _REPARSE_DATA_BUFFER { | |
60 ULONG ReparseTag; | |
61 USHORT ReparseDataLength; | |
62 USHORT Reserved; | |
63 union { | |
64 struct { | |
65 USHORT SubstituteNameOffset; | |
66 USHORT SubstituteNameLength; | |
67 USHORT PrintNameOffset; | |
68 USHORT PrintNameLength; | |
69 ULONG Flags; | |
70 WCHAR PathBuffer[1]; | |
71 } SymbolicLinkReparseBuffer; | |
72 struct { | |
73 USHORT SubstituteNameOffset; | |
74 USHORT SubstituteNameLength; | |
75 USHORT PrintNameOffset; | |
76 USHORT PrintNameLength; | |
77 WCHAR PathBuffer[1]; | |
78 } MountPointReparseBuffer; | |
79 struct { | |
80 UCHAR DataBuffer[1]; | |
81 } GenericReparseBuffer; | |
82 }; | |
83 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; | |
84 | |
85 // Sets a reparse point. |source| will now point to |target|. Returns true if | |
86 // the call succeeds, false otherwise. | |
87 bool SetReparsePoint(HANDLE source, const FilePath& target_path) { | |
88 std::wstring kPathPrefix = L"\\??\\"; | |
89 std::wstring target_str; | |
90 // The juction will not work if the target path does not start with \??\ . | |
91 if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size())) | |
92 target_str += kPathPrefix; | |
93 target_str += target_path.value(); | |
94 const wchar_t* target = target_str.c_str(); | |
95 USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]); | |
96 char buffer[2000] = {0}; | |
97 DWORD returned; | |
98 | |
99 REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer); | |
100 | |
101 data->ReparseTag = 0xa0000003; | |
102 memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2); | |
103 | |
104 data->MountPointReparseBuffer.SubstituteNameLength = size_target; | |
105 data->MountPointReparseBuffer.PrintNameOffset = size_target + 2; | |
106 data->ReparseDataLength = size_target + 4 + 8; | |
107 | |
108 int data_size = data->ReparseDataLength + 8; | |
109 | |
110 if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size, | |
111 NULL, 0, &returned, NULL)) { | |
112 return false; | |
113 } | |
114 return true; | |
115 } | |
116 | |
117 // Delete the reparse point referenced by |source|. Returns true if the call | |
118 // succeeds, false otherwise. | |
119 bool DeleteReparsePoint(HANDLE source) { | |
120 DWORD returned; | |
121 REPARSE_DATA_BUFFER data = {0}; | |
122 data.ReparseTag = 0xa0000003; | |
123 if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0, | |
124 &returned, NULL)) { | |
125 return false; | |
126 } | |
127 return true; | |
128 } | |
129 | |
130 // Manages a reparse point for a test. | |
131 class ReparsePoint { | |
132 public: | |
133 // Creates a reparse point from |source| (an empty directory) to |target|. | |
134 ReparsePoint(const FilePath& source, const FilePath& target) { | |
135 dir_.Set( | |
136 ::CreateFile(source.value().c_str(), | |
137 FILE_ALL_ACCESS, | |
138 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | |
139 NULL, | |
140 OPEN_EXISTING, | |
141 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. | |
142 NULL)); | |
143 created_ = dir_.IsValid() && SetReparsePoint(dir_.Get(), target); | |
144 } | |
145 | |
146 ~ReparsePoint() { | |
147 if (created_) | |
148 DeleteReparsePoint(dir_.Get()); | |
149 } | |
150 | |
151 bool IsValid() { return created_; } | |
152 | |
153 private: | |
154 win::ScopedHandle dir_; | |
155 bool created_; | |
156 DISALLOW_COPY_AND_ASSIGN(ReparsePoint); | |
157 }; | |
158 | |
159 #endif | |
160 | |
161 #if defined(OS_POSIX) | 45 #if defined(OS_POSIX) |
162 // Provide a simple way to change the permissions bits on |path| in tests. | 46 // Provide a simple way to change the permissions bits on |path| in tests. |
163 // ASSERT failures will return, but not stop the test. Caller should wrap | 47 // ASSERT failures will return, but not stop the test. Caller should wrap |
164 // calls to this function in ASSERT_NO_FATAL_FAILURE(). | 48 // calls to this function in ASSERT_NO_FATAL_FAILURE(). |
165 void ChangePosixFilePermissions(const FilePath& path, | 49 void ChangePosixFilePermissions(const FilePath& path, |
166 int mode_bits_to_set, | 50 int mode_bits_to_set, |
167 int mode_bits_to_clear) { | 51 int mode_bits_to_clear) { |
168 ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear) | 52 ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear) |
169 << "Can't set and clear the same bits."; | 53 << "Can't set and clear the same bits."; |
170 | 54 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 std::wstring ReadTextFile(const FilePath& filename) { | 121 std::wstring ReadTextFile(const FilePath& filename) { |
238 wchar_t contents[64]; | 122 wchar_t contents[64]; |
239 std::wifstream file; | 123 std::wifstream file; |
240 file.open(filename.value().c_str()); | 124 file.open(filename.value().c_str()); |
241 EXPECT_TRUE(file.is_open()); | 125 EXPECT_TRUE(file.is_open()); |
242 file.getline(contents, arraysize(contents)); | 126 file.getline(contents, arraysize(contents)); |
243 file.close(); | 127 file.close(); |
244 return std::wstring(contents); | 128 return std::wstring(contents); |
245 } | 129 } |
246 | 130 |
247 #if defined(OS_WIN) | |
248 uint64 FileTimeAsUint64(const FILETIME& ft) { | |
249 ULARGE_INTEGER u; | |
250 u.LowPart = ft.dwLowDateTime; | |
251 u.HighPart = ft.dwHighDateTime; | |
252 return u.QuadPart; | |
253 } | |
254 #endif | |
255 | |
256 TEST_F(FileUtilTest, FileAndDirectorySize) { | 131 TEST_F(FileUtilTest, FileAndDirectorySize) { |
257 // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize | 132 // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize |
258 // should return 53 bytes. | 133 // should return 53 bytes. |
259 FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt")); | 134 FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt")); |
260 CreateTextFile(file_01, L"12345678901234567890"); | 135 CreateTextFile(file_01, L"12345678901234567890"); |
261 int64 size_f1 = 0; | 136 int64 size_f1 = 0; |
262 ASSERT_TRUE(GetFileSize(file_01, &size_f1)); | 137 ASSERT_TRUE(GetFileSize(file_01, &size_f1)); |
263 EXPECT_EQ(20ll, size_f1); | 138 EXPECT_EQ(20ll, size_f1); |
264 | 139 |
265 FilePath subdir_path = temp_dir_.path().Append(FPL("Level2")); | 140 FilePath subdir_path = temp_dir_.path().Append(FPL("Level2")); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 ASSERT_TRUE(PathExists(file_b_path)); | 177 ASSERT_TRUE(PathExists(file_b_path)); |
303 ASSERT_TRUE(NormalizeFilePath(file_b_path, &normalized_file_b_path)); | 178 ASSERT_TRUE(NormalizeFilePath(file_b_path, &normalized_file_b_path)); |
304 | 179 |
305 // Beacuse this test created |dir_path|, we know it is not a link | 180 // Beacuse this test created |dir_path|, we know it is not a link |
306 // or junction. So, the real path of the directory holding file a | 181 // or junction. So, the real path of the directory holding file a |
307 // must be the parent of the path holding file b. | 182 // must be the parent of the path holding file b. |
308 ASSERT_TRUE(normalized_file_a_path.DirName() | 183 ASSERT_TRUE(normalized_file_a_path.DirName() |
309 .IsParent(normalized_file_b_path.DirName())); | 184 .IsParent(normalized_file_b_path.DirName())); |
310 } | 185 } |
311 | 186 |
312 #if defined(OS_WIN) | |
313 | |
314 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) { | |
315 // Build the following directory structure: | |
316 // | |
317 // temp_dir | |
318 // |-> base_a | |
319 // | |-> sub_a | |
320 // | |-> file.txt | |
321 // | |-> long_name___... (Very long name.) | |
322 // | |-> sub_long | |
323 // | |-> deep.txt | |
324 // |-> base_b | |
325 // |-> to_sub_a (reparse point to temp_dir\base_a\sub_a) | |
326 // |-> to_base_b (reparse point to temp_dir\base_b) | |
327 // |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long) | |
328 | |
329 FilePath base_a = temp_dir_.path().Append(FPL("base_a")); | |
330 #if defined(OS_WIN) | |
331 // TEMP can have a lower case drive letter. | |
332 string16 temp_base_a = base_a.value(); | |
333 ASSERT_FALSE(temp_base_a.empty()); | |
334 *temp_base_a.begin() = ToUpperASCII(*temp_base_a.begin()); | |
335 base_a = FilePath(temp_base_a); | |
336 #endif | |
337 ASSERT_TRUE(CreateDirectory(base_a)); | |
338 | |
339 FilePath sub_a = base_a.Append(FPL("sub_a")); | |
340 ASSERT_TRUE(CreateDirectory(sub_a)); | |
341 | |
342 FilePath file_txt = sub_a.Append(FPL("file.txt")); | |
343 CreateTextFile(file_txt, bogus_content); | |
344 | |
345 // Want a directory whose name is long enough to make the path to the file | |
346 // inside just under MAX_PATH chars. This will be used to test that when | |
347 // a junction expands to a path over MAX_PATH chars in length, | |
348 // NormalizeFilePath() fails without crashing. | |
349 FilePath sub_long_rel(FPL("sub_long")); | |
350 FilePath deep_txt(FPL("deep.txt")); | |
351 | |
352 int target_length = MAX_PATH; | |
353 target_length -= (sub_a.value().length() + 1); // +1 for the sepperator '\'. | |
354 target_length -= (sub_long_rel.Append(deep_txt).value().length() + 1); | |
355 // Without making the path a bit shorter, CreateDirectory() fails. | |
356 // the resulting path is still long enough to hit the failing case in | |
357 // NormalizePath(). | |
358 const int kCreateDirLimit = 4; | |
359 target_length -= kCreateDirLimit; | |
360 FilePath::StringType long_name_str = FPL("long_name_"); | |
361 long_name_str.resize(target_length, '_'); | |
362 | |
363 FilePath long_name = sub_a.Append(FilePath(long_name_str)); | |
364 FilePath deep_file = long_name.Append(sub_long_rel).Append(deep_txt); | |
365 ASSERT_EQ(MAX_PATH - kCreateDirLimit, deep_file.value().length()); | |
366 | |
367 FilePath sub_long = deep_file.DirName(); | |
368 ASSERT_TRUE(CreateDirectory(sub_long)); | |
369 CreateTextFile(deep_file, bogus_content); | |
370 | |
371 FilePath base_b = temp_dir_.path().Append(FPL("base_b")); | |
372 ASSERT_TRUE(CreateDirectory(base_b)); | |
373 | |
374 FilePath to_sub_a = base_b.Append(FPL("to_sub_a")); | |
375 ASSERT_TRUE(CreateDirectory(to_sub_a)); | |
376 FilePath normalized_path; | |
377 { | |
378 ReparsePoint reparse_to_sub_a(to_sub_a, sub_a); | |
379 ASSERT_TRUE(reparse_to_sub_a.IsValid()); | |
380 | |
381 FilePath to_base_b = base_b.Append(FPL("to_base_b")); | |
382 ASSERT_TRUE(CreateDirectory(to_base_b)); | |
383 ReparsePoint reparse_to_base_b(to_base_b, base_b); | |
384 ASSERT_TRUE(reparse_to_base_b.IsValid()); | |
385 | |
386 FilePath to_sub_long = base_b.Append(FPL("to_sub_long")); | |
387 ASSERT_TRUE(CreateDirectory(to_sub_long)); | |
388 ReparsePoint reparse_to_sub_long(to_sub_long, sub_long); | |
389 ASSERT_TRUE(reparse_to_sub_long.IsValid()); | |
390 | |
391 // Normalize a junction free path: base_a\sub_a\file.txt . | |
392 ASSERT_TRUE(NormalizeFilePath(file_txt, &normalized_path)); | |
393 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); | |
394 | |
395 // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude | |
396 // the junction to_sub_a. | |
397 ASSERT_TRUE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), | |
398 &normalized_path)); | |
399 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); | |
400 | |
401 // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be | |
402 // normalized to exclude junctions to_base_b and to_sub_a . | |
403 ASSERT_TRUE(NormalizeFilePath(base_b.Append(FPL("to_base_b")) | |
404 .Append(FPL("to_base_b")) | |
405 .Append(FPL("to_sub_a")) | |
406 .Append(FPL("file.txt")), | |
407 &normalized_path)); | |
408 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); | |
409 | |
410 // A long enough path will cause NormalizeFilePath() to fail. Make a long | |
411 // path using to_base_b many times, and check that paths long enough to fail | |
412 // do not cause a crash. | |
413 FilePath long_path = base_b; | |
414 const int kLengthLimit = MAX_PATH + 200; | |
415 while (long_path.value().length() <= kLengthLimit) { | |
416 long_path = long_path.Append(FPL("to_base_b")); | |
417 } | |
418 long_path = long_path.Append(FPL("to_sub_a")) | |
419 .Append(FPL("file.txt")); | |
420 | |
421 ASSERT_FALSE(NormalizeFilePath(long_path, &normalized_path)); | |
422 | |
423 // Normalizing the junction to deep.txt should fail, because the expanded | |
424 // path to deep.txt is longer than MAX_PATH. | |
425 ASSERT_FALSE(NormalizeFilePath(to_sub_long.Append(deep_txt), | |
426 &normalized_path)); | |
427 | |
428 // Delete the reparse points, and see that NormalizeFilePath() fails | |
429 // to traverse them. | |
430 } | |
431 | |
432 ASSERT_FALSE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), | |
433 &normalized_path)); | |
434 } | |
435 | |
436 TEST_F(FileUtilTest, DevicePathToDriveLetter) { | |
437 // Get a drive letter. | |
438 std::wstring real_drive_letter = temp_dir_.path().value().substr(0, 2); | |
439 StringToUpperASCII(&real_drive_letter); | |
440 if (!isalpha(real_drive_letter[0]) || ':' != real_drive_letter[1]) { | |
441 LOG(ERROR) << "Can't get a drive letter to test with."; | |
442 return; | |
443 } | |
444 | |
445 // Get the NT style path to that drive. | |
446 wchar_t device_path[MAX_PATH] = {'\0'}; | |
447 ASSERT_TRUE( | |
448 ::QueryDosDevice(real_drive_letter.c_str(), device_path, MAX_PATH)); | |
449 FilePath actual_device_path(device_path); | |
450 FilePath win32_path; | |
451 | |
452 // Run DevicePathToDriveLetterPath() on the NT style path we got from | |
453 // QueryDosDevice(). Expect the drive letter we started with. | |
454 ASSERT_TRUE(DevicePathToDriveLetterPath(actual_device_path, &win32_path)); | |
455 ASSERT_EQ(real_drive_letter, win32_path.value()); | |
456 | |
457 // Add some directories to the path. Expect those extra path componenets | |
458 // to be preserved. | |
459 FilePath kRelativePath(FPL("dir1\\dir2\\file.txt")); | |
460 ASSERT_TRUE(DevicePathToDriveLetterPath( | |
461 actual_device_path.Append(kRelativePath), | |
462 &win32_path)); | |
463 EXPECT_EQ(FilePath(real_drive_letter + L"\\").Append(kRelativePath).value(), | |
464 win32_path.value()); | |
465 | |
466 // Deform the real path so that it is invalid by removing the last four | |
467 // characters. The way windows names devices that are hard disks | |
468 // (\Device\HardDiskVolume${NUMBER}) guarantees that the string is longer | |
469 // than three characters. The only way the truncated string could be a | |
470 // real drive is if more than 10^3 disks are mounted: | |
471 // \Device\HardDiskVolume10000 would be truncated to \Device\HardDiskVolume1 | |
472 // Check that DevicePathToDriveLetterPath fails. | |
473 int path_length = actual_device_path.value().length(); | |
474 int new_length = path_length - 4; | |
475 ASSERT_LT(0, new_length); | |
476 FilePath prefix_of_real_device_path( | |
477 actual_device_path.value().substr(0, new_length)); | |
478 ASSERT_FALSE(DevicePathToDriveLetterPath(prefix_of_real_device_path, | |
479 &win32_path)); | |
480 | |
481 ASSERT_FALSE(DevicePathToDriveLetterPath( | |
482 prefix_of_real_device_path.Append(kRelativePath), | |
483 &win32_path)); | |
484 | |
485 // Deform the real path so that it is invalid by adding some characters. For | |
486 // example, if C: maps to \Device\HardDiskVolume8, then we simulate a | |
487 // request for the drive letter whose native path is | |
488 // \Device\HardDiskVolume812345 . We assume such a device does not exist, | |
489 // because drives are numbered in order and mounting 112345 hard disks will | |
490 // never happen. | |
491 const FilePath::StringType kExtraChars = FPL("12345"); | |
492 | |
493 FilePath real_device_path_plus_numbers( | |
494 actual_device_path.value() + kExtraChars); | |
495 | |
496 ASSERT_FALSE(DevicePathToDriveLetterPath( | |
497 real_device_path_plus_numbers, | |
498 &win32_path)); | |
499 | |
500 ASSERT_FALSE(DevicePathToDriveLetterPath( | |
501 real_device_path_plus_numbers.Append(kRelativePath), | |
502 &win32_path)); | |
503 } | |
504 | |
505 TEST_F(FileUtilTest, CreateTemporaryFileInDirLongPathTest) { | |
506 // Test that CreateTemporaryFileInDir() creates a path and returns a long path | |
507 // if it is available. This test requires that: | |
508 // - the filesystem at |temp_dir_| supports long filenames. | |
509 // - the account has FILE_LIST_DIRECTORY permission for all ancestor | |
510 // directories of |temp_dir_|. | |
511 const FilePath::CharType kLongDirName[] = FPL("A long path"); | |
512 const FilePath::CharType kTestSubDirName[] = FPL("test"); | |
513 FilePath long_test_dir = temp_dir_.path().Append(kLongDirName); | |
514 ASSERT_TRUE(CreateDirectory(long_test_dir)); | |
515 | |
516 // kLongDirName is not a 8.3 component. So GetShortName() should give us a | |
517 // different short name. | |
518 WCHAR path_buffer[MAX_PATH]; | |
519 DWORD path_buffer_length = GetShortPathName(long_test_dir.value().c_str(), | |
520 path_buffer, MAX_PATH); | |
521 ASSERT_LT(path_buffer_length, DWORD(MAX_PATH)); | |
522 ASSERT_NE(DWORD(0), path_buffer_length); | |
523 FilePath short_test_dir(path_buffer); | |
524 ASSERT_STRNE(kLongDirName, short_test_dir.BaseName().value().c_str()); | |
525 | |
526 FilePath temp_file; | |
527 ASSERT_TRUE(CreateTemporaryFileInDir(short_test_dir, &temp_file)); | |
528 EXPECT_STREQ(kLongDirName, temp_file.DirName().BaseName().value().c_str()); | |
529 EXPECT_TRUE(PathExists(temp_file)); | |
530 | |
531 // Create a subdirectory of |long_test_dir| and make |long_test_dir| | |
532 // unreadable. We should still be able to create a temp file in the | |
533 // subdirectory, but we won't be able to determine the long path for it. This | |
534 // mimics the environment that some users run where their user profiles reside | |
535 // in a location where the don't have full access to the higher level | |
536 // directories. (Note that this assumption is true for NTFS, but not for some | |
537 // network file systems. E.g. AFS). | |
538 FilePath access_test_dir = long_test_dir.Append(kTestSubDirName); | |
539 ASSERT_TRUE(CreateDirectory(access_test_dir)); | |
540 FilePermissionRestorer long_test_dir_restorer(long_test_dir); | |
541 ASSERT_TRUE(MakeFileUnreadable(long_test_dir)); | |
542 | |
543 // Use the short form of the directory to create a temporary filename. | |
544 ASSERT_TRUE(CreateTemporaryFileInDir( | |
545 short_test_dir.Append(kTestSubDirName), &temp_file)); | |
546 EXPECT_TRUE(PathExists(temp_file)); | |
547 EXPECT_TRUE(short_test_dir.IsParent(temp_file.DirName())); | |
548 | |
549 // Check that the long path can't be determined for |temp_file|. | |
550 path_buffer_length = GetLongPathName(temp_file.value().c_str(), | |
551 path_buffer, MAX_PATH); | |
552 EXPECT_EQ(DWORD(0), path_buffer_length); | |
553 } | |
554 | |
555 #endif // defined(OS_WIN) | |
556 | |
557 #if defined(OS_POSIX) | 187 #if defined(OS_POSIX) |
558 | 188 |
559 TEST_F(FileUtilTest, CreateAndReadSymlinks) { | 189 TEST_F(FileUtilTest, CreateAndReadSymlinks) { |
560 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); | 190 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); |
561 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); | 191 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); |
562 CreateTextFile(link_to, bogus_content); | 192 CreateTextFile(link_to, bogus_content); |
563 | 193 |
564 ASSERT_TRUE(CreateSymbolicLink(link_to, link_from)) | 194 ASSERT_TRUE(CreateSymbolicLink(link_to, link_from)) |
565 << "Failed to create file symlink."; | 195 << "Failed to create file symlink."; |
566 | 196 |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 EXPECT_TRUE(c2.HasFile(file_name)); | 469 EXPECT_TRUE(c2.HasFile(file_name)); |
840 EXPECT_EQ(1, c2.size()); | 470 EXPECT_EQ(1, c2.size()); |
841 | 471 |
842 // Delete the file. | 472 // Delete the file. |
843 EXPECT_TRUE(DeleteFile(subdir_path, true)); | 473 EXPECT_TRUE(DeleteFile(subdir_path, true)); |
844 EXPECT_FALSE(PathExists(subdir_path)); | 474 EXPECT_FALSE(PathExists(subdir_path)); |
845 } | 475 } |
846 | 476 |
847 #endif // defined(OS_POSIX) | 477 #endif // defined(OS_POSIX) |
848 | 478 |
849 #if defined(OS_WIN) | |
850 // Tests that the Delete function works for wild cards, especially | |
851 // with the recursion flag. Also coincidentally tests PathExists. | |
852 // TODO(erikkay): see if anyone's actually using this feature of the API | |
853 TEST_F(FileUtilTest, DeleteWildCard) { | |
854 // Create a file and a directory | |
855 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteWildCard.txt")); | |
856 CreateTextFile(file_name, bogus_content); | |
857 ASSERT_TRUE(PathExists(file_name)); | |
858 | |
859 FilePath subdir_path = temp_dir_.path().Append(FPL("DeleteWildCardDir")); | |
860 CreateDirectory(subdir_path); | |
861 ASSERT_TRUE(PathExists(subdir_path)); | |
862 | |
863 // Create the wildcard path | |
864 FilePath directory_contents = temp_dir_.path(); | |
865 directory_contents = directory_contents.Append(FPL("*")); | |
866 | |
867 // Delete non-recursively and check that only the file is deleted | |
868 EXPECT_TRUE(DeleteFile(directory_contents, false)); | |
869 EXPECT_FALSE(PathExists(file_name)); | |
870 EXPECT_TRUE(PathExists(subdir_path)); | |
871 | |
872 // Delete recursively and make sure all contents are deleted | |
873 EXPECT_TRUE(DeleteFile(directory_contents, true)); | |
874 EXPECT_FALSE(PathExists(file_name)); | |
875 EXPECT_FALSE(PathExists(subdir_path)); | |
876 } | |
877 | |
878 // TODO(erikkay): see if anyone's actually using this feature of the API | |
879 TEST_F(FileUtilTest, DeleteNonExistantWildCard) { | |
880 // Create a file and a directory | |
881 FilePath subdir_path = | |
882 temp_dir_.path().Append(FPL("DeleteNonExistantWildCard")); | |
883 CreateDirectory(subdir_path); | |
884 ASSERT_TRUE(PathExists(subdir_path)); | |
885 | |
886 // Create the wildcard path | |
887 FilePath directory_contents = subdir_path; | |
888 directory_contents = directory_contents.Append(FPL("*")); | |
889 | |
890 // Delete non-recursively and check nothing got deleted | |
891 EXPECT_TRUE(DeleteFile(directory_contents, false)); | |
892 EXPECT_TRUE(PathExists(subdir_path)); | |
893 | |
894 // Delete recursively and check nothing got deleted | |
895 EXPECT_TRUE(DeleteFile(directory_contents, true)); | |
896 EXPECT_TRUE(PathExists(subdir_path)); | |
897 } | |
898 #endif | |
899 | |
900 // Tests non-recursive Delete() for a directory. | 479 // Tests non-recursive Delete() for a directory. |
901 TEST_F(FileUtilTest, DeleteDirNonRecursive) { | 480 TEST_F(FileUtilTest, DeleteDirNonRecursive) { |
902 // Create a subdirectory and put a file and two directories inside. | 481 // Create a subdirectory and put a file and two directories inside. |
903 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive")); | 482 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive")); |
904 CreateDirectory(test_subdir); | 483 CreateDirectory(test_subdir); |
905 ASSERT_TRUE(PathExists(test_subdir)); | 484 ASSERT_TRUE(PathExists(test_subdir)); |
906 | 485 |
907 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); | 486 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); |
908 CreateTextFile(file_name, bogus_content); | 487 CreateTextFile(file_name, bogus_content); |
909 ASSERT_TRUE(PathExists(file_name)); | 488 ASSERT_TRUE(PathExists(file_name)); |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); | 942 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); |
1364 ASSERT_TRUE(PathExists(file_name_from)); | 943 ASSERT_TRUE(PathExists(file_name_from)); |
1365 | 944 |
1366 // Copy the directory recursively. | 945 // Copy the directory recursively. |
1367 FilePath dir_name_to = | 946 FilePath dir_name_to = |
1368 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); | 947 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); |
1369 FilePath file_name_to = | 948 FilePath file_name_to = |
1370 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); | 949 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); |
1371 | 950 |
1372 // Create from path with trailing separators. | 951 // Create from path with trailing separators. |
1373 #if defined(OS_WIN) | 952 #if defined (OS_POSIX) |
1374 FilePath from_path = | |
1375 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir\\\\\\")); | |
1376 #elif defined (OS_POSIX) | |
1377 FilePath from_path = | 953 FilePath from_path = |
1378 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///")); | 954 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///")); |
1379 #endif | 955 #endif |
1380 | 956 |
1381 EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true)); | 957 EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true)); |
1382 | 958 |
1383 // Check everything has been copied. | 959 // Check everything has been copied. |
1384 EXPECT_TRUE(PathExists(dir_name_from)); | 960 EXPECT_TRUE(PathExists(dir_name_from)); |
1385 EXPECT_TRUE(PathExists(file_name_from)); | 961 EXPECT_TRUE(PathExists(file_name_from)); |
1386 EXPECT_TRUE(PathExists(dir_name_to)); | 962 EXPECT_TRUE(PathExists(dir_name_to)); |
1387 EXPECT_TRUE(PathExists(file_name_to)); | 963 EXPECT_TRUE(PathExists(file_name_to)); |
1388 } | 964 } |
1389 | 965 |
1390 // Sets the source file to read-only. | 966 // Sets the source file to read-only. |
1391 void SetReadOnly(const FilePath& path, bool read_only) { | 967 void SetReadOnly(const FilePath& path, bool read_only) { |
1392 #if defined(OS_WIN) | |
1393 // On Windows, it involves setting/removing the 'readonly' bit. | |
1394 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
1395 ASSERT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
1396 ASSERT_TRUE(SetFileAttributes( | |
1397 path.value().c_str(), | |
1398 read_only ? (attrs | FILE_ATTRIBUTE_READONLY) : | |
1399 (attrs & ~FILE_ATTRIBUTE_READONLY))); | |
1400 | |
1401 DWORD expected = read_only ? | |
1402 ((attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)) | | |
1403 FILE_ATTRIBUTE_READONLY) : | |
1404 (attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)); | |
1405 | |
1406 // Ignore FILE_ATTRIBUTE_NOT_CONTENT_INDEXED if present. | |
1407 attrs = GetFileAttributes(path.value().c_str()) & | |
1408 ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; | |
1409 ASSERT_EQ(expected, attrs); | |
1410 #else | |
1411 // On all other platforms, it involves removing/setting the write bit. | |
1412 mode_t mode = read_only ? S_IRUSR : (S_IRUSR | S_IWUSR); | 968 mode_t mode = read_only ? S_IRUSR : (S_IRUSR | S_IWUSR); |
1413 EXPECT_TRUE(SetPosixFilePermissions( | 969 EXPECT_TRUE(SetPosixFilePermissions( |
1414 path, DirectoryExists(path) ? (mode | S_IXUSR) : mode)); | 970 path, DirectoryExists(path) ? (mode | S_IXUSR) : mode)); |
1415 #endif | |
1416 } | 971 } |
1417 | 972 |
1418 bool IsReadOnly(const FilePath& path) { | 973 bool IsReadOnly(const FilePath& path) { |
1419 #if defined(OS_WIN) | |
1420 DWORD attrs = GetFileAttributes(path.value().c_str()); | |
1421 EXPECT_NE(INVALID_FILE_ATTRIBUTES, attrs); | |
1422 return attrs & FILE_ATTRIBUTE_READONLY; | |
1423 #else | |
1424 int mode = 0; | 974 int mode = 0; |
1425 EXPECT_TRUE(GetPosixFilePermissions(path, &mode)); | 975 EXPECT_TRUE(GetPosixFilePermissions(path, &mode)); |
1426 return !(mode & S_IWUSR); | 976 return !(mode & S_IWUSR); |
1427 #endif | |
1428 } | 977 } |
1429 | 978 |
1430 TEST_F(FileUtilTest, CopyDirectoryACL) { | 979 TEST_F(FileUtilTest, CopyDirectoryACL) { |
1431 // Create source directories. | 980 // Create source directories. |
1432 FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src")); | 981 FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src")); |
1433 FilePath src_subdir = src.Append(FILE_PATH_LITERAL("subdir")); | 982 FilePath src_subdir = src.Append(FILE_PATH_LITERAL("subdir")); |
1434 CreateDirectory(src_subdir); | 983 CreateDirectory(src_subdir); |
1435 ASSERT_TRUE(PathExists(src_subdir)); | 984 ASSERT_TRUE(PathExists(src_subdir)); |
1436 | 985 |
1437 // Create a file under the directory. | 986 // Create a file under the directory. |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 EXPECT_FALSE(TextContentsEqual(original_file, shortened_file)); | 1153 EXPECT_FALSE(TextContentsEqual(original_file, shortened_file)); |
1605 EXPECT_FALSE(TextContentsEqual(original_file, different_file)); | 1154 EXPECT_FALSE(TextContentsEqual(original_file, different_file)); |
1606 EXPECT_FALSE(TextContentsEqual(original_file, different_first_file)); | 1155 EXPECT_FALSE(TextContentsEqual(original_file, different_first_file)); |
1607 EXPECT_FALSE(TextContentsEqual(original_file, different_last_file)); | 1156 EXPECT_FALSE(TextContentsEqual(original_file, different_last_file)); |
1608 EXPECT_FALSE(TextContentsEqual(first1_file, first2_file)); | 1157 EXPECT_FALSE(TextContentsEqual(first1_file, first2_file)); |
1609 EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file)); | 1158 EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file)); |
1610 EXPECT_FALSE(TextContentsEqual(original_file, empty1_file)); | 1159 EXPECT_FALSE(TextContentsEqual(original_file, empty1_file)); |
1611 EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file)); | 1160 EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file)); |
1612 } | 1161 } |
1613 | 1162 |
1614 // We don't need equivalent functionality outside of Windows. | |
1615 #if defined(OS_WIN) | |
1616 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) { | |
1617 // Create a directory | |
1618 FilePath dir_name_from = | |
1619 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir")); | |
1620 CreateDirectory(dir_name_from); | |
1621 ASSERT_TRUE(PathExists(dir_name_from)); | |
1622 | |
1623 // Create a file under the directory | |
1624 FilePath file_name_from = | |
1625 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); | |
1626 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); | |
1627 ASSERT_TRUE(PathExists(file_name_from)); | |
1628 | |
1629 // Move the directory by using CopyAndDeleteDirectory | |
1630 FilePath dir_name_to = temp_dir_.path().Append( | |
1631 FILE_PATH_LITERAL("CopyAndDelete_To_Subdir")); | |
1632 FilePath file_name_to = | |
1633 dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); | |
1634 | |
1635 ASSERT_FALSE(PathExists(dir_name_to)); | |
1636 | |
1637 EXPECT_TRUE(internal::CopyAndDeleteDirectory(dir_name_from, | |
1638 dir_name_to)); | |
1639 | |
1640 // Check everything has been moved. | |
1641 EXPECT_FALSE(PathExists(dir_name_from)); | |
1642 EXPECT_FALSE(PathExists(file_name_from)); | |
1643 EXPECT_TRUE(PathExists(dir_name_to)); | |
1644 EXPECT_TRUE(PathExists(file_name_to)); | |
1645 } | |
1646 | |
1647 TEST_F(FileUtilTest, GetTempDirTest) { | |
1648 static const TCHAR* kTmpKey = _T("TMP"); | |
1649 static const TCHAR* kTmpValues[] = { | |
1650 _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\") | |
1651 }; | |
1652 // Save the original $TMP. | |
1653 size_t original_tmp_size; | |
1654 TCHAR* original_tmp; | |
1655 ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey)); | |
1656 // original_tmp may be NULL. | |
1657 | |
1658 for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) { | |
1659 FilePath path; | |
1660 ::_tputenv_s(kTmpKey, kTmpValues[i]); | |
1661 GetTempDir(&path); | |
1662 EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] << | |
1663 " result=" << path.value(); | |
1664 } | |
1665 | |
1666 // Restore the original $TMP. | |
1667 if (original_tmp) { | |
1668 ::_tputenv_s(kTmpKey, original_tmp); | |
1669 free(original_tmp); | |
1670 } else { | |
1671 ::_tputenv_s(kTmpKey, _T("")); | |
1672 } | |
1673 } | |
1674 #endif // OS_WIN | |
1675 | |
1676 TEST_F(FileUtilTest, CreateTemporaryFileTest) { | 1163 TEST_F(FileUtilTest, CreateTemporaryFileTest) { |
1677 FilePath temp_files[3]; | 1164 FilePath temp_files[3]; |
1678 for (int i = 0; i < 3; i++) { | 1165 for (int i = 0; i < 3; i++) { |
1679 ASSERT_TRUE(CreateTemporaryFile(&(temp_files[i]))); | 1166 ASSERT_TRUE(CreateTemporaryFile(&(temp_files[i]))); |
1680 EXPECT_TRUE(PathExists(temp_files[i])); | 1167 EXPECT_TRUE(PathExists(temp_files[i])); |
1681 EXPECT_FALSE(DirectoryExists(temp_files[i])); | 1168 EXPECT_FALSE(DirectoryExists(temp_files[i])); |
1682 } | 1169 } |
1683 for (int i = 0; i < 3; i++) | 1170 for (int i = 0; i < 3; i++) |
1684 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]); | 1171 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]); |
1685 for (int i = 0; i < 3; i++) | 1172 for (int i = 0; i < 3; i++) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 // So here we just test that it returns something "reasonable". | 1245 // So here we just test that it returns something "reasonable". |
1759 FilePath home = GetHomeDir(); | 1246 FilePath home = GetHomeDir(); |
1760 ASSERT_FALSE(home.empty()); | 1247 ASSERT_FALSE(home.empty()); |
1761 ASSERT_TRUE(home.IsAbsolute()); | 1248 ASSERT_TRUE(home.IsAbsolute()); |
1762 #endif | 1249 #endif |
1763 } | 1250 } |
1764 | 1251 |
1765 TEST_F(FileUtilTest, CreateDirectoryTest) { | 1252 TEST_F(FileUtilTest, CreateDirectoryTest) { |
1766 FilePath test_root = | 1253 FilePath test_root = |
1767 temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test")); | 1254 temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test")); |
1768 #if defined(OS_WIN) | 1255 #if defined(OS_POSIX) |
1769 FilePath test_path = | |
1770 test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\")); | |
1771 #elif defined(OS_POSIX) | |
1772 FilePath test_path = | 1256 FilePath test_path = |
1773 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/")); | 1257 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/")); |
1774 #endif | 1258 #endif |
1775 | 1259 |
1776 EXPECT_FALSE(PathExists(test_path)); | 1260 EXPECT_FALSE(PathExists(test_path)); |
1777 EXPECT_TRUE(CreateDirectory(test_path)); | 1261 EXPECT_TRUE(CreateDirectory(test_path)); |
1778 EXPECT_TRUE(PathExists(test_path)); | 1262 EXPECT_TRUE(PathExists(test_path)); |
1779 // CreateDirectory returns true if the DirectoryExists returns true. | 1263 // CreateDirectory returns true if the DirectoryExists returns true. |
1780 EXPECT_TRUE(CreateDirectory(test_path)); | 1264 EXPECT_TRUE(CreateDirectory(test_path)); |
1781 | 1265 |
(...skipping 16 matching lines...) Expand all Loading... |
1798 while (top_level != top_level.DirName()) { | 1282 while (top_level != top_level.DirName()) { |
1799 top_level = top_level.DirName(); | 1283 top_level = top_level.DirName(); |
1800 } | 1284 } |
1801 ASSERT_TRUE(DirectoryExists(top_level)); | 1285 ASSERT_TRUE(DirectoryExists(top_level)); |
1802 | 1286 |
1803 // Given these assumptions hold, it should be safe to | 1287 // Given these assumptions hold, it should be safe to |
1804 // test that "creating" these directories succeeds. | 1288 // test that "creating" these directories succeeds. |
1805 EXPECT_TRUE(CreateDirectory( | 1289 EXPECT_TRUE(CreateDirectory( |
1806 FilePath(FilePath::kCurrentDirectory))); | 1290 FilePath(FilePath::kCurrentDirectory))); |
1807 EXPECT_TRUE(CreateDirectory(top_level)); | 1291 EXPECT_TRUE(CreateDirectory(top_level)); |
1808 | |
1809 #if defined(OS_WIN) | |
1810 FilePath invalid_drive(FILE_PATH_LITERAL("o:\\")); | |
1811 FilePath invalid_path = | |
1812 invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir")); | |
1813 if (!PathExists(invalid_drive)) { | |
1814 EXPECT_FALSE(CreateDirectory(invalid_path)); | |
1815 } | |
1816 #endif | |
1817 } | 1292 } |
1818 | 1293 |
1819 TEST_F(FileUtilTest, DetectDirectoryTest) { | 1294 TEST_F(FileUtilTest, DetectDirectoryTest) { |
1820 // Check a directory | 1295 // Check a directory |
1821 FilePath test_root = | 1296 FilePath test_root = |
1822 temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test")); | 1297 temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test")); |
1823 EXPECT_FALSE(PathExists(test_root)); | 1298 EXPECT_FALSE(PathExists(test_root)); |
1824 EXPECT_TRUE(CreateDirectory(test_root)); | 1299 EXPECT_TRUE(CreateDirectory(test_root)); |
1825 EXPECT_TRUE(PathExists(test_root)); | 1300 EXPECT_TRUE(PathExists(test_root)); |
1826 EXPECT_TRUE(DirectoryExists(test_root)); | 1301 EXPECT_TRUE(DirectoryExists(test_root)); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1928 // Enumerate with a pattern. | 1403 // Enumerate with a pattern. |
1929 FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*")); | 1404 FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*")); |
1930 FindResultCollector c5(&f5); | 1405 FindResultCollector c5(&f5); |
1931 EXPECT_TRUE(c5.HasFile(dir1)); | 1406 EXPECT_TRUE(c5.HasFile(dir1)); |
1932 EXPECT_TRUE(c5.HasFile(dir2)); | 1407 EXPECT_TRUE(c5.HasFile(dir2)); |
1933 EXPECT_TRUE(c5.HasFile(dir2file)); | 1408 EXPECT_TRUE(c5.HasFile(dir2file)); |
1934 EXPECT_TRUE(c5.HasFile(dir2inner)); | 1409 EXPECT_TRUE(c5.HasFile(dir2inner)); |
1935 EXPECT_TRUE(c5.HasFile(dir2innerfile)); | 1410 EXPECT_TRUE(c5.HasFile(dir2innerfile)); |
1936 EXPECT_EQ(5, c5.size()); | 1411 EXPECT_EQ(5, c5.size()); |
1937 | 1412 |
1938 #if defined(OS_WIN) | |
1939 { | |
1940 // Make dir1 point to dir2. | |
1941 ReparsePoint reparse_point(dir1, dir2); | |
1942 EXPECT_TRUE(reparse_point.IsValid()); | |
1943 | |
1944 if ((win::GetVersion() >= win::VERSION_VISTA)) { | |
1945 // There can be a delay for the enumeration code to see the change on | |
1946 // the file system so skip this test for XP. | |
1947 // Enumerate the reparse point. | |
1948 FileEnumerator f6(dir1, true, FILES_AND_DIRECTORIES); | |
1949 FindResultCollector c6(&f6); | |
1950 FilePath inner2 = dir1.Append(FPL("inner")); | |
1951 EXPECT_TRUE(c6.HasFile(inner2)); | |
1952 EXPECT_TRUE(c6.HasFile(inner2.Append(FPL("innerfile.txt")))); | |
1953 EXPECT_TRUE(c6.HasFile(dir1.Append(FPL("dir2file.txt")))); | |
1954 EXPECT_EQ(3, c6.size()); | |
1955 } | |
1956 | |
1957 // No changes for non recursive operation. | |
1958 FileEnumerator f7(temp_dir_.path(), false, FILES_AND_DIRECTORIES); | |
1959 FindResultCollector c7(&f7); | |
1960 EXPECT_TRUE(c7.HasFile(dir2)); | |
1961 EXPECT_TRUE(c7.HasFile(dir2)); | |
1962 EXPECT_TRUE(c7.HasFile(file1)); | |
1963 EXPECT_TRUE(c7.HasFile(file2_abs)); | |
1964 EXPECT_EQ(4, c7.size()); | |
1965 | |
1966 // Should not enumerate inside dir1 when using recursion. | |
1967 FileEnumerator f8(temp_dir_.path(), true, FILES_AND_DIRECTORIES); | |
1968 FindResultCollector c8(&f8); | |
1969 EXPECT_TRUE(c8.HasFile(dir1)); | |
1970 EXPECT_TRUE(c8.HasFile(dir2)); | |
1971 EXPECT_TRUE(c8.HasFile(file1)); | |
1972 EXPECT_TRUE(c8.HasFile(file2_abs)); | |
1973 EXPECT_TRUE(c8.HasFile(dir2file)); | |
1974 EXPECT_TRUE(c8.HasFile(dir2inner)); | |
1975 EXPECT_TRUE(c8.HasFile(dir2innerfile)); | |
1976 EXPECT_EQ(7, c8.size()); | |
1977 } | |
1978 #endif | |
1979 | |
1980 // Make sure the destructor closes the find handle while in the middle of a | 1413 // Make sure the destructor closes the find handle while in the middle of a |
1981 // query to allow TearDown to delete the directory. | 1414 // query to allow TearDown to delete the directory. |
1982 FileEnumerator f9(temp_dir_.path(), true, FILES_AND_DIRECTORIES); | 1415 FileEnumerator f9(temp_dir_.path(), true, FILES_AND_DIRECTORIES); |
1983 EXPECT_FALSE(f9.Next().value().empty()); // Should have found something | 1416 EXPECT_FALSE(f9.Next().value().empty()); // Should have found something |
1984 // (we don't care what). | 1417 // (we don't care what). |
1985 } | 1418 } |
1986 | 1419 |
1987 TEST_F(FileUtilTest, AppendToFile) { | 1420 TEST_F(FileUtilTest, AppendToFile) { |
1988 FilePath data_dir = | 1421 FilePath data_dir = |
1989 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); | 1422 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2527 // Trying to close it should crash. This is important for security. | 1960 // Trying to close it should crash. This is important for security. |
2528 EXPECT_DEATH(CloseWithScopedFD(fds[1]), ""); | 1961 EXPECT_DEATH(CloseWithScopedFD(fds[1]), ""); |
2529 #endif | 1962 #endif |
2530 } | 1963 } |
2531 | 1964 |
2532 #endif // defined(OS_POSIX) | 1965 #endif // defined(OS_POSIX) |
2533 | 1966 |
2534 } // namespace | 1967 } // namespace |
2535 | 1968 |
2536 } // namespace base | 1969 } // namespace base |
OLD | NEW |