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

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: 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 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 target_file_2_ = temp_dir_.path().Append(L"Target 2.txt");
433 CreateTextFile(target_file_2_, file_contents_2_);
434
435 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 private:
464 // Keep these paths around for the life of this fixture as they contain
465 // strings pointed to by |link_properties_*| above.
robertshield 2012/09/06 02:37:34 nit: "strings pointed to" -> "paths referenced by"
gab 2012/09/06 04:20:02 Oops, thanks for catching this, this is actually n
466 FilePath target_file_;
467 FilePath target_file_2_;
468 FilePath icon_path_2_;
469 };
470
471 TEST_F(FileUtilShortcutTest, CreateShortcut) {
472 file_util::ShortcutProperties only_target_properties;
473 only_target_properties.set_target(link_properties_.target);
474
475 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
476 link_file_.value().c_str(), only_target_properties,
477 file_util::SHORTCUT_CREATE_ALWAYS));
478
479 FilePath resolved_name;
480 EXPECT_TRUE(file_util::ResolveShortcut(link_file_, &resolved_name, NULL));
481 const string16 read_contents(ReadTextFile(resolved_name));
482 EXPECT_EQ(file_contents_, read_contents);
483 }
484
485 TEST_F(FileUtilShortcutTest, CreateShortcutWithOnlySomeProperties) {
486 file_util::ShortcutProperties target_and_args_properties;
487 target_and_args_properties.set_target(link_properties_.target);
488 target_and_args_properties.set_arguments(link_properties_.arguments);
489
490 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
491 link_file_.value().c_str(), target_and_args_properties,
492 file_util::SHORTCUT_CREATE_ALWAYS));
493
494 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
495 file_util::VerifyShortcut(link_file_.value(),
496 target_and_args_properties));
497 }
498
499 TEST_F(FileUtilShortcutTest, CreateShortcutVerifyProperties) {
500 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
501 link_file_.value().c_str(), link_properties_,
502 file_util::SHORTCUT_CREATE_ALWAYS));
503
504 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
505 file_util::VerifyShortcut(link_file_.value(), link_properties_));
506 }
507
508 TEST_F(FileUtilShortcutTest, UpdateShortcutVerifyProperties) {
509 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
510 link_file_.value().c_str(), link_properties_,
511 file_util::SHORTCUT_CREATE_ALWAYS));
512
513 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
514 link_file_.value().c_str(), link_properties_2_,
515 file_util::SHORTCUT_UPDATE_EXISTING));
516
517 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
518 file_util::VerifyShortcut(link_file_.value(), link_properties_2_));
519 }
520
521 TEST_F(FileUtilShortcutTest, UpdateShortcutUpdateOnlyTarget) {
522 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
523 link_file_.value().c_str(), link_properties_,
524 file_util::SHORTCUT_CREATE_ALWAYS));
525
526 file_util::ShortcutProperties update_only_target_properties;
527 update_only_target_properties.set_target(link_properties_2_.target);
528
529 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
530 link_file_.value().c_str(), update_only_target_properties,
531 file_util::SHORTCUT_UPDATE_EXISTING));
532
533 file_util::ShortcutProperties expected_properties = link_properties_;
534 expected_properties.set_target(link_properties_2_.target);
535 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
536 file_util::VerifyShortcut(link_file_.value(), expected_properties));
537 }
538
539 TEST_F(FileUtilShortcutTest, UpdateShortcutMakeDualMode) {
540 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
541 link_file_.value().c_str(), link_properties_,
542 file_util::SHORTCUT_CREATE_ALWAYS));
543
544 file_util::ShortcutProperties make_dual_mode_properties;
545 make_dual_mode_properties.set_dual_mode(true);
546
547 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
548 link_file_.value().c_str(), make_dual_mode_properties,
549 file_util::SHORTCUT_UPDATE_EXISTING));
550
551 file_util::ShortcutProperties expected_properties = link_properties_;
552 expected_properties.set_dual_mode(true);
553 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
554 file_util::VerifyShortcut(link_file_.value(), expected_properties));
555 }
556
557 TEST_F(FileUtilShortcutTest, UpdateShortcutRemoveDualMode) {
558 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
559 link_file_.value().c_str(), link_properties_2_,
560 file_util::SHORTCUT_CREATE_ALWAYS));
561
562 file_util::ShortcutProperties remove_dual_mode_properties;
563 remove_dual_mode_properties.set_dual_mode(false);
564
565 ASSERT_TRUE(file_util::CreateOrUpdateShortcutLink(
566 link_file_.value().c_str(), remove_dual_mode_properties,
567 file_util::SHORTCUT_UPDATE_EXISTING));
568
569 file_util::ShortcutProperties expected_properties = link_properties_2_;
570 expected_properties.set_dual_mode(false);
571 ASSERT_EQ(file_util::VERIFY_SHORTCUT_SUCCESS,
572 file_util::VerifyShortcut(link_file_.value(), expected_properties));
573 }
574
400 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) { 575 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) {
401 // Build the following directory structure: 576 // Build the following directory structure:
402 // 577 //
403 // temp_dir 578 // temp_dir
404 // |-> base_a 579 // |-> base_a
405 // | |-> sub_a 580 // | |-> sub_a
406 // | |-> file.txt 581 // | |-> file.txt
407 // | |-> long_name___... (Very long name.) 582 // | |-> long_name___... (Very long name.)
408 // | |-> sub_long 583 // | |-> sub_long
409 // | |-> deep.txt 584 // | |-> deep.txt
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 std::wstring contents; 1807 std::wstring contents;
1633 contents = ReadTextFile(link_file); 1808 contents = ReadTextFile(link_file);
1634 EXPECT_EQ(L"This is the target.", contents); 1809 EXPECT_EQ(L"This is the target.", contents);
1635 1810
1636 // Cleaning 1811 // Cleaning
1637 DeleteFile(target_file.value().c_str()); 1812 DeleteFile(target_file.value().c_str());
1638 DeleteFile(link_file.value().c_str()); 1813 DeleteFile(link_file.value().c_str());
1639 CoUninitialize(); 1814 CoUninitialize();
1640 } 1815 }
1641 1816
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) { 1817 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) {
1665 // Create a directory 1818 // Create a directory
1666 FilePath dir_name_from = 1819 FilePath dir_name_from =
1667 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir")); 1820 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir"));
1668 file_util::CreateDirectory(dir_name_from); 1821 file_util::CreateDirectory(dir_name_from);
1669 ASSERT_TRUE(file_util::PathExists(dir_name_from)); 1822 ASSERT_TRUE(file_util::PathExists(dir_name_from));
1670 1823
1671 // Create a file under the directory 1824 // Create a file under the directory
1672 FilePath file_name_from = 1825 FilePath file_name_from =
1673 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1826 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( 2611 file_util::VerifyPathControlledByUser(
2459 base_dir_, text_file_, uid_, ok_gids_)); 2612 base_dir_, text_file_, uid_, ok_gids_));
2460 EXPECT_TRUE( 2613 EXPECT_TRUE(
2461 file_util::VerifyPathControlledByUser( 2614 file_util::VerifyPathControlledByUser(
2462 sub_dir_, text_file_, uid_, ok_gids_)); 2615 sub_dir_, text_file_, uid_, ok_gids_));
2463 } 2616 }
2464 2617
2465 #endif // defined(OS_POSIX) 2618 #endif // defined(OS_POSIX)
2466 2619
2467 } // namespace 2620 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698