Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / profiles / profile_browsertest.cc
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/prefs/pref_service.h"
10 #include "base/synchronization/waitable_event.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   std::string data("{}");
37   ASSERT_TRUE(base::WriteFile(pref_path, data.c_str(), data.size()));
38 }
39
40 scoped_ptr<Profile> CreateProfile(
41     const base::FilePath& path,
42     Profile::Delegate* delegate,
43     Profile::CreateMode create_mode) {
44   scoped_ptr<Profile> profile(Profile::CreateProfile(
45       path, delegate, create_mode));
46   EXPECT_TRUE(profile.get());
47   // This is necessary to avoid a memleak from BookmarkModel::Load.
48   // Unfortunately, this also results in warnings during debug runs.
49   StartupTaskRunnerServiceFactory::GetForProfile(profile.get())->
50       StartDeferredTaskRunners();
51   return profile.Pass();
52 }
53
54 void CheckChromeVersion(Profile *profile, bool is_new) {
55   std::string created_by_version;
56   if (is_new) {
57     chrome::VersionInfo version_info;
58     created_by_version = version_info.Version();
59   } else {
60     created_by_version = "1.0.0.0";
61   }
62   std::string pref_version =
63       ChromeVersionService::GetVersion(profile->GetPrefs());
64   // Assert that created_by_version pref gets set to current version.
65   EXPECT_EQ(created_by_version, pref_version);
66 }
67
68 void BlockThread(
69     base::WaitableEvent* is_blocked,
70     base::WaitableEvent* unblock) {
71   is_blocked->Signal();
72   unblock->Wait();
73 }
74
75 void SpinThreads() {
76   // Give threads a chance to do their stuff before shutting down (i.e.
77   // deleting scoped temp dir etc).
78   // Should not be necessary anymore once Profile deletion is fixed
79   // (see crbug.com/88586).
80   content::RunAllPendingInMessageLoop();
81   content::RunAllPendingInMessageLoop(content::BrowserThread::DB);
82   content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
83 }
84
85 }  // namespace
86
87 typedef InProcessBrowserTest ProfileBrowserTest;
88
89 // Test OnProfileCreate is called with is_new_profile set to true when
90 // creating a new profile synchronously.
91 //
92 // Flaky (sometimes timeout): http://crbug.com/141141
93 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
94                        DISABLED_CreateNewProfileSynchronous) {
95   base::ScopedTempDir temp_dir;
96   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
97
98   MockProfileDelegate delegate;
99   EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
100
101   {
102     scoped_ptr<Profile> profile(CreateProfile(
103         temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
104     CheckChromeVersion(profile.get(), true);
105   }
106
107   SpinThreads();
108 }
109
110 // Test OnProfileCreate is called with is_new_profile set to false when
111 // creating a profile synchronously with an existing prefs file.
112 // Flaky: http://crbug.com/141517
113 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
114                        DISABLED_CreateOldProfileSynchronous) {
115   base::ScopedTempDir temp_dir;
116   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
117   CreatePrefsFileInDirectory(temp_dir.path());
118
119   MockProfileDelegate delegate;
120   EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, false));
121
122   {
123     scoped_ptr<Profile> profile(CreateProfile(
124         temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
125     CheckChromeVersion(profile.get(), false);
126   }
127
128   SpinThreads();
129 }
130
131 // Test OnProfileCreate is called with is_new_profile set to true when
132 // creating a new profile asynchronously.
133 // This test is flaky on Linux, Win and Mac.  See crbug.com/142787
134 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
135                        DISABLED_CreateNewProfileAsynchronous) {
136   base::ScopedTempDir temp_dir;
137   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
138
139   MockProfileDelegate delegate;
140   EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
141
142   {
143     content::WindowedNotificationObserver observer(
144         chrome::NOTIFICATION_PROFILE_CREATED,
145         content::NotificationService::AllSources());
146
147     scoped_ptr<Profile> profile(CreateProfile(
148         temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS));
149
150     // Wait for the profile to be created.
151     observer.Wait();
152     CheckChromeVersion(profile.get(), true);
153   }
154
155   SpinThreads();
156 }
157
158 // Test OnProfileCreate is called with is_new_profile set to false when
159 // creating a profile asynchronously with an existing prefs file.
160 // Flaky: http://crbug.com/141517
161 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
162                        DISABLED_CreateOldProfileAsynchronous) {
163   base::ScopedTempDir temp_dir;
164   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
165   CreatePrefsFileInDirectory(temp_dir.path());
166
167   MockProfileDelegate delegate;
168   EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, false));
169
170   {
171     content::WindowedNotificationObserver observer(
172         chrome::NOTIFICATION_PROFILE_CREATED,
173         content::NotificationService::AllSources());
174
175     scoped_ptr<Profile> profile(CreateProfile(
176         temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS));
177
178     // Wait for the profile to be created.
179     observer.Wait();
180     CheckChromeVersion(profile.get(), false);
181   }
182
183   SpinThreads();
184 }
185
186 // Test that a README file is created for profiles that didn't have it.
187 // Flaky: http://crbug.com/140882
188 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DISABLED_ProfileReadmeCreated) {
189   base::ScopedTempDir temp_dir;
190   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
191
192   MockProfileDelegate delegate;
193   EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
194
195   // No delay before README creation.
196   ProfileImpl::create_readme_delay_ms = 0;
197
198   {
199     content::WindowedNotificationObserver observer(
200         chrome::NOTIFICATION_PROFILE_CREATED,
201         content::NotificationService::AllSources());
202
203     scoped_ptr<Profile> profile(CreateProfile(
204         temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS));
205
206     // Wait for the profile to be created.
207     observer.Wait();
208
209     // Wait for file thread to create the README.
210     content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
211
212     // Verify that README exists.
213     EXPECT_TRUE(base::PathExists(
214         temp_dir.path().Append(chrome::kReadmeFilename)));
215   }
216
217   SpinThreads();
218 }
219
220 // Test that Profile can be deleted before README file is created.
221 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ProfileDeletedBeforeReadmeCreated) {
222   base::ScopedTempDir temp_dir;
223   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
224
225   MockProfileDelegate delegate;
226   EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
227
228   // No delay before README creation.
229   ProfileImpl::create_readme_delay_ms = 0;
230
231   base::WaitableEvent is_blocked(false, false);
232   base::WaitableEvent* unblock = new base::WaitableEvent(false, false);
233
234   // Block file thread.
235   content::BrowserThread::PostTask(
236       content::BrowserThread::FILE, FROM_HERE,
237       base::Bind(&BlockThread, &is_blocked, base::Owned(unblock)));
238   // Wait for file thread to actually be blocked.
239   is_blocked.Wait();
240
241   scoped_ptr<Profile> profile(CreateProfile(
242       temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
243
244   // Delete the Profile instance before we give the file thread a chance to
245   // create the README.
246   profile.reset();
247
248   // Now unblock the file thread again and run pending tasks (this includes the
249   // task for README creation).
250   unblock->Signal();
251
252   SpinThreads();
253 }
254
255 // Test that repeated setting of exit type is handled correctly.
256 #if defined(OS_WIN)
257 // Flaky on Windows: http://crbug.com/163713
258 #define MAYBE_ExitType DISABLED_ExitType
259 #else
260 #define MAYBE_ExitType ExitType
261 #endif
262 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, MAYBE_ExitType) {
263   base::ScopedTempDir temp_dir;
264   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
265
266   MockProfileDelegate delegate;
267   EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
268   {
269     scoped_ptr<Profile> profile(CreateProfile(
270         temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
271
272     PrefService* prefs = profile->GetPrefs();
273     // The initial state is crashed; store for later reference.
274     std::string crash_value(prefs->GetString(prefs::kSessionExitType));
275
276     // The first call to a type other than crashed should change the value.
277     profile->SetExitType(Profile::EXIT_SESSION_ENDED);
278     std::string first_call_value(prefs->GetString(prefs::kSessionExitType));
279     EXPECT_NE(crash_value, first_call_value);
280
281     // Subsequent calls to a non-crash value should be ignored.
282     profile->SetExitType(Profile::EXIT_NORMAL);
283     std::string second_call_value(prefs->GetString(prefs::kSessionExitType));
284     EXPECT_EQ(first_call_value, second_call_value);
285
286     // Setting back to a crashed value should work.
287     profile->SetExitType(Profile::EXIT_CRASHED);
288     std::string final_value(prefs->GetString(prefs::kSessionExitType));
289     EXPECT_EQ(crash_value, final_value);
290   }
291
292   SpinThreads();
293 }