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/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 
     23 namespace {
     24 
     25 class 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.
     31 void 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 
     41 void 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 
     57 typedef 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
     63 IN_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
     80 IN_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
     98 IN_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
    121 IN_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
    143 IN_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.
    171 IN_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
    200 IN_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