Chromium Code Reviews| Index: chrome/browser/profiles/profile_manager_browsertest.cc |
| diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc |
| index f0287d73c6b953d7a3c65518adb11d0e0178910c..9f5e1059b41be1f03a7cc4b35fde3c52304b8537 100644 |
| --- a/chrome/browser/profiles/profile_manager_browsertest.cc |
| +++ b/chrome/browser/profiles/profile_manager_browsertest.cc |
| @@ -7,8 +7,13 @@ |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/macros.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/stl_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| +#include "chrome/browser/browsing_data/browsing_data_remover_impl.h" |
| +#include "chrome/browser/lifetime/keep_alive_types.h" |
| +#include "chrome/browser/lifetime/scoped_keep_alive.h" |
| #include "chrome/browser/password_manager/password_store_factory.h" |
| #include "chrome/browser/profiles/profile_attributes_entry.h" |
| #include "chrome/browser/profiles/profile_attributes_storage.h" |
| @@ -59,6 +64,79 @@ void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) { |
| base::MessageLoop::current()->QuitWhenIdle(); |
| } |
| +// An observer returns back to test code after one or more profiles was deleted. |
| +// It has ScopedKeepAlive object to prevent browser shutdown started in case |
|
Mike Lerman
2017/04/03 16:56:49
nit: this sentence needs better grammar
|
| +// browser become windowless. |
| +class MultipleProfileDeletionObserver |
| + : public BrowsingDataRemoverImpl::CompletionInhibitor { |
| + public: |
| + MultipleProfileDeletionObserver(size_t expect_profile_creation_count, |
| + size_t expected_profile_data_removed_count) |
| + : profiles_created_count_(0), |
| + profiles_data_removed_count_(0), |
| + expected_profile_creation_count_(expect_profile_creation_count), |
| + expected_profile_data_removed_count_( |
| + expected_profile_data_removed_count) { |
| + size_t expected_events_count = |
| + expected_profile_creation_count_ + expected_profile_data_removed_count_; |
| + EXPECT_GT(expected_events_count, 0u); |
| + BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(this); |
| + } |
| + ~MultipleProfileDeletionObserver() { |
| + BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(nullptr); |
| + } |
| + ProfileManager::CreateCallback OnProfileCreatedClosure() { |
| + return base::Bind(&MultipleProfileDeletionObserver::OnProfileCreated, |
| + base::Unretained(this)); |
| + } |
| + void Wait() { |
| + keep_alive_ = base::MakeUnique<ScopedKeepAlive>( |
| + KeepAliveOrigin::PROFILE_HELPER, KeepAliveRestartOption::DISABLED); |
| + loop_.Run(); |
| + } |
| + |
| + private: |
| + void OnProfileCreated(Profile* profile, Profile::CreateStatus status) { |
| + EXPECT_EQ(Profile::CREATE_STATUS_INITIALIZED, status); |
| + profiles_created_count_++; |
| + MaybeQuit(); |
| + } |
| + |
| + // TODO(https://crbug.com/704601): remove this code when bug is fixed. |
| + void OnBrowsingDataRemoverWouldComplete( |
| + BrowsingDataRemoverImpl* remover, |
| + const base::Closure& continue_to_completion) override { |
| + continue_to_completion.Run(); |
| + profiles_data_removed_count_++; |
| + MaybeQuit(); |
| + } |
| + |
| + void MaybeQuit() { |
| + DLOG(INFO) << profiles_created_count_ << " of expected " |
| + << expected_profile_creation_count_ << " profiles created, " |
| + << profiles_data_removed_count_ << " of expected " |
| + << expected_profile_data_removed_count_ |
| + << " profile data removed."; |
| + if (profiles_created_count_ < expected_profile_creation_count_ || |
| + profiles_data_removed_count_ < expected_profile_data_removed_count_) |
| + return; |
| + |
| + EXPECT_EQ(expected_profile_creation_count_, profiles_created_count_); |
| + EXPECT_EQ(expected_profile_data_removed_count_, |
| + profiles_data_removed_count_); |
| + |
| + keep_alive_.reset(); |
| + loop_.Quit(); |
| + } |
| + |
| + base::RunLoop loop_; |
| + std::unique_ptr<ScopedKeepAlive> keep_alive_; |
| + size_t profiles_created_count_; |
| + size_t profiles_data_removed_count_; |
| + size_t expected_profile_creation_count_; |
| + size_t expected_profile_data_removed_count_; |
| +}; |
| + |
| void EphemeralProfileCreationComplete(Profile* profile, |
| Profile::CreateStatus status) { |
| if (status == Profile::CREATE_STATUS_INITIALIZED) |
| @@ -152,7 +230,9 @@ class ProfileManagerBrowserTest : public InProcessBrowserTest { |
| } |
| }; |
| -#if defined(OS_MACOSX) |
| +// Android does not support multi-profiles, and CrOS multi-profiles |
| +// implementation is too different for these tests. |
| +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
| // Delete single profile and make sure a new one is created. |
| IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) { |
| @@ -168,14 +248,14 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) { |
| base::FilePath singleton_profile_path = |
| storage.GetAllProfilesAttributes().front()->GetPath(); |
| EXPECT_FALSE(singleton_profile_path.empty()); |
| - base::RunLoop run_loop; |
| + MultipleProfileDeletionObserver profile_deletion_observer(1u, 1u); |
| profile_manager->ScheduleProfileForDeletion( |
| singleton_profile_path, |
| - base::Bind(&OnUnblockOnProfileCreation, &run_loop)); |
| + profile_deletion_observer.OnProfileCreatedClosure()); |
| // Run the message loop until the profile is actually deleted (as indicated |
| // by the callback above being called). |
| - run_loop.Run(); |
| + profile_deletion_observer.Wait(); |
| // Make sure a new profile was created automatically. |
| EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
| @@ -194,10 +274,76 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) { |
| EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name()); |
| } |
| +// Delete inactive profile in a multi profile setup and make sure current |
| +// browser is not affected. |
| +IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteInactiveProfile) { |
| + ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| + ProfileAttributesStorage& storage = |
| + profile_manager->GetProfileAttributesStorage(); |
| + base::FilePath current_profile_path = browser()->profile()->GetPath(); |
| + |
| + // Create an additional profile. |
| + base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
| + base::RunLoop run_loop; |
| + profile_manager->CreateProfileAsync( |
| + new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), |
| + base::string16(), std::string(), std::string()); |
| + run_loop.Run(); |
| + |
| + ASSERT_EQ(2u, storage.GetNumberOfProfiles()); |
| + |
| + // Delete inactive profile. |
| + MultipleProfileDeletionObserver profile_deletion_observer(0u, 1u); |
| + profile_manager->ScheduleProfileForDeletion( |
| + new_path, profile_deletion_observer.OnProfileCreatedClosure()); |
| + profile_deletion_observer.Wait(); |
| + |
| + // Make sure there only preexisted profile left. |
| + EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
| + EXPECT_EQ(current_profile_path, |
| + storage.GetAllProfilesAttributes().front()->GetPath()); |
| + |
| + // Make sure that last used profile preference is set correctly. |
| + Profile* last_used = ProfileManager::GetLastUsedProfile(); |
| + EXPECT_EQ(current_profile_path, last_used->GetPath()); |
| +} |
| + |
| +// Delete current profile in a multi profile setup and make sure an existing one |
| +// is loaded. |
| +IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteCurrentProfile) { |
| + ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| + ProfileAttributesStorage& storage = |
| + profile_manager->GetProfileAttributesStorage(); |
| + |
| + // Create an additional profile. |
| + base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
| + base::RunLoop run_loop; |
| + profile_manager->CreateProfileAsync( |
| + new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), |
| + base::string16(), std::string(), std::string()); |
| + run_loop.Run(); |
| + |
| + ASSERT_EQ(2u, storage.GetNumberOfProfiles()); |
| + |
| + // Delete current profile. |
| + MultipleProfileDeletionObserver profile_deletion_observer(1u, 1u); |
| + profile_manager->ScheduleProfileForDeletion( |
| + browser()->profile()->GetPath(), |
| + profile_deletion_observer.OnProfileCreatedClosure()); |
| + profile_deletion_observer.Wait(); |
| + |
| + // Make sure a profile created earlier become the only profile. |
| + EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
| + EXPECT_EQ(new_path, storage.GetAllProfilesAttributes().front()->GetPath()); |
| + |
| + // Make sure that last used profile preference is set correctly. |
| + Profile* last_used = ProfileManager::GetLastUsedProfile(); |
| + EXPECT_EQ(new_path, last_used->GetPath()); |
| +} |
| + |
| // Delete all profiles in a multi profile setup and make sure a new one is |
| // created. |
| -// Crashes/CHECKs. See crbug.com/104851 |
| -IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) { |
| +IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteAllProfiles) { |
| ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| ProfileAttributesStorage& storage = |
| profile_manager->GetProfileAttributesStorage(); |
| @@ -216,6 +362,7 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) { |
| ASSERT_EQ(2u, storage.GetNumberOfProfiles()); |
| // Delete all profiles. |
| + MultipleProfileDeletionObserver profile_deletion_observer(2u, 2u); |
| std::vector<ProfileAttributesEntry*> entries = |
| storage.GetAllProfilesAttributes(); |
| std::vector<base::FilePath> old_profile_paths; |
| @@ -223,12 +370,10 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) { |
| base::FilePath profile_path = entry->GetPath(); |
| EXPECT_FALSE(profile_path.empty()); |
| profile_manager->ScheduleProfileForDeletion( |
| - profile_path, ProfileManager::CreateCallback()); |
| + profile_path, profile_deletion_observer.OnProfileCreatedClosure()); |
| old_profile_paths.push_back(profile_path); |
| } |
| - |
| - // Spin things so deletion can take place. |
| - content::RunAllPendingInMessageLoop(); |
| + profile_deletion_observer.Wait(); |
| // Make sure a new profile was created automatically. |
| EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
| @@ -241,7 +386,7 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) { |
| Profile* last_used = ProfileManager::GetLastUsedProfile(); |
| EXPECT_EQ(new_profile_path, last_used->GetPath()); |
| } |
| -#endif // OS_MACOSX |
| +#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
| #if defined(OS_CHROMEOS) |