Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: base/file_util_unittest.cc

Issue 10914109: Refactoring and tests for the highly undertested file_util::CreateOrUpdateShortcutLink() method. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: better path matching Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #include <objbase.h>
9 #include <shellapi.h> 10 #include <shellapi.h>
10 #include <shlobj.h> 11 #include <shlobj.h>
11 #include <tchar.h> 12 #include <tchar.h>
12 #include <winioctl.h> 13 #include <winioctl.h>
13 #endif 14 #endif
14 15
15 #include <algorithm> 16 #include <algorithm>
16 #include <fstream> 17 #include <fstream>
17 #include <set> 18 #include <set>
18 19
19 #include "base/base_paths.h" 20 #include "base/base_paths.h"
20 #include "base/file_path.h" 21 #include "base/file_path.h"
21 #include "base/file_util.h" 22 #include "base/file_util.h"
22 #include "base/path_service.h" 23 #include "base/path_service.h"
23 #include "base/scoped_temp_dir.h" 24 #include "base/scoped_temp_dir.h"
25 #include "base/memory/scoped_ptr.h"
26 #include "base/test/test_file_util.h"
24 #include "base/threading/platform_thread.h" 27 #include "base/threading/platform_thread.h"
25 #include "base/utf_string_conversions.h" 28 #include "base/utf_string_conversions.h"
26 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
27 #include "testing/platform_test.h" 30 #include "testing/platform_test.h"
28 31
29 #if defined(OS_WIN) 32 #if defined(OS_WIN)
30 #include "base/win/scoped_handle.h" 33 #include "base/win/scoped_handle.h"
31 #endif 34 #endif
32 35
33 // This macro helps avoid wrapped lines in the test structs. 36 // This macro helps avoid wrapped lines in the test structs.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 mode &= ~mode_bits_to_clear; 129 mode &= ~mode_bits_to_clear;
127 ASSERT_TRUE(file_util::SetPosixFilePermissions(path, mode)); 130 ASSERT_TRUE(file_util::SetPosixFilePermissions(path, mode));
128 } 131 }
129 #endif // defined(OS_POSIX) 132 #endif // defined(OS_POSIX)
130 133
131 const wchar_t bogus_content[] = L"I'm cannon fodder."; 134 const wchar_t bogus_content[] = L"I'm cannon fodder.";
132 135
133 const int FILES_AND_DIRECTORIES = 136 const int FILES_AND_DIRECTORIES =
134 file_util::FileEnumerator::FILES | file_util::FileEnumerator::DIRECTORIES; 137 file_util::FileEnumerator::FILES | file_util::FileEnumerator::DIRECTORIES;
135 138
136 // file_util winds up using autoreleased objects on the Mac, so this needs
137 // to be a PlatformTest
138 class FileUtilTest : public PlatformTest {
139 protected:
140 virtual void SetUp() OVERRIDE {
141 PlatformTest::SetUp();
142 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
143 }
144
145 ScopedTempDir temp_dir_;
146 };
147
148 // Collects all the results from the given file enumerator, and provides an 139 // Collects all the results from the given file enumerator, and provides an
149 // interface to query whether a given file is present. 140 // interface to query whether a given file is present.
150 class FindResultCollector { 141 class FindResultCollector {
151 public: 142 public:
152 explicit FindResultCollector(file_util::FileEnumerator& enumerator) { 143 explicit FindResultCollector(file_util::FileEnumerator& enumerator) {
153 FilePath cur_file; 144 FilePath cur_file;
154 while (!(cur_file = enumerator.Next()).value().empty()) { 145 while (!(cur_file = enumerator.Next()).value().empty()) {
155 FilePath::StringType path = cur_file.value(); 146 FilePath::StringType path = cur_file.value();
156 // The file should not be returned twice. 147 // The file should not be returned twice.
157 EXPECT_TRUE(files_.end() == files_.find(path)) 148 EXPECT_TRUE(files_.end() == files_.find(path))
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 {L"/foo/bar/", L"/foo/bar"}, 291 {L"/foo/bar/", L"/foo/bar"},
301 {L"/foo/bar//", L"/foo/bar"}, 292 {L"/foo/bar//", L"/foo/bar"},
302 {L"/foo/bar", L"/foo"}, 293 {L"/foo/bar", L"/foo"},
303 {L"/foo/bar./", L"/foo/bar."}, 294 {L"/foo/bar./", L"/foo/bar."},
304 {L"/", L"/"}, 295 {L"/", L"/"},
305 {L".", L"."}, 296 {L".", L"."},
306 {L"..", L"."}, // yes, ".." technically lives in "." 297 {L"..", L"."}, // yes, ".." technically lives in "."
307 #endif 298 #endif
308 }; 299 };
309 300
301 // file_util winds up using autoreleased objects on the Mac, so this needs
302 // to be a PlatformTest
303 class FileUtilTest : public PlatformTest {
304 protected:
305 virtual void SetUp() OVERRIDE {
306 PlatformTest::SetUp();
307 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
308 ASSERT_TRUE(temp_dir_2_.CreateUniqueTempDir());
309 }
310
311 ScopedTempDir temp_dir_;
312 ScopedTempDir temp_dir_2_;
313 };
314
310 TEST_F(FileUtilTest, CountFilesCreatedAfter) { 315 TEST_F(FileUtilTest, CountFilesCreatedAfter) {
311 FilePath file_name = 316 FilePath file_name =
312 temp_dir_.path().Append(FILE_PATH_LITERAL("f.txt")); 317 temp_dir_.path().Append(FILE_PATH_LITERAL("f.txt"));
313 CreateTextFile(file_name, L"test"); 318 CreateTextFile(file_name, L"test");
314 319
315 base::PlatformFileInfo info; 320 base::PlatformFileInfo info;
316 file_util::GetFileInfo(file_name, &info); 321 file_util::GetFileInfo(file_name, &info);
317 base::Time file_time = info.creation_time; 322 base::Time file_time = info.creation_time;
318 323
319 base::TimeDelta two_secs = base::TimeDelta::FromSeconds(2); 324 base::TimeDelta two_secs = base::TimeDelta::FromSeconds(2);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 395
391 // Beacuse this test created |dir_path|, we know it is not a link 396 // Beacuse this test created |dir_path|, we know it is not a link
392 // or junction. So, the real path of the directory holding file a 397 // or junction. So, the real path of the directory holding file a
393 // must be the parent of the path holding file b. 398 // must be the parent of the path holding file b.
394 ASSERT_TRUE(normalized_file_a_path.DirName() 399 ASSERT_TRUE(normalized_file_a_path.DirName()
395 .IsParent(normalized_file_b_path.DirName())); 400 .IsParent(normalized_file_b_path.DirName()));
396 } 401 }
397 402
398 #if defined(OS_WIN) 403 #if defined(OS_WIN)
399 404
405 class FileUtilShortcutTest : public FileUtilTest {
406 protected:
407 virtual void SetUp() OVERRIDE {
408 FileUtilTest::SetUp();
409
410 EXPECT_EQ(S_OK, CoInitialize(NULL));
411
412 link_file_ = temp_dir_.path().Append(L"My Link.lnk");
413
414 // Shortcut 1's properties
415 {
416 file_contents_ = string16(L"This is a target.");
417 const FilePath target_file(temp_dir_.path().Append(L"Target 1.txt"));
418 CreateTextFile(target_file, file_contents_);
419
420 link_properties_.set_target(target_file.value());
421 link_properties_.set_working_dir(temp_dir_.path().value());
422 link_properties_.set_arguments(L"--magic --awesome");
423 link_properties_.set_description(L"Chrome is awesome.");
424 link_properties_.set_icon(link_properties_.target, 4);
425 link_properties_.set_app_id(L"Chrome");
426 link_properties_.set_dual_mode(false);
427 }
428
429 // Shortcut 2's properties (all different from properties of shortcut 1).
430 {
431 file_contents_2_ = string16(L"This is another target.");
432 const FilePath target_file_2(temp_dir_.path().Append(L"Target 2.txt"));
433 CreateTextFile(target_file_2, file_contents_2_);
434
435 const FilePath icon_path_2(temp_dir_.path().Append(L"icon.ico"));
436 CreateTextFile(icon_path_2, L"A fake icon");
437
438 link_properties_2_.set_target(target_file_2.value());
439 link_properties_2_.set_working_dir(temp_dir_2_.path().value());
440 link_properties_2_.set_arguments(L"--super --crazy");
441 link_properties_2_.set_description(L"The best in the west.");
442 link_properties_2_.set_icon(icon_path_2.value(), 0);
443 link_properties_2_.set_app_id(L"Chrome.UserLevelCrazySuffix");
444 link_properties_2_.set_dual_mode(true);
445 }
446 }
447
448 virtual void TearDown() OVERRIDE {
449 CoUninitialize();
450 }
451
452 // The link file to be created/updated in the shortcut tests below.
453 FilePath link_file_;
454
455 // Properties for the created shortcut.
456 string16 file_contents_;
457 file_util::ShortcutProperties link_properties_;
458
459 // Properties for the updated shortcut.
460 string16 file_contents_2_;
461 file_util::ShortcutProperties link_properties_2_;
462 };
463
464 TEST_F(FileUtilShortcutTest, CreateShortcut) {
465 file_util::ShortcutProperties only_target_properties;
466 only_target_properties.set_target(link_properties_.target);
467
468 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
469 link_file_.value().c_str(), only_target_properties,
470 file_util::SHORTCUT_CREATE_ALWAYS));
471
472 FilePath resolved_name;
473 EXPECT_TRUE(file_util::ResolveShortcut(link_file_, &resolved_name, NULL));
474 const string16 read_contents(ReadTextFile(resolved_name));
475 EXPECT_EQ(file_contents_, read_contents);
476 }
477
478 TEST_F(FileUtilShortcutTest, CreateShortcutWithOnlySomeProperties) {
479 file_util::ShortcutProperties target_and_args_properties;
480 target_and_args_properties.set_target(link_properties_.target);
481 target_and_args_properties.set_arguments(link_properties_.arguments);
482
483 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
484 link_file_.value().c_str(), target_and_args_properties,
485 file_util::SHORTCUT_CREATE_ALWAYS));
486
487 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
488 file_util::VerifyShortcut(link_file_.value(),
489 target_and_args_properties));
490 }
491
492 TEST_F(FileUtilShortcutTest, CreateShortcutVerifyProperties) {
493 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
494 link_file_.value().c_str(), link_properties_,
495 file_util::SHORTCUT_CREATE_ALWAYS));
496
497 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
498 file_util::VerifyShortcut(link_file_.value(), link_properties_));
499 }
500
501 TEST_F(FileUtilShortcutTest, UpdateShortcutVerifyProperties) {
502 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
503 link_file_.value().c_str(), link_properties_,
504 file_util::SHORTCUT_CREATE_ALWAYS));
505
506 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
507 link_file_.value().c_str(), link_properties_2_,
508 file_util::SHORTCUT_UPDATE_EXISTING));
509
510 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
511 file_util::VerifyShortcut(link_file_.value(), link_properties_2_));
512 }
513
514 TEST_F(FileUtilShortcutTest, UpdateShortcutUpdateOnlyTarget) {
515 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
516 link_file_.value().c_str(), link_properties_,
517 file_util::SHORTCUT_CREATE_ALWAYS));
518
519 file_util::ShortcutProperties update_only_target_properties;
520 update_only_target_properties.set_target(link_properties_2_.target);
521
522 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
523 link_file_.value().c_str(), update_only_target_properties,
524 file_util::SHORTCUT_UPDATE_EXISTING));
525
526 file_util::ShortcutProperties expected_properties = link_properties_;
527 expected_properties.set_target(link_properties_2_.target);
528 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
529 file_util::VerifyShortcut(link_file_.value(), expected_properties));
530 }
531
532 TEST_F(FileUtilShortcutTest, UpdateShortcutMakeDualMode) {
533 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
534 link_file_.value().c_str(), link_properties_,
535 file_util::SHORTCUT_CREATE_ALWAYS));
536
537 file_util::ShortcutProperties make_dual_mode_properties;
538 make_dual_mode_properties.set_dual_mode(true);
539
540 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
541 link_file_.value().c_str(), make_dual_mode_properties,
542 file_util::SHORTCUT_UPDATE_EXISTING));
543
544 file_util::ShortcutProperties expected_properties = link_properties_;
545 expected_properties.set_dual_mode(true);
546 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
547 file_util::VerifyShortcut(link_file_.value(), expected_properties));
548 }
549
550 TEST_F(FileUtilShortcutTest, UpdateShortcutRemoveDualMode) {
551 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
552 link_file_.value().c_str(), link_properties_2_,
553 file_util::SHORTCUT_CREATE_ALWAYS));
554
555 file_util::ShortcutProperties remove_dual_mode_properties;
556 remove_dual_mode_properties.set_dual_mode(false);
557
558 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
559 link_file_.value().c_str(), remove_dual_mode_properties,
560 file_util::SHORTCUT_UPDATE_EXISTING));
561
562 file_util::ShortcutProperties expected_properties = link_properties_2_;
563 expected_properties.set_dual_mode(false);
564 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
565 file_util::VerifyShortcut(link_file_.value(), expected_properties));
566 }
567
400 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) { 568 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) {
401 // Build the following directory structure: 569 // Build the following directory structure:
402 // 570 //
403 // temp_dir 571 // temp_dir
404 // |-> base_a 572 // |-> base_a
405 // | |-> sub_a 573 // | |-> sub_a
406 // | |-> file.txt 574 // | |-> file.txt
407 // | |-> long_name___... (Very long name.) 575 // | |-> long_name___... (Very long name.)
408 // | |-> sub_long 576 // | |-> sub_long
409 // | |-> deep.txt 577 // | |-> deep.txt
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 std::wstring contents; 1800 std::wstring contents;
1633 contents = ReadTextFile(link_file); 1801 contents = ReadTextFile(link_file);
1634 EXPECT_EQ(L"This is the target.", contents); 1802 EXPECT_EQ(L"This is the target.", contents);
1635 1803
1636 // Cleaning 1804 // Cleaning
1637 DeleteFile(target_file.value().c_str()); 1805 DeleteFile(target_file.value().c_str());
1638 DeleteFile(link_file.value().c_str()); 1806 DeleteFile(link_file.value().c_str());
1639 CoUninitialize(); 1807 CoUninitialize();
1640 } 1808 }
1641 1809
1642 TEST_F(FileUtilTest, CreateShortcutTest) {
1643 const wchar_t* file_contents = L"This is another target.";
1644 FilePath target_file = temp_dir_.path().Append(L"Target1.txt");
1645 CreateTextFile(target_file, file_contents);
1646
1647 FilePath link_file = temp_dir_.path().Append(L"Link1.lnk");
1648
1649 CoInitialize(NULL);
1650 EXPECT_TRUE(file_util::CreateOrUpdateShortcutLink(
1651 target_file.value().c_str(), link_file.value().c_str(), NULL,
1652 NULL, NULL, NULL, 0, NULL,
1653 file_util::SHORTCUT_CREATE_ALWAYS));
1654 FilePath resolved_name;
1655 EXPECT_TRUE(file_util::ResolveShortcut(link_file, &resolved_name, NULL));
1656 std::wstring read_contents = ReadTextFile(resolved_name);
1657 EXPECT_EQ(file_contents, read_contents);
1658
1659 DeleteFile(target_file.value().c_str());
1660 DeleteFile(link_file.value().c_str());
1661 CoUninitialize();
1662 }
1663
1664 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) { 1810 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) {
1665 // Create a directory 1811 // Create a directory
1666 FilePath dir_name_from = 1812 FilePath dir_name_from =
1667 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir")); 1813 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir"));
1668 file_util::CreateDirectory(dir_name_from); 1814 file_util::CreateDirectory(dir_name_from);
1669 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 1815 ASSERT_TRUE(file_util::PathExists(dir_name_from));
1670 1816
1671 // Create a file under the directory 1817 // Create a file under the directory
1672 FilePath file_name_from = 1818 FilePath file_name_from =
1673 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1819 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 file_util::VerifyPathControlledByUser( 2604 file_util::VerifyPathControlledByUser(
2459 base_dir_, text_file_, uid_, ok_gids_)); 2605 base_dir_, text_file_, uid_, ok_gids_));
2460 EXPECT_TRUE( 2606 EXPECT_TRUE(
2461 file_util::VerifyPathControlledByUser( 2607 file_util::VerifyPathControlledByUser(
2462 sub_dir_, text_file_, uid_, ok_gids_)); 2608 sub_dir_, text_file_, uid_, ok_gids_));
2463 } 2609 }
2464 2610
2465 #endif // defined(OS_POSIX) 2611 #endif // defined(OS_POSIX)
2466 2612
2467 } // namespace 2613 } // namespace
OLDNEW
« base/file_util.h ('K') | « base/file_util.h ('k') | base/file_util_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698