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