Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / chrome / browser / profiles / profile_manager_browsertest.cc
blobf07472902f85fa851324cbb7d1a820141d046a84
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
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/password_manager/password_store_factory.h"
10 #include "chrome/browser/profiles/profile_info_cache.h"
11 #include "chrome/browser/profiles/profile_info_cache_observer.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/profiles/profile_window.h"
14 #include "chrome/browser/profiles/profiles_state.h"
15 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/browser/ui/browser_list.h"
17 #include "chrome/browser/ui/browser_window.h"
18 #include "chrome/browser/ui/host_desktop.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/test_switches.h"
22 #include "chrome/test/base/testing_browser_process.h"
23 #include "components/autofill/core/common/password_form.h"
24 #include "components/password_manager/core/browser/password_store.h"
25 #include "components/password_manager/core/browser/password_store_consumer.h"
26 #include "content/public/test/test_utils.h"
28 #if defined(OS_CHROMEOS)
29 #include "base/path_service.h"
30 #include "chrome/common/chrome_constants.h"
31 #include "chrome/common/chrome_paths.h"
32 #include "chromeos/chromeos_switches.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34 #endif
36 namespace {
38 const ProfileManager::CreateCallback kOnProfileSwitchDoNothing;
40 // An observer that returns back to test code after a new profile is
41 // initialized.
42 void OnUnblockOnProfileCreation(Profile* profile,
43 Profile::CreateStatus status) {
44 if (status == Profile::CREATE_STATUS_INITIALIZED)
45 base::MessageLoop::current()->Quit();
48 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) {
49 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL);
50 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL);
51 // No browser should have been created for this profile yet.
52 EXPECT_EQ(chrome::GetTotalBrowserCountForProfile(profile), 0U);
53 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
54 if (status == Profile::CREATE_STATUS_INITIALIZED)
55 base::MessageLoop::current()->Quit();
58 void EphemeralProfileCreationComplete(Profile* profile,
59 Profile::CreateStatus status) {
60 if (status == Profile::CREATE_STATUS_INITIALIZED)
61 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true);
62 ProfileCreationComplete(profile, status);
65 class ProfileRemovalObserver : public ProfileInfoCacheObserver {
66 public:
67 ProfileRemovalObserver() {
68 g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(
69 this);
72 ~ProfileRemovalObserver() override {
73 g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
74 this);
77 std::string last_used_profile_name() { return last_used_profile_name_; }
79 // ProfileInfoCacheObserver overrides:
80 void OnProfileWillBeRemoved(const base::FilePath& profile_path) override {
81 last_used_profile_name_ = g_browser_process->local_state()->GetString(
82 prefs::kProfileLastUsed);
85 private:
86 std::string last_used_profile_name_;
88 DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver);
91 // The class serves to retrieve passwords from PasswordStore asynchronously. It
92 // used by ProfileManagerBrowserTest.DeletePasswords on some platforms.
93 class PasswordStoreConsumerVerifier :
94 public password_manager::PasswordStoreConsumer {
95 public:
96 PasswordStoreConsumerVerifier() : called_(false) {}
98 void OnGetPasswordStoreResults(
99 ScopedVector<autofill::PasswordForm> results) override {
100 EXPECT_FALSE(called_);
101 called_ = true;
102 password_entries_.swap(results);
105 bool IsCalled() const { return called_; }
107 const std::vector<autofill::PasswordForm*>& GetPasswords() const {
108 return password_entries_.get();
110 private:
111 ScopedVector<autofill::PasswordForm> password_entries_;
112 bool called_;
115 } // namespace
117 // This file contains tests for the ProfileManager that require a heavyweight
118 // InProcessBrowserTest. These include tests involving profile deletion.
120 // TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
121 // platforms.
122 class ProfileManagerBrowserTest : public InProcessBrowserTest {
123 protected:
124 void SetUpCommandLine(base::CommandLine* command_line) override {
125 #if defined(OS_CHROMEOS)
126 command_line->AppendSwitch(
127 chromeos::switches::kIgnoreUserProfileMappingForTests);
128 #endif
132 #if defined(OS_MACOSX)
134 // Delete single profile and make sure a new one is created.
135 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
136 ProfileManager* profile_manager = g_browser_process->profile_manager();
137 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
138 ProfileRemovalObserver observer;
140 // We should start out with 1 profile.
141 ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);
143 // Delete singleton profile.
144 base::FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
145 EXPECT_FALSE(singleton_profile_path.empty());
146 profile_manager->ScheduleProfileForDeletion(singleton_profile_path,
147 ProfileManager::CreateCallback());
149 // Spin things till profile is actually deleted.
150 content::RunAllPendingInMessageLoop();
152 // Make sure a new profile was created automatically.
153 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
154 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
155 EXPECT_NE(new_profile_path, singleton_profile_path);
157 // Make sure that last used profile preference is set correctly.
158 Profile* last_used = ProfileManager::GetLastUsedProfile();
159 EXPECT_EQ(new_profile_path, last_used->GetPath());
161 // Make sure the last used profile was set correctly before the notification
162 // was sent.
163 std::string last_used_profile_name =
164 last_used->GetPath().BaseName().MaybeAsASCII();
165 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name());
168 // Delete all profiles in a multi profile setup and make sure a new one is
169 // created.
170 // Crashes/CHECKs. See crbug.com/104851
171 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) {
172 ProfileManager* profile_manager = g_browser_process->profile_manager();
173 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
175 // Create an additional profile.
176 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
177 profile_manager->CreateProfileAsync(new_path,
178 base::Bind(&OnUnblockOnProfileCreation),
179 base::string16(), base::string16(),
180 std::string());
182 // Spin to allow profile creation to take place, loop is terminated
183 // by OnUnblockOnProfileCreation when the profile is created.
184 content::RunMessageLoop();
186 ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
188 // Delete all profiles.
189 base::FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
190 base::FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
191 EXPECT_FALSE(profile_path1.empty());
192 EXPECT_FALSE(profile_path2.empty());
193 profile_manager->ScheduleProfileForDeletion(profile_path1,
194 ProfileManager::CreateCallback());
195 profile_manager->ScheduleProfileForDeletion(profile_path2,
196 ProfileManager::CreateCallback());
198 // Spin things so deletion can take place.
199 content::RunAllPendingInMessageLoop();
201 // Make sure a new profile was created automatically.
202 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
203 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
204 EXPECT_NE(new_profile_path, profile_path1);
205 EXPECT_NE(new_profile_path, profile_path2);
207 // Make sure that last used profile preference is set correctly.
208 Profile* last_used = ProfileManager::GetLastUsedProfile();
209 EXPECT_EQ(new_profile_path, last_used->GetPath());
211 #endif // OS_MACOSX
213 #if defined(OS_CHROMEOS)
215 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest {
216 protected:
217 void SetUpCommandLine(base::CommandLine* command_line) override {
218 // Use a user hash other than the default chrome::kTestUserProfileDir
219 // so that the prefix case is tested.
220 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
221 "test-user-hash");
225 IN_PROC_BROWSER_TEST_F(ProfileManagerCrOSBrowserTest, GetLastUsedProfile) {
226 // Make sure that last used profile is correct.
227 Profile* last_used_profile = ProfileManager::GetLastUsedProfile();
228 EXPECT_TRUE(last_used_profile != NULL);
230 base::FilePath profile_path;
231 PathService::Get(chrome::DIR_USER_DATA, &profile_path);
233 profile_path = profile_path.AppendASCII(
234 std::string(chrome::kProfileDirPrefix) + "test-user-hash");
235 EXPECT_EQ(profile_path.value(), last_used_profile->GetPath().value());
238 #endif // OS_CHROMEOS
240 // Times out (http://crbug.com/159002)
241 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
242 DISABLED_CreateProfileWithCallback) {
243 ProfileManager* profile_manager = g_browser_process->profile_manager();
245 ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
246 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
248 // Create a profile, make sure callback is invoked before any callbacks are
249 // invoked (so they can do things like sign in the profile, etc).
250 ProfileManager::CreateMultiProfileAsync(
251 base::string16(), // name
252 base::string16(), // icon url
253 base::Bind(ProfileCreationComplete),
254 std::string());
255 // Wait for profile to finish loading.
256 content::RunMessageLoop();
257 EXPECT_EQ(profile_manager->GetNumberOfProfiles(), 2U);
258 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
260 // Now close all browser windows.
261 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
262 for (std::vector<Profile*>::const_iterator it = profiles.begin();
263 it != profiles.end(); ++it) {
264 BrowserList::CloseAllBrowsersWithProfile(*it);
268 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
269 SwitchToProfile) {
270 #if defined(OS_WIN) && defined(USE_ASH)
271 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
272 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
273 switches::kAshBrowserTests))
274 return;
275 #endif
277 // If multiprofile mode is not enabled, you can't switch between profiles.
278 if (!profiles::IsMultipleProfilesEnabled())
279 return;
281 ProfileManager* profile_manager = g_browser_process->profile_manager();
282 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
283 base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
285 ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
286 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
288 // Create an additional profile.
289 base::FilePath path_profile2 =
290 profile_manager->GenerateNextProfileDirectoryPath();
291 profile_manager->CreateProfileAsync(path_profile2,
292 base::Bind(&OnUnblockOnProfileCreation),
293 base::string16(), base::string16(),
294 std::string());
296 // Spin to allow profile creation to take place, loop is terminated
297 // by OnUnblockOnProfileCreation when the profile is created.
298 content::RunMessageLoop();
300 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
301 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
302 ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
303 EXPECT_EQ(1U, browser_list->size());
305 // Open a browser window for the first profile.
306 profiles::SwitchToProfile(path_profile1, desktop_type, false,
307 kOnProfileSwitchDoNothing,
308 ProfileMetrics::SWITCH_PROFILE_ICON);
309 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
310 EXPECT_EQ(1U, browser_list->size());
311 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
313 // Open a browser window for the second profile.
314 profiles::SwitchToProfile(path_profile2, desktop_type, false,
315 kOnProfileSwitchDoNothing,
316 ProfileMetrics::SWITCH_PROFILE_ICON);
317 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
318 EXPECT_EQ(2U, browser_list->size());
319 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
321 // Switch to the first profile without opening a new window.
322 profiles::SwitchToProfile(path_profile1, desktop_type, false,
323 kOnProfileSwitchDoNothing,
324 ProfileMetrics::SWITCH_PROFILE_ICON);
325 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
326 EXPECT_EQ(2U, browser_list->size());
328 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
329 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
332 // Flakes on Windows: http://crbug.com/314905
333 #if defined(OS_WIN)
334 #define MAYBE_EphemeralProfile DISABLED_EphemeralProfile
335 #else
336 #define MAYBE_EphemeralProfile EphemeralProfile
337 #endif
338 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, MAYBE_EphemeralProfile) {
339 #if defined(OS_WIN) && defined(USE_ASH)
340 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
341 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
342 switches::kAshBrowserTests))
343 return;
344 #endif
346 // If multiprofile mode is not enabled, you can't switch between profiles.
347 if (!profiles::IsMultipleProfilesEnabled())
348 return;
350 ProfileManager* profile_manager = g_browser_process->profile_manager();
351 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
352 base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
354 ASSERT_EQ(1U, profile_manager->GetNumberOfProfiles());
355 EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
357 // Create an ephemeral profile.
358 base::FilePath path_profile2 =
359 profile_manager->GenerateNextProfileDirectoryPath();
360 profile_manager->CreateProfileAsync(
361 path_profile2,
362 base::Bind(&EphemeralProfileCreationComplete),
363 base::string16(), base::string16(), std::string());
365 // Spin to allow profile creation to take place.
366 content::RunMessageLoop();
368 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
369 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
370 ASSERT_EQ(2U, cache.GetNumberOfProfiles());
371 EXPECT_EQ(1U, browser_list->size());
373 // Open a browser window for the second profile.
374 profiles::SwitchToProfile(path_profile2, desktop_type, false,
375 kOnProfileSwitchDoNothing,
376 ProfileMetrics::SWITCH_PROFILE_ICON);
377 EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
378 EXPECT_EQ(2U, browser_list->size());
379 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
381 // Create a second window for the ephemeral profile.
382 profiles::SwitchToProfile(path_profile2, desktop_type, true,
383 kOnProfileSwitchDoNothing,
384 ProfileMetrics::SWITCH_PROFILE_ICON);
385 EXPECT_EQ(3U, chrome::GetTotalBrowserCount());
386 EXPECT_EQ(3U, browser_list->size());
388 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
389 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
390 EXPECT_EQ(path_profile2, browser_list->get(2)->profile()->GetPath());
392 // Closing the first window of the ephemeral profile should not delete it.
393 browser_list->get(2)->window()->Close();
394 content::RunAllPendingInMessageLoop();
395 EXPECT_EQ(2U, browser_list->size());
396 ASSERT_EQ(2U, cache.GetNumberOfProfiles());
398 // The second should though.
399 browser_list->get(1)->window()->Close();
400 content::RunAllPendingInMessageLoop();
401 EXPECT_EQ(1U, browser_list->size());
402 ASSERT_EQ(1U, cache.GetNumberOfProfiles());
405 // The test makes sense on those platforms where the keychain exists.
406 #if !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
407 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeletePasswords) {
408 Profile* profile = ProfileManager::GetActiveUserProfile();
409 ASSERT_TRUE(profile);
411 autofill::PasswordForm form;
412 form.scheme = autofill::PasswordForm::SCHEME_HTML;
413 form.origin = GURL("http://accounts.google.com/LoginAuth");
414 form.signon_realm = "http://accounts.google.com/";
415 form.username_value = base::ASCIIToUTF16("my_username");
416 form.password_value = base::ASCIIToUTF16("my_password");
417 form.ssl_valid = false;
418 form.preferred = true;
419 form.blacklisted_by_user = false;
421 scoped_refptr<password_manager::PasswordStore> password_store =
422 PasswordStoreFactory::GetForProfile(
423 profile, ServiceAccessType::EXPLICIT_ACCESS).get();
424 ASSERT_TRUE(password_store.get());
426 password_store->AddLogin(form);
427 PasswordStoreConsumerVerifier verify_add;
428 password_store->GetAutofillableLogins(&verify_add);
430 ProfileManager* profile_manager = g_browser_process->profile_manager();
431 profile_manager->ScheduleProfileForDeletion(profile->GetPath(),
432 ProfileManager::CreateCallback());
433 content::RunAllPendingInMessageLoop();
434 PasswordStoreConsumerVerifier verify_delete;
435 password_store->GetAutofillableLogins(&verify_delete);
437 // Run the password background thread.
438 base::RunLoop run_loop;
439 base::Closure task = base::Bind(
440 base::IgnoreResult(&content::BrowserThread::PostTask),
441 content::BrowserThread::UI,
442 FROM_HERE,
443 run_loop.QuitClosure());
444 EXPECT_TRUE(password_store->ScheduleTask(task));
445 run_loop.Run();
447 EXPECT_TRUE(verify_add.IsCalled());
448 EXPECT_EQ(1u, verify_add.GetPasswords().size());
449 EXPECT_TRUE(verify_delete.IsCalled());
450 EXPECT_EQ(0u, verify_delete.GetPasswords().size());
452 #endif // !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)