Home | History | Annotate | Download | only in profiles
      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 
     25 namespace {
     26 
     27 class 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.
     34 void 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 
     44 void 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 
     60 typedef 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
     66 IN_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
     85 IN_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
    105 IN_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
    130 IN_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
    154 IN_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.
    184 IN_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
    215 IN_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