15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/command_line.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/json/json_reader.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/metrics/field_trial.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/sequenced_task_runner.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/synchronization/waitable_event.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/values.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/browser_process.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/chrome_version_service.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_impl.h"
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/profiles/profile_manager.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/startup_task_runner_service.h"
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/startup_task_runner_service_factory.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chromeos/chromeos_switches.h"
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockProfileDelegate : public Profile::Delegate {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MOCK_METHOD1(OnPrefsLoaded, void(Profile*));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD3(OnProfileCreated, void(Profile*, bool, bool));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a prefs file in the given directory.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CreatePrefsFileInDirectory(const base::FilePath& directory_path) {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath pref_path(directory_path.Append(chrome::kPreferencesFilename));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data("{}");
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(base::WriteFile(pref_path, data.c_str(), data.size()));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CheckChromeVersion(Profile *profile, bool is_new) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string created_by_version;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_new) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::VersionInfo version_info;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    created_by_version = version_info.Version();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    created_by_version = "1.0.0.0";
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string pref_version =
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChromeVersionService::GetVersion(profile->GetPrefs());
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assert that created_by_version pref gets set to current version.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(created_by_version, pref_version);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid BlockThread(
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::WaitableEvent* is_blocked,
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::WaitableEvent* unblock) {
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  is_blocked->Signal();
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  unblock->Wait();
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FlushTaskRunner(base::SequencedTaskRunner* runner) {
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(runner);
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::WaitableEvent unblock(false, false);
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  runner->PostTask(FROM_HERE,
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&base::WaitableEvent::Signal, base::Unretained(&unblock)));
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  unblock.Wait();
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid SpinThreads() {
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Give threads a chance to do their stuff before shutting down (i.e.
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // deleting scoped temp dir etc).
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Should not be necessary anymore once Profile deletion is fixed
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // (see crbug.com/88586).
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  content::RunAllPendingInMessageLoop();
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  content::RunAllPendingInMessageLoop(content::BrowserThread::DB);
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ProfileBrowserTest : public InProcessBrowserTest {
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) protected:
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    command_line->AppendSwitch(
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        chromeos::switches::kIgnoreUserProfileMappingForTests);
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<Profile> CreateProfile(
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const base::FilePath& path,
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      Profile::Delegate* delegate,
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      Profile::CreateMode create_mode) {
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<Profile> profile(Profile::CreateProfile(
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        path, delegate, create_mode));
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_TRUE(profile.get());
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Store the Profile's IO task runner so we can wind it down.
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    profile_io_task_runner_ = profile->GetIOTaskRunner();
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return profile.Pass();
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void FlushIoTaskRunnerAndSpinThreads() {
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FlushTaskRunner(profile_io_task_runner_.get());
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpinThreads();
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<base::SequencedTaskRunner> profile_io_task_runner_;
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test OnProfileCreate is called with is_new_profile set to true when
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creating a new profile synchronously.
127116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(ProfileBrowserTest, CreateNewProfileSynchronous) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProfileDelegate delegate;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<Profile> profile(CreateProfile(
1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CheckChromeVersion(profile.get(), true);
1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushIoTaskRunnerAndSpinThreads();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test OnProfileCreate is called with is_new_profile set to false when
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creating a profile synchronously with an existing prefs file.
145116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(ProfileBrowserTest, CreateOldProfileSynchronous) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreatePrefsFileInDirectory(temp_dir.path());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProfileDelegate delegate;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, false));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<Profile> profile(CreateProfile(
1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CheckChromeVersion(profile.get(), false);
1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushIoTaskRunnerAndSpinThreads();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Flaky: http://crbug.com/393177
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test OnProfileCreate is called with is_new_profile set to true when
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creating a new profile asynchronously.
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       DISABLED_CreateNewProfileAsynchronous) {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProfileDelegate delegate;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    content::WindowedNotificationObserver observer(
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        chrome::NOTIFICATION_PROFILE_CREATED,
1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        content::NotificationService::AllSources());
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<Profile> profile(CreateProfile(
1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS));
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Wait for the profile to be created.
1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    observer.Wait();
1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CheckChromeVersion(profile.get(), true);
1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushIoTaskRunnerAndSpinThreads();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Flaky: http://crbug.com/393177
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test OnProfileCreate is called with is_new_profile set to false when
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creating a profile asynchronously with an existing prefs file.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       DISABLED_CreateOldProfileAsynchronous) {
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreatePrefsFileInDirectory(temp_dir.path());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProfileDelegate delegate;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, false));
2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    content::WindowedNotificationObserver observer(
2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        chrome::NOTIFICATION_PROFILE_CREATED,
2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        content::NotificationService::AllSources());
2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<Profile> profile(CreateProfile(
2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS));
2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Wait for the profile to be created.
2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    observer.Wait();
2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CheckChromeVersion(profile.get(), false);
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushIoTaskRunnerAndSpinThreads();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Flaky: http://crbug.com/393177
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a README file is created for profiles that didn't have it.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DISABLED_ProfileReadmeCreated) {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProfileDelegate delegate;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No delay before README creation.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProfileImpl::create_readme_delay_ms = 0;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
2315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    content::WindowedNotificationObserver observer(
2325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        chrome::NOTIFICATION_PROFILE_CREATED,
2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        content::NotificationService::AllSources());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<Profile> profile(CreateProfile(
2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        temp_dir.path(), &delegate, Profile::CREATE_MODE_ASYNCHRONOUS));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Wait for the profile to be created.
2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    observer.Wait();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Wait for file thread to create the README.
2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Verify that README exists.
2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_TRUE(base::PathExists(
2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        temp_dir.path().Append(chrome::kReadmeFilename)));
2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushIoTaskRunnerAndSpinThreads();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Profile can be deleted before README file is created.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ProfileDeletedBeforeReadmeCreated) {
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProfileDelegate delegate;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No delay before README creation.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProfileImpl::create_readme_delay_ms = 0;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::WaitableEvent is_blocked(false, false);
2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::WaitableEvent* unblock = new base::WaitableEvent(false, false);
2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Block file thread.
2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  content::BrowserThread::PostTask(
2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      content::BrowserThread::FILE, FROM_HERE,
2695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      base::Bind(&BlockThread, &is_blocked, base::Owned(unblock)));
2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Wait for file thread to actually be blocked.
2715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  is_blocked.Wait();
2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<Profile> profile(CreateProfile(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Delete the Profile instance before we give the file thread a chance to
2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // create the README.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile.reset();
2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Now unblock the file thread again and run pending tasks (this includes the
2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // task for README creation).
2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  unblock->Signal();
2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushIoTaskRunnerAndSpinThreads();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that repeated setting of exit type is handled correctly.
288116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ExitType) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProfileDelegate delegate;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<Profile> profile(CreateProfile(
2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    PrefService* prefs = profile->GetPrefs();
2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // The initial state is crashed; store for later reference.
3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string crash_value(prefs->GetString(prefs::kSessionExitType));
3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // The first call to a type other than crashed should change the value.
3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    profile->SetExitType(Profile::EXIT_SESSION_ENDED);
3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string first_call_value(prefs->GetString(prefs::kSessionExitType));
3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_NE(crash_value, first_call_value);
3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Subsequent calls to a non-crash value should be ignored.
3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    profile->SetExitType(Profile::EXIT_NORMAL);
3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string second_call_value(prefs->GetString(prefs::kSessionExitType));
3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(first_call_value, second_call_value);
3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Setting back to a crashed value should work.
3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    profile->SetExitType(Profile::EXIT_CRASHED);
3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string final_value(prefs->GetString(prefs::kSessionExitType));
3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(crash_value, final_value);
3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FlushIoTaskRunnerAndSpinThreads();
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// The EndSession IO synchronization is only critical on Windows, but also
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// happens under the USE_X11 define. See BrowserProcessImpl::EndSession.
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(USE_X11) || defined(OS_WIN)
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstd::string GetExitTypePreferenceFromDisk(Profile* profile) {
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::FilePath prefs_path =
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      profile->GetPath().Append(chrome::kPreferencesFilename);
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string prefs;
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!base::ReadFileToString(prefs_path, &prefs))
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return std::string();
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<base::Value> value(base::JSONReader::Read(prefs));
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!value)
336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return std::string();
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::DictionaryValue* dict = NULL;
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!value->GetAsDictionary(&dict) || !dict)
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return std::string();
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string exit_type;
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!dict->GetString("profile.exit_type", &exit_type))
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return std::string();
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return exit_type;
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
351116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       WritesProfilesSynchronouslyOnEndSession) {
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::ScopedTempDir temp_dir;
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ProfileManager* profile_manager = g_browser_process->profile_manager();
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(profile_manager);
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<Profile*> loaded_profiles = profile_manager->GetLoadedProfiles();
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_NE(loaded_profiles.size(), 0UL);
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Profile* profile = loaded_profiles[0];
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This retry loop reduces flakiness due to the fact that this ultimately
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // tests whether or not a code path hits a timed wait.
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool succeeded = false;
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (size_t retries = 0; !succeeded && retries < 3; ++retries) {
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Flush the profile data to disk for all loaded profiles.
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    profile->SetExitType(Profile::EXIT_CRASHED);
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FlushTaskRunner(profile->GetIOTaskRunner().get());
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Make sure that the prefs file was written with the expected key/value.
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_EQ(GetExitTypePreferenceFromDisk(profile), "Crashed");
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The blocking wait in EndSession has a timeout.
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::Time start = base::Time::Now();
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // This must not return until the profile data has been written to disk.
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If this test flakes, then logoff on Windows has broken again.
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    g_browser_process->EndSession();
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::Time end = base::Time::Now();
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The EndSession timeout is 10 seconds. If we take more than half that,
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // go around again, as we may have timed out on the wait.
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // This helps against flakes, and also ensures that if the IO thread starts
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // blocking systemically for that length of time (e.g. deadlocking or such),
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // we'll get a consistent test failure.
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (end - start > base::TimeDelta::FromSeconds(5))
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Make sure that the prefs file was written with the expected key/value.
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_EQ(GetExitTypePreferenceFromDisk(profile), "SessionEnded");
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Mark the success.
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    succeeded = true;
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(succeeded) << "profile->EndSession() timed out too often.";
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
401116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(ProfileBrowserTest,
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       EndSessionBrokenSynchronizationExperiment) {
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::ScopedTempDir temp_dir;
404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Select into the field trial group.
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::FieldTrialList::CreateFieldTrial("WindowsLogoffRace",
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                         "BrokenSynchronization");
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ProfileManager* profile_manager = g_browser_process->profile_manager();
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(profile_manager);
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<Profile*> loaded_profiles = profile_manager->GetLoadedProfiles();
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_NE(loaded_profiles.size(), 0UL);
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Profile* profile = loaded_profiles[0];
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool mis_wrote = false;
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This retry loop reduces flakiness due to the fact that this ultimately
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // tests whether or not a code path hits a timed wait.
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (size_t retries = 0; retries < 3; ++retries) {
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Flush the profile data to disk for all loaded profiles.
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    profile->SetExitType(Profile::EXIT_CRASHED);
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FlushTaskRunner(profile->GetIOTaskRunner().get());
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Make sure that the prefs file was written with the expected key/value.
426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_EQ(GetExitTypePreferenceFromDisk(profile), "Crashed");
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::WaitableEvent is_blocked(false, false);
429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::WaitableEvent* unblock = new base::WaitableEvent(false, false);
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Block the profile's IO thread.
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    profile->GetIOTaskRunner()->PostTask(FROM_HERE,
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&BlockThread, &is_blocked, base::Owned(unblock)));
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Wait for the IO thread to actually be blocked.
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    is_blocked.Wait();
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The blocking wait in EndSession has a timeout, so a non-write can only be
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // concluded if it happens in less time than the timeout.
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::Time start = base::Time::Now();
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // With the broken synchronization this is expected to return without
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // blocking for the Profile's IO thread.
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    g_browser_process->EndSession();
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::Time end = base::Time::Now();
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The EndSession timeout is 10 seconds, we take a 5 second run-through as
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // sufficient proof that we didn't hit the timed wait.
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (end - start < base::TimeDelta::FromSeconds(5)) {
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Make sure that the prefs file is unmodified with the expected
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // key/value.
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      EXPECT_EQ(GetExitTypePreferenceFromDisk(profile), "Crashed");
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      mis_wrote = true;
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Release the IO thread thread.
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    unblock->Signal();
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(mis_wrote);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // defined(USE_X11) || defined(OS_WIN)
464