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

Side by Side Diff: chrome/browser/profiles/profile_manager_browsertest.cc

Issue 2021253002: Skip profiles in GetLastOpenedProfiles that fail to initialize (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add test, fix nits Created 4 years, 6 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
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 <stddef.h> 5 #include <stddef.h>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 18 matching lines...) Expand all
29 29
30 #if defined(OS_CHROMEOS) 30 #if defined(OS_CHROMEOS)
31 #include "base/path_service.h" 31 #include "base/path_service.h"
32 #include "chrome/browser/chromeos/profiles/profile_helper.h" 32 #include "chrome/browser/chromeos/profiles/profile_helper.h"
33 #include "chrome/common/chrome_constants.h" 33 #include "chrome/common/chrome_constants.h"
34 #include "chrome/common/chrome_paths.h" 34 #include "chrome/common/chrome_paths.h"
35 #include "chromeos/chromeos_switches.h" 35 #include "chromeos/chromeos_switches.h"
36 #include "testing/gtest/include/gtest/gtest.h" 36 #include "testing/gtest/include/gtest/gtest.h"
37 #endif 37 #endif
38 38
39 #if defined(OS_WIN)
40 #include <AccCtrl.h>
41 #include <Aclapi.h>
42 #include "base/callback_forward.h"
43 #include "base/files/file_util.h"
44 #include "base/path_service.h"
45 #include "chrome/common/chrome_paths.h"
46 #include "chrome/common/chrome_switches.h"
47 #endif
Peter Kasting 2016/06/04 01:24:25 Nit: There's a lot of stuff in this block and adde
WC Leung 2016/06/04 04:55:22 SGTM
48
39 namespace { 49 namespace {
40 50
41 const ProfileManager::CreateCallback kOnProfileSwitchDoNothing; 51 const ProfileManager::CreateCallback kOnProfileSwitchDoNothing;
42 52
43 // An observer that returns back to test code after a new profile is 53 // An observer that returns back to test code after a new profile is
44 // initialized. 54 // initialized.
45 void OnUnblockOnProfileCreation(base::RunLoop* run_loop, 55 void OnUnblockOnProfileCreation(base::RunLoop* run_loop,
46 Profile* profile, 56 Profile* profile,
47 Profile::CreateStatus status) { 57 Profile::CreateStatus status) {
48 if (status == Profile::CREATE_STATUS_INITIALIZED) 58 if (status == Profile::CREATE_STATUS_INITIALIZED)
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 502
493 EXPECT_FALSE(profile->HasOffTheRecordProfile()); 503 EXPECT_FALSE(profile->HasOffTheRecordProfile());
494 EXPECT_FALSE(profile_manager->IsValidProfile(incognito_profile)); 504 EXPECT_FALSE(profile_manager->IsValidProfile(incognito_profile));
495 EXPECT_EQ(initial_profile_count, profile_manager->GetNumberOfProfiles()); 505 EXPECT_EQ(initial_profile_count, profile_manager->GetNumberOfProfiles());
496 // After destroying the incognito profile incognito preferences should be 506 // After destroying the incognito profile incognito preferences should be
497 // cleared so the default save path should be taken from the main profile. 507 // cleared so the default save path should be taken from the main profile.
498 EXPECT_FALSE(profile->GetOffTheRecordPrefs() 508 EXPECT_FALSE(profile->GetOffTheRecordPrefs()
499 ->GetFilePath(prefs::kSaveFileDefaultDirectory) 509 ->GetFilePath(prefs::kSaveFileDefaultDirectory)
500 .empty()); 510 .empty());
501 } 511 }
512
513 #if defined(OS_WIN)
514
515 bool AddAceToObjectsSecurityDescriptor(LPTSTR filename, LPTSTR trustee,
brettw 2016/06/03 21:47:24 I'm OK duplicating this code. It's a bit yucky but
Peter Kasting 2016/06/04 01:24:25 It looks to me as if these two are so close that j
WC Leung 2016/06/04 04:55:22 I see. Then I'll do the deduplication.
516 DWORD access_rights, ACCESS_MODE access_mode, DWORD inheritance) {
Peter Kasting 2016/06/04 01:24:25 Nit: All lines of args must be indented the same.
WC Leung 2016/06/04 04:55:21 Acknowledged. Anyway, if that deduplication succee
517 // Get a pointer to the existing DACL.
518 ACL* old_dacl = nullptr;
519 PSECURITY_DESCRIPTOR security_descriptor = nullptr;
520 DWORD result = GetNamedSecurityInfo(filename, SE_FILE_OBJECT,
521 DACL_SECURITY_INFORMATION,
522 nullptr, nullptr, &old_dacl, nullptr,
523 &security_descriptor);
524 if (result != ERROR_SUCCESS) {
525 LOG(WARNING) << "GetNamedSecurityInfo Error " << result;
Peter Kasting 2016/06/04 01:24:25 Are you going to collect and analyze this log data
526 } else {
527 // Initialize an EXPLICIT_ACCESS structure for the new ACE.
528 EXPLICIT_ACCESS explicit_access;
529 ZeroMemory(&explicit_access, sizeof(EXPLICIT_ACCESS));
530 explicit_access.grfAccessPermissions = access_rights;
531 explicit_access.grfAccessMode = access_mode;
532 explicit_access.grfInheritance = inheritance;
533 explicit_access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
534 explicit_access.Trustee.ptstrName = trustee;
Peter Kasting 2016/06/04 01:24:25 Nit: Try to use initializer values if possible, e.
535
536 // Create a new ACL that merges the new ACE into the existing DACL.
537 ACL* new_dacl = nullptr;
538 result = SetEntriesInAcl(1, &explicit_access, old_dacl, &new_dacl);
539 if (result != ERROR_SUCCESS) {
540 LOG(WARNING) << "SetEntriesInAcl Error " << result;
541 } else {
542 // Attach the new ACL as the object's DACL.
543 result = SetNamedSecurityInfo(filename, SE_FILE_OBJECT,
544 DACL_SECURITY_INFORMATION,
545 nullptr, nullptr, new_dacl, nullptr);
546 if (result != ERROR_SUCCESS)
547 LOG(WARNING) << "SetNamedSecurityInfo Error " << result;
548 }
549
550 if (new_dacl)
Peter Kasting 2016/06/04 01:24:25 Don't conditionalize these LocalFree() calls; it s
WC Leung 2016/06/04 04:55:22 Noted and thanks. https://msdn.microsoft.com/en-us
551 LocalFree((HLOCAL)new_dacl);
Peter Kasting 2016/06/04 01:24:25 Consider creating a scoping object that frees thes
WC Leung 2016/06/04 04:55:22 Acknowledged.
552 }
553
554 if (security_descriptor)
555 LocalFree((HLOCAL)security_descriptor);
556
557 return result == ERROR_SUCCESS;
558 }
559
560 bool RemoveCreateDirectoryPermission(const base::FilePath& path) {
561 return AddAceToObjectsSecurityDescriptor(
562 const_cast<wchar_t*>(path.value().c_str()), L"EVERYONE",
563 FILE_ADD_SUBDIRECTORY, DENY_ACCESS, NO_INHERITANCE);
564 }
565
566 class ProfileManagerWinBrowserTest : public ProfileManagerBrowserTest {
567 public:
568 // Tests may be reported as PASS even if the test has never been run. To
Peter Kasting 2016/06/04 01:24:25 I have no idea what this is talking about :(.
WC Leung 2016/06/04 04:55:22 You've stumpled on a bug in the browser test. :-)
Peter Kasting 2016/06/04 08:01:39 Please understand this bug completely before proce
WC Leung 2016/06/04 15:48:33 Agree that the bug needs more investigation. The p
569 // mitigate the issue, a "red flag" is raised for suspectable tests. These
Peter Kasting 2016/06/04 01:24:25 Do you mean "susceptible" or "suspicious"?
WC Leung 2016/06/04 04:55:22 Susceptble. Sorry for wrong spelling.
WC Leung 2016/06/04 17:34:43 Done.
570 // tests need to call DropRedFlag() to pass the test.
571 void DropRedFlag() { red_flag_ = false; }
572
573 protected:
574 void SetUpCommandLine(base::CommandLine* command_line) override {
575 command_line->AppendSwitch(switches::kRestoreLastSession);
576 }
577
578 bool SetUpUserDataDirectory() override {
579 std::string testname(
580 testing::UnitTest::GetInstance()->current_test_info()->name());
581 if (testname == "LastOpenedProfileMissing") {
brettw 2016/06/03 21:47:24 This seems potentially very confusing since people
WC Leung 2016/06/04 04:55:22 We need to do remove a profile directory and set t
582 red_flag_ = true;
583
584 base::FilePath user_data_dir;
585 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
586 return false;
587
588 base::FilePath dir_to_delete = user_data_dir.AppendASCII("Profile 1");
589 return base::DirectoryExists(dir_to_delete) &&
590 DeleteFile(dir_to_delete, true) &&
591 RemoveCreateDirectoryPermission(user_data_dir);
592 }
593 return true;
594 }
595
596 void TearDown() override {
597 EXPECT_FALSE(red_flag_);
598 ProfileManagerBrowserTest::TearDown();
599 }
600
601 private:
602 bool red_flag_ = false;
603 };
Peter Kasting 2016/06/04 01:24:25 Nit: DISALLOW_COPY_AND_ASSIGN
WC Leung 2016/06/04 04:55:22 Acknowledged.
WC Leung 2016/06/04 17:34:43 Unable to do this in test fixtures, because compil
Peter Kasting 2016/06/04 18:12:31 Why?
WC Leung 2016/06/05 03:04:48 Here's the compiler log: f:\chromium\src\chrome\b
604
605 IN_PROC_BROWSER_TEST_F(ProfileManagerWinBrowserTest,
606 PRE_LastOpenedProfileMissing) {
Peter Kasting 2016/06/04 01:24:25 I'm not terribly familiar with using PRE_ in tests
WC Leung 2016/06/04 04:55:22 The test (PRE_ and non-PRE_ as a whole) do the fol
Peter Kasting 2016/06/04 08:01:39 That didn't really answer my question. Are you sa
WC Leung 2016/06/04 15:48:33 Oh sorry for my bad explanation. What you're sayin
607 ProfileManager* profile_manager = g_browser_process->profile_manager();
608 ASSERT_TRUE(profile_manager);
609
610 std::vector<base::FilePath> profile_paths;
611 // Create two additional profile.
612 for (int i = 0; i < 2; ++i) {
613 base::FilePath path = profile_manager->GenerateNextProfileDirectoryPath();
614 profile_paths.push_back(path);
615
616 base::RunLoop run_loop;
617 profile_manager->CreateProfileAsync(
618 path, base::Bind(&OnUnblockOnProfileCreation, &run_loop),
619 base::string16(), std::string(), std::string());
620
621 // Run the message loop to allow profile creation to take place; the loop is
622 // terminated by OnUnblockOnProfileCreation when the profile is created.
623 run_loop.Run();
624
625 profiles::SwitchToProfile(path, false, kOnProfileSwitchDoNothing,
626 ProfileMetrics::SWITCH_PROFILE_ICON);
627 }
628
629 ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("Profile 1")),
630 profile_paths[0].BaseName());
631 }
632
633 IN_PROC_BROWSER_TEST_F(ProfileManagerWinBrowserTest,
634 LastOpenedProfileMissing) {
635 DropRedFlag();
636
637 ProfileManager* profile_manager = g_browser_process->profile_manager();
Peter Kasting 2016/06/04 01:24:25 Why do you need this variable?
WC Leung 2016/06/04 04:55:21 I don't need it, sorry for that. Forgot to remove
638 ASSERT_TRUE(profile_manager);
639
640 BrowserList* browser_list = BrowserList::GetInstance();
641 EXPECT_EQ(2u, browser_list->size());
642 for (const Browser* browser : *browser_list) {
643 EXPECT_NE(base::FilePath(FILE_PATH_LITERAL("Profile 1")),
644 browser->profile()->GetPath().BaseName());
645 }
646 }
647 #endif // defined(OS_WIN)
Peter Kasting 2016/06/04 01:24:25 Nit: Blank line above this, or no blank below the
WC Leung 2016/06/04 04:55:22 Acknowledged.
OLDNEW
« no previous file with comments | « chrome/browser/profiles/profile_manager.cc ('k') | chrome/browser/ui/startup/startup_browser_creator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698