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. 4 5#include "chrome/browser/profiles/profile.h" 6 7#include "base/file_util.h" 8#include "base/files/scoped_temp_dir.h" 9#include "base/platform_file.h" 10#include "base/prefs/pref_service.h" 11#include "base/version.h" 12#include "chrome/browser/chrome_notification_types.h" 13#include "chrome/browser/profiles/chrome_version_service.h" 14#include "chrome/browser/profiles/profile_impl.h" 15#include "chrome/browser/profiles/startup_task_runner_service.h" 16#include "chrome/browser/profiles/startup_task_runner_service_factory.h" 17#include "chrome/common/chrome_constants.h" 18#include "chrome/common/chrome_version_info.h" 19#include "chrome/common/pref_names.h" 20#include "chrome/test/base/in_process_browser_test.h" 21#include "chrome/test/base/ui_test_utils.h" 22#include "testing/gmock/include/gmock/gmock.h" 23#include "testing/gtest/include/gtest/gtest.h" 24 25namespace { 26 27class MockProfileDelegate : public Profile::Delegate { 28 public: 29 MOCK_METHOD1(OnPrefsLoaded, void(Profile*)); 30 MOCK_METHOD3(OnProfileCreated, void(Profile*, bool, bool)); 31}; 32 33// Creates a prefs file in the given directory. 34void CreatePrefsFileInDirectory(const base::FilePath& directory_path) { 35 base::FilePath pref_path(directory_path.Append(chrome::kPreferencesFilename)); 36 base::PlatformFile file = base::CreatePlatformFile(pref_path, 37 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, NULL, NULL); 38 ASSERT_TRUE(file != base::kInvalidPlatformFileValue); 39 ASSERT_TRUE(base::ClosePlatformFile(file)); 40 std::string data("{}"); 41 ASSERT_TRUE(file_util::WriteFile(pref_path, data.c_str(), data.size())); 42} 43 44void CheckChromeVersion(Profile *profile, bool is_new) { 45 std::string created_by_version; 46 if (is_new) { 47 chrome::VersionInfo version_info; 48 created_by_version = version_info.Version(); 49 } else { 50 created_by_version = "1.0.0.0"; 51 } 52 std::string pref_version = 53 ChromeVersionService::GetVersion(profile->GetPrefs()); 54 // Assert that created_by_version pref gets set to current version. 55 EXPECT_EQ(created_by_version, pref_version); 56} 57 58} // namespace 59 60typedef InProcessBrowserTest ProfileBrowserTest; 61 62// Test OnProfileCreate is called with is_new_profile set to true when 63// creating a new profile synchronously. 64// 65// Flaky (sometimes timeout): http://crbug.com/141141 66IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, 67 DISABLED_CreateNewProfileSynchronous) { 68 base::ScopedTempDir temp_dir; 69 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 70 71 MockProfileDelegate delegate; 72 EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); 73 74 scoped_ptr<Profile> profile(Profile::CreateProfile( 75 temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS)); 76 ASSERT_TRUE(profile.get()); 77 CheckChromeVersion(profile.get(), true); 78 StartupTaskRunnerServiceFactory::GetForProfile(profile.get())-> 79 StartDeferredTaskRunners(); 80} 81 82// Test OnProfileCreate is called with is_new_profile set to false when 83// creating a profile synchronously with an existing prefs file. 84// Flaky: http://crbug.com/141517 85IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, 86 DISABLED_CreateOldProfileSynchronous) { 87 base::ScopedTempDir temp_dir; 88 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 89 CreatePrefsFileInDirectory(temp_dir.path()); 90 91 MockProfileDelegate delegate; 92 EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, false)); 93 94 scoped_ptr<Profile> profile(Profile::CreateProfile( 95 temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS)); 96 ASSERT_TRUE(profile.get()); 97 CheckChromeVersion(profile.get(), false); 98 StartupTaskRunnerServiceFactory::GetForProfile(profile.get())-> 99 StartDeferredTaskRunners(); 100} 101 102// Test OnProfileCreate is called with is_new_profile set to true when 103// creating a new profile asynchronously. 104// This test is flaky on Linux, Win and Mac. See crbug.com/142787 105IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, 106 DISABLED_CreateNewProfileAsynchronous) { 107 base::ScopedTempDir temp_dir; 108 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 109 110 MockProfileDelegate delegate; 111 EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); 112 113 scoped_ptr<Profile> profile(Profile::CreateProfile( 114 temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS)); 115 ASSERT_TRUE(profile.get()); 116 StartupTaskRunnerServiceFactory::GetForProfile(profile.get())-> 117 StartDeferredTaskRunners(); 118 119 // Wait for the profile to be created. 120 content::WindowedNotificationObserver observer( 121 chrome::NOTIFICATION_PROFILE_CREATED, 122 content::Source<Profile>(profile.get())); 123 observer.Wait(); 124 CheckChromeVersion(profile.get(), true); 125} 126 127// Test OnProfileCreate is called with is_new_profile set to false when 128// creating a profile asynchronously with an existing prefs file. 129// Flaky: http://crbug.com/141517 130IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, 131 DISABLED_CreateOldProfileAsynchronous) { 132 base::ScopedTempDir temp_dir; 133 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 134 CreatePrefsFileInDirectory(temp_dir.path()); 135 136 MockProfileDelegate delegate; 137 EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, false)); 138 scoped_ptr<Profile> profile(Profile::CreateProfile( 139 temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS)); 140 ASSERT_TRUE(profile.get()); 141 StartupTaskRunnerServiceFactory::GetForProfile(profile.get())-> 142 StartDeferredTaskRunners(); 143 144 // Wait for the profile to be created. 145 content::WindowedNotificationObserver observer( 146 chrome::NOTIFICATION_PROFILE_CREATED, 147 content::Source<Profile>(profile.get())); 148 observer.Wait(); 149 CheckChromeVersion(profile.get(), false); 150} 151 152// Test that a README file is created for profiles that didn't have it. 153// Flaky: http://crbug.com/140882 154IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DISABLED_ProfileReadmeCreated) { 155 base::ScopedTempDir temp_dir; 156 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 157 158 MockProfileDelegate delegate; 159 EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); 160 161 // No delay before README creation. 162 ProfileImpl::create_readme_delay_ms = 0; 163 164 scoped_ptr<Profile> profile(Profile::CreateProfile( 165 temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS)); 166 ASSERT_TRUE(profile.get()); 167 StartupTaskRunnerServiceFactory::GetForProfile(profile.get())-> 168 StartDeferredTaskRunners(); 169 170 // Wait for the profile to be created. 171 content::WindowedNotificationObserver observer( 172 chrome::NOTIFICATION_PROFILE_CREATED, 173 content::Source<Profile>(profile.get())); 174 observer.Wait(); 175 176 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE); 177 178 // Verify that README exists. 179 EXPECT_TRUE(base::PathExists( 180 temp_dir.path().Append(chrome::kReadmeFilename))); 181} 182 183// Test that Profile can be deleted before README file is created. 184IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ProfileDeletedBeforeReadmeCreated) { 185 base::ScopedTempDir temp_dir; 186 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 187 188 MockProfileDelegate delegate; 189 EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); 190 191 // No delay before README creation. 192 ProfileImpl::create_readme_delay_ms = 0; 193 194 scoped_ptr<Profile> profile(Profile::CreateProfile( 195 temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS)); 196 ASSERT_TRUE(profile.get()); 197 StartupTaskRunnerServiceFactory::GetForProfile(profile.get())-> 198 StartDeferredTaskRunners(); 199 200 // Delete the Profile instance and run pending tasks (this includes the task 201 // for README creation). 202 profile.reset(); 203 content::RunAllPendingInMessageLoop(); 204 content::RunAllPendingInMessageLoop(content::BrowserThread::DB); 205 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE); 206} 207 208// Test that repeated setting of exit type is handled correctly. 209#if defined(OS_WIN) 210// Flaky on Windows: http://crbug.com/163713 211#define MAYBE_ExitType DISABLED_ExitType 212#else 213#define MAYBE_ExitType ExitType 214#endif 215IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, MAYBE_ExitType) { 216 base::ScopedTempDir temp_dir; 217 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 218 219 MockProfileDelegate delegate; 220 EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); 221 222 scoped_ptr<Profile> profile(Profile::CreateProfile( 223 temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS)); 224 ASSERT_TRUE(profile.get()); 225 StartupTaskRunnerServiceFactory::GetForProfile(profile.get())-> 226 StartDeferredTaskRunners(); 227 228 PrefService* prefs = profile->GetPrefs(); 229 // The initial state is crashed; store for later reference. 230 std::string crash_value(prefs->GetString(prefs::kSessionExitType)); 231 232 // The first call to a type other than crashed should change the value. 233 profile->SetExitType(Profile::EXIT_SESSION_ENDED); 234 std::string first_call_value(prefs->GetString(prefs::kSessionExitType)); 235 EXPECT_NE(crash_value, first_call_value); 236 237 // Subsequent calls to a non-crash value should be ignored. 238 profile->SetExitType(Profile::EXIT_NORMAL); 239 std::string second_call_value(prefs->GetString(prefs::kSessionExitType)); 240 EXPECT_EQ(first_call_value, second_call_value); 241 242 // Setting back to a crashed value should work. 243 profile->SetExitType(Profile::EXIT_CRASHED); 244 std::string final_value(prefs->GetString(prefs::kSessionExitType)); 245 EXPECT_EQ(crash_value, final_value); 246 247 // This test runs fast enough that the WebDataService may still be 248 // initializing (which uses the temp directory) when the test 249 // ends. Give it a chance to complete. 250 profile.reset(); 251 content::RunAllPendingInMessageLoop(); 252 content::RunAllPendingInMessageLoop(content::BrowserThread::DB); 253} 254