1 // Copyright (c) 2011 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 <string>
6
7 #include "base/command_line.h"
8 #include "base/memory/scoped_temp_dir.h"
9 #include "base/message_loop.h"
10 #include "base/path_service.h"
11 #include "chrome/browser/prefs/browser_prefs.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/test/testing_browser_process.h"
18 #include "chrome/test/testing_pref_service.h"
19 #include "content/browser/browser_thread.h"
20 #include "content/common/notification_service.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/base/system_monitor/system_monitor.h"
24
25 namespace {
26 // This global variable is used to check that value returned to different
27 // observers is the same.
28 Profile* g_created_profile;
29
30 } // namespace
31
32 class ProfileManagerTest : public testing::Test {
33 protected:
ProfileManagerTest()34 ProfileManagerTest()
35 : ui_thread_(BrowserThread::UI, &message_loop_),
36 file_thread_(BrowserThread::FILE, &message_loop_),
37 profile_manager_(new ProfileManagerWithoutInit) {
38 }
39
SetUp()40 virtual void SetUp() {
41 // Create a new temporary directory, and store the path
42 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
43
44 // Create a local_state PrefService.
45 browser::RegisterLocalState(&test_local_state_);
46 TestingBrowserProcess* testing_browser_process =
47 static_cast<TestingBrowserProcess*>(g_browser_process);
48 testing_browser_process->SetPrefService(&test_local_state_);
49 }
50
TearDown()51 virtual void TearDown() {
52 profile_manager_.reset();
53
54 TestingBrowserProcess* testing_browser_process =
55 static_cast<TestingBrowserProcess*>(g_browser_process);
56 testing_browser_process->SetPrefService(NULL);
57 }
58
59 class MockObserver : public ProfileManager::Observer {
60 public:
61 MOCK_METHOD1(OnProfileCreated, void(Profile* profile));
62 };
63
64 // The path to temporary directory used to contain the test operations.
65 ScopedTempDir temp_dir_;
66
67 MessageLoopForUI message_loop_;
68 BrowserThread ui_thread_;
69 BrowserThread file_thread_;
70
71 ui::SystemMonitor system_monitor_dummy_;
72
73 // Also will test profile deletion.
74 scoped_ptr<ProfileManager> profile_manager_;
75
76 TestingPrefService test_local_state_;
77 };
78
TEST_F(ProfileManagerTest,GetProfile)79 TEST_F(ProfileManagerTest, GetProfile) {
80 FilePath dest_path = temp_dir_.path();
81 dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));
82
83 Profile* profile;
84
85 // Successfully create a profile.
86 profile = profile_manager_->GetProfile(dest_path);
87 EXPECT_TRUE(profile);
88
89 // The profile already exists when we call GetProfile. Just load it.
90 EXPECT_EQ(profile, profile_manager_->GetProfile(dest_path));
91 }
92
TEST_F(ProfileManagerTest,DefaultProfileDir)93 TEST_F(ProfileManagerTest, DefaultProfileDir) {
94 CommandLine *cl = CommandLine::ForCurrentProcess();
95 std::string profile_dir("my_user");
96
97 cl->AppendSwitch(switches::kTestType);
98
99 FilePath expected_default =
100 FilePath().AppendASCII(chrome::kNotSignedInProfile);
101 EXPECT_EQ(expected_default.value(),
102 profile_manager_->GetCurrentProfileDir().value());
103 }
104
105 #if defined(OS_CHROMEOS)
106 // This functionality only exists on Chrome OS.
TEST_F(ProfileManagerTest,LoggedInProfileDir)107 TEST_F(ProfileManagerTest, LoggedInProfileDir) {
108 CommandLine *cl = CommandLine::ForCurrentProcess();
109 std::string profile_dir("my_user");
110
111 cl->AppendSwitchASCII(switches::kLoginProfile, profile_dir);
112 cl->AppendSwitch(switches::kTestType);
113
114 FilePath expected_default =
115 FilePath().AppendASCII(chrome::kNotSignedInProfile);
116 EXPECT_EQ(expected_default.value(),
117 profile_manager_->GetCurrentProfileDir().value());
118
119 profile_manager_->Observe(NotificationType::LOGIN_USER_CHANGED,
120 NotificationService::AllSources(),
121 NotificationService::NoDetails());
122 FilePath expected_logged_in(profile_dir);
123 EXPECT_EQ(expected_logged_in.value(),
124 profile_manager_->GetCurrentProfileDir().value());
125 VLOG(1) << temp_dir_.path().Append(
126 profile_manager_->GetCurrentProfileDir()).value();
127 }
128
129 #endif
130
TEST_F(ProfileManagerTest,CreateAndUseTwoProfiles)131 TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) {
132 FilePath dest_path1 = temp_dir_.path();
133 dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));
134
135 FilePath dest_path2 = temp_dir_.path();
136 dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2"));
137
138 Profile* profile1;
139 Profile* profile2;
140
141 // Successfully create the profiles.
142 profile1 = profile_manager_->GetProfile(dest_path1);
143 ASSERT_TRUE(profile1);
144
145 profile2 = profile_manager_->GetProfile(dest_path2);
146 ASSERT_TRUE(profile2);
147
148 // Force lazy-init of some profile services to simulate use.
149 EXPECT_TRUE(profile1->GetHistoryService(Profile::EXPLICIT_ACCESS));
150 EXPECT_TRUE(profile1->GetBookmarkModel());
151 EXPECT_TRUE(profile2->GetBookmarkModel());
152 EXPECT_TRUE(profile2->GetHistoryService(Profile::EXPLICIT_ACCESS));
153
154 // Make sure any pending tasks run before we destroy the profiles.
155 message_loop_.RunAllPending();
156
157 profile_manager_.reset();
158
159 // Make sure history cleans up correctly.
160 message_loop_.RunAllPending();
161 }
162
163 // Tests asynchronous profile creation mechanism.
TEST_F(ProfileManagerTest,CreateProfileAsync)164 TEST_F(ProfileManagerTest, CreateProfileAsync) {
165 FilePath dest_path =
166 temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile"));
167
168 MockObserver mock_observer;
169 EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(1);
170
171 profile_manager_->CreateProfileAsync(dest_path, &mock_observer);
172
173 message_loop_.RunAllPending();
174 }
175
176 MATCHER(SameNotNull, "The same non-NULL value for all cals.") {
177 if (!g_created_profile)
178 g_created_profile = arg;
179 return g_created_profile == arg;
180 }
181
TEST_F(ProfileManagerTest,CreateProfileAsyncMultipleRequests)182 TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) {
183 FilePath dest_path =
184 temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile"));
185
186 g_created_profile = NULL;
187
188 MockObserver mock_observer1;
189 EXPECT_CALL(mock_observer1, OnProfileCreated(SameNotNull())).Times(1);
190 MockObserver mock_observer2;
191 EXPECT_CALL(mock_observer2, OnProfileCreated(SameNotNull())).Times(1);
192 MockObserver mock_observer3;
193 EXPECT_CALL(mock_observer3, OnProfileCreated(SameNotNull())).Times(1);
194
195 profile_manager_->CreateProfileAsync(dest_path, &mock_observer1);
196 profile_manager_->CreateProfileAsync(dest_path, &mock_observer2);
197 profile_manager_->CreateProfileAsync(dest_path, &mock_observer3);
198
199 message_loop_.RunAllPending();
200 }
201
TEST_F(ProfileManagerTest,CreateProfilesAsync)202 TEST_F(ProfileManagerTest, CreateProfilesAsync) {
203 FilePath dest_path1 =
204 temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 1"));
205 FilePath dest_path2 =
206 temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 2"));
207
208 MockObserver mock_observer;
209 EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(2);
210
211 profile_manager_->CreateProfileAsync(dest_path1, &mock_observer);
212 profile_manager_->CreateProfileAsync(dest_path2, &mock_observer);
213
214 message_loop_.RunAllPending();
215 }
216