OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ | 5 #ifndef CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ |
6 #define CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ | 6 #define CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "chrome/browser/profile.h" | 12 #include "chrome/browser/profile.h" |
13 #include "chrome/browser/sync/engine/syncapi.h" | 13 #include "chrome/browser/sync/engine/syncapi.h" |
14 #include "chrome/browser/sync/profile_sync_factory.h" | 14 #include "chrome/browser/sync/profile_sync_factory.h" |
15 #include "chrome/browser/sync/profile_sync_service.h" | 15 #include "chrome/browser/sync/profile_sync_service.h" |
16 #include "chrome/browser/sync/glue/data_type_controller.h" | 16 #include "chrome/browser/sync/glue/data_type_controller.h" |
17 #include "chrome/browser/sync/glue/data_type_manager_impl.h" | 17 #include "chrome/browser/sync/glue/data_type_manager_impl.h" |
18 #include "chrome/browser/sync/glue/sync_backend_host.h" | 18 #include "chrome/browser/sync/glue/sync_backend_host.h" |
19 #include "chrome/browser/sync/sessions/session_state.h" | 19 #include "chrome/browser/sync/sessions/session_state.h" |
20 #include "chrome/browser/sync/syncable/directory_manager.h" | 20 #include "chrome/browser/sync/syncable/directory_manager.h" |
21 #include "chrome/browser/sync/syncable/syncable.h" | 21 #include "chrome/browser/sync/syncable/syncable.h" |
22 #include "chrome/common/notification_service.h" | 22 #include "chrome/common/notification_service.h" |
23 #include "chrome/test/profile_mock.h" | 23 #include "chrome/test/profile_mock.h" |
24 #include "chrome/test/sync/test_http_bridge_factory.h" | 24 #include "chrome/test/sync/test_http_bridge_factory.h" |
| 25 #include "chrome/test/sync/engine/test_id_factory.h" |
25 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
26 | 27 |
27 using browser_sync::ModelSafeRoutingInfo; | 28 using browser_sync::ModelSafeRoutingInfo; |
28 using browser_sync::sessions::ErrorCounters; | 29 using browser_sync::sessions::ErrorCounters; |
29 using browser_sync::sessions::SyncerStatus; | 30 using browser_sync::sessions::SyncerStatus; |
30 using browser_sync::sessions::SyncSessionSnapshot; | 31 using browser_sync::sessions::SyncSessionSnapshot; |
31 using sync_api::UserShare; | 32 using sync_api::UserShare; |
32 using syncable::DirectoryManager; | 33 using syncable::DirectoryManager; |
33 using syncable::ModelType; | 34 using syncable::ModelType; |
34 using syncable::ScopedDirLookup; | 35 using syncable::ScopedDirLookup; |
35 | 36 |
| 37 class TestProfileSyncService; |
| 38 |
36 ACTION_P(CallOnPaused, core) { | 39 ACTION_P(CallOnPaused, core) { |
37 core->OnPaused(); | 40 core->OnPaused(); |
38 }; | 41 }; |
39 | 42 |
40 ACTION_P(CallOnResumed, core) { | 43 ACTION_P(CallOnResumed, core) { |
41 core->OnResumed(); | 44 core->OnResumed(); |
42 } | 45 } |
43 | 46 |
44 ACTION(ReturnNewDataTypeManager) { | 47 ACTION(ReturnNewDataTypeManager) { |
45 return new browser_sync::DataTypeManagerImpl(arg0, arg1); | 48 return new browser_sync::DataTypeManagerImpl(arg0, arg1); |
46 } | 49 } |
47 | 50 |
48 namespace browser_sync { | 51 namespace browser_sync { |
49 | 52 |
50 // Mocks out the SyncerThread operations (Pause/Resume) since no thread is | 53 // Mocks out the SyncerThread operations (Pause/Resume) since no thread is |
51 // running in these tests, and allows tests to provide a task on construction | 54 // running in these tests, and allows tests to provide a task on construction |
52 // to set up initial nodes to mock out an actual server initial sync | 55 // to set up initial nodes to mock out an actual server initial sync |
53 // download. | 56 // download. |
54 class SyncBackendHostForProfileSyncTest : public SyncBackendHost { | 57 class SyncBackendHostForProfileSyncTest : public SyncBackendHost { |
55 public: | 58 public: |
56 // |initial_condition_setup_task| can be used to populate nodes before the | 59 // |initial_condition_setup_task| can be used to populate nodes before the |
57 // OnBackendInitialized callback fires. | 60 // OnBackendInitialized callback fires. |
58 // |set_initial_sync_ended_on_init| determines whether we pretend that a full | 61 // |set_initial_sync_ended_on_init| determines whether we pretend that a full |
59 // initial download has occurred and set bits for enabled data types. If | 62 // initial download has occurred and set bits for enabled data types. If |
60 // this is false, configuring data types will require a syncer nudge. | 63 // this is false, configuring data types will require a syncer nudge. |
61 // |synchronous_init| causes initialization to block until the syncapi has | 64 // |synchronous_init| causes initialization to block until the syncapi has |
62 // completed setting itself up and called us back. | 65 // completed setting itself up and called us back. |
63 SyncBackendHostForProfileSyncTest(SyncFrontend* frontend, | 66 SyncBackendHostForProfileSyncTest(TestProfileSyncService* service, |
64 Profile* profile, | 67 Profile* profile, |
65 const FilePath& profile_path, | 68 const FilePath& profile_path, |
66 const DataTypeController::TypeMap& data_type_controllers, | 69 const DataTypeController::TypeMap& data_type_controllers, |
67 Task* initial_condition_setup_task, | 70 Task* initial_condition_setup_task, |
68 int num_expected_resumes, | 71 int num_expected_resumes, |
69 int num_expected_pauses, | 72 int num_expected_pauses, |
70 bool set_initial_sync_ended_on_init, | 73 bool set_initial_sync_ended_on_init, |
71 bool synchronous_init) | 74 bool synchronous_init); |
72 : browser_sync::SyncBackendHost(frontend, profile, profile_path, | |
73 data_type_controllers), | |
74 initial_condition_setup_task_(initial_condition_setup_task), | |
75 set_initial_sync_ended_on_init_(set_initial_sync_ended_on_init), | |
76 synchronous_init_(synchronous_init) { | |
77 // By default, the RequestPause and RequestResume methods will | |
78 // send the confirmation notification and return true. | |
79 ON_CALL(*this, RequestPause()). | |
80 WillByDefault(testing::DoAll(CallOnPaused(core_), | |
81 testing::Return(true))); | |
82 ON_CALL(*this, RequestResume()). | |
83 WillByDefault(testing::DoAll(CallOnResumed(core_), | |
84 testing::Return(true))); | |
85 ON_CALL(*this, RequestNudge()).WillByDefault(testing::Invoke(this, | |
86 &SyncBackendHostForProfileSyncTest:: | |
87 SimulateSyncCycleCompletedInitialSyncEnded)); | |
88 | |
89 EXPECT_CALL(*this, RequestPause()).Times(num_expected_pauses); | |
90 EXPECT_CALL(*this, RequestResume()).Times(num_expected_resumes); | |
91 EXPECT_CALL(*this, RequestNudge()). | |
92 Times(set_initial_sync_ended_on_init ? 0 : 1); | |
93 } | |
94 | 75 |
95 MOCK_METHOD0(RequestPause, bool()); | 76 MOCK_METHOD0(RequestPause, bool()); |
96 MOCK_METHOD0(RequestResume, bool()); | 77 MOCK_METHOD0(RequestResume, bool()); |
97 MOCK_METHOD0(RequestNudge, void()); | 78 MOCK_METHOD0(RequestNudge, void()); |
98 | 79 |
99 void SetInitialSyncEndedForEnabledTypes() { | 80 void SetInitialSyncEndedForEnabledTypes(); |
100 UserShare* user_share = core_->syncapi()->GetUserShare(); | |
101 DirectoryManager* dir_manager = user_share->dir_manager.get(); | |
102 | 81 |
103 ScopedDirLookup dir(dir_manager, user_share->name); | 82 virtual void HandleInitializationCompletedOnFrontendLoop(); |
104 if (!dir.good()) | |
105 FAIL(); | |
106 | |
107 ModelSafeRoutingInfo enabled_types; | |
108 GetModelSafeRoutingInfo(&enabled_types); | |
109 for (ModelSafeRoutingInfo::const_iterator i = enabled_types.begin(); | |
110 i != enabled_types.end(); ++i) { | |
111 dir->set_initial_sync_ended_for_type(i->first, true); | |
112 } | |
113 } | |
114 | |
115 virtual void HandleInitializationCompletedOnFrontendLoop() { | |
116 set_syncapi_initialized(); // Need to do this asap so task below works. | |
117 | |
118 // Set up any nodes the test wants around before model association. | |
119 if (initial_condition_setup_task_) { | |
120 initial_condition_setup_task_->Run(); | |
121 } | |
122 | |
123 // Pretend we downloaded initial updates and set initial sync ended bits | |
124 // if we were asked to. | |
125 if (set_initial_sync_ended_on_init_) | |
126 SetInitialSyncEndedForEnabledTypes(); | |
127 | |
128 SyncBackendHost::HandleInitializationCompletedOnFrontendLoop(); | |
129 } | |
130 | 83 |
131 // Called when a nudge comes in. | 84 // Called when a nudge comes in. |
132 void SimulateSyncCycleCompletedInitialSyncEnded() { | 85 void SimulateSyncCycleCompletedInitialSyncEnded(); |
133 syncable::ModelTypeBitSet sync_ended; | |
134 ModelSafeRoutingInfo enabled_types; | |
135 GetModelSafeRoutingInfo(&enabled_types); | |
136 for (ModelSafeRoutingInfo::const_iterator i = enabled_types.begin(); | |
137 i != enabled_types.end(); ++i) { | |
138 sync_ended.set(i->first); | |
139 } | |
140 core_->HandleSyncCycleCompletedOnFrontendLoop(new SyncSessionSnapshot( | |
141 SyncerStatus(), ErrorCounters(), 0, 0, false, | |
142 sync_ended, false, false, 0, 0, false)); | |
143 } | |
144 | 86 |
145 virtual sync_api::HttpPostProviderFactory* MakeHttpBridgeFactory( | 87 virtual sync_api::HttpPostProviderFactory* MakeHttpBridgeFactory( |
146 URLRequestContextGetter* getter) { | 88 URLRequestContextGetter* getter) { |
147 return new browser_sync::TestHttpBridgeFactory; | 89 return new browser_sync::TestHttpBridgeFactory; |
148 } | 90 } |
149 | 91 |
150 virtual void InitCore(const Core::DoInitializeOptions& options) { | 92 virtual void InitCore(const Core::DoInitializeOptions& options); |
151 std::wstring user = L"testuser"; | |
152 core_loop()->PostTask(FROM_HERE, | |
153 NewRunnableMethod(core_.get(), | |
154 &SyncBackendHost::Core::DoInitializeForTest, | |
155 user, | |
156 options.http_bridge_factory, | |
157 options.delete_sync_data_folder)); | |
158 | 93 |
159 // TODO(akalin): Figure out a better way to do this. | 94 static void SetDefaultExpectationsForWorkerCreation(ProfileMock* profile); |
160 if (synchronous_init_) { | |
161 // The SyncBackend posts a task to the current loop when | |
162 // initialization completes. | |
163 MessageLoop::current()->Run(); | |
164 } | |
165 } | |
166 | |
167 static void SetDefaultExpectationsForWorkerCreation(ProfileMock* profile) { | |
168 EXPECT_CALL(*profile, GetPasswordStore(testing::_)). | |
169 WillOnce(testing::Return((PasswordStore*)NULL)); | |
170 EXPECT_CALL(*profile, GetHistoryService(testing::_)). | |
171 WillOnce(testing::Return((HistoryService*)NULL)); | |
172 } | |
173 | 95 |
174 private: | 96 private: |
175 Task* initial_condition_setup_task_; | 97 Task* initial_condition_setup_task_; |
176 bool set_initial_sync_ended_on_init_; | 98 bool set_initial_sync_ended_on_init_; |
177 bool synchronous_init_; | 99 bool synchronous_init_; |
178 | 100 TestProfileSyncService* test_service_; |
179 }; | 101 }; |
180 | 102 |
181 } // namespace browser_sync | 103 } // namespace browser_sync |
182 | 104 |
183 class TestProfileSyncService : public ProfileSyncService { | 105 class TestProfileSyncService : public ProfileSyncService { |
184 public: | 106 public: |
185 TestProfileSyncService(ProfileSyncFactory* factory, | 107 TestProfileSyncService(ProfileSyncFactory* factory, |
186 Profile* profile, | 108 Profile* profile, |
187 const std::string& test_user, | 109 const std::string& test_user, |
188 bool synchronous_backend_initialization, | 110 bool synchronous_backend_initialization, |
189 Task* initial_condition_setup_task) | 111 Task* initial_condition_setup_task); |
190 : ProfileSyncService(factory, profile, | |
191 !test_user.empty() ? | |
192 test_user : ""), | |
193 synchronous_backend_initialization_( | |
194 synchronous_backend_initialization), | |
195 synchronous_sync_configuration_(false), | |
196 num_expected_resumes_(1), | |
197 num_expected_pauses_(1), | |
198 initial_condition_setup_task_(initial_condition_setup_task), | |
199 set_initial_sync_ended_on_init_(true) { | |
200 RegisterPreferences(); | |
201 SetSyncSetupCompleted(); | |
202 } | |
203 virtual ~TestProfileSyncService() { } | 112 virtual ~TestProfileSyncService() { } |
204 | 113 |
205 virtual void CreateBackend() { | 114 virtual void CreateBackend(); |
206 backend_.reset(new browser_sync::SyncBackendHostForProfileSyncTest( | |
207 this, profile(), | |
208 profile()->GetPath(), data_type_controllers(), | |
209 initial_condition_setup_task_.release(), | |
210 num_expected_resumes_, num_expected_pauses_, | |
211 set_initial_sync_ended_on_init_, | |
212 synchronous_backend_initialization_)); | |
213 } | |
214 | 115 |
215 virtual void OnBackendInitialized() { | 116 virtual void OnBackendInitialized(); |
216 ProfileSyncService::OnBackendInitialized(); | |
217 // TODO(akalin): Figure out a better way to do this. | |
218 if (synchronous_backend_initialization_) { | |
219 MessageLoop::current()->Quit(); | |
220 } | |
221 } | |
222 | 117 |
223 virtual void Observe(NotificationType type, | 118 virtual void Observe(NotificationType type, |
224 const NotificationSource& source, | 119 const NotificationSource& source, |
225 const NotificationDetails& details) { | 120 const NotificationDetails& details); |
226 ProfileSyncService::Observe(type, source, details); | |
227 if (type == NotificationType::SYNC_CONFIGURE_DONE && | |
228 !synchronous_sync_configuration_) { | |
229 MessageLoop::current()->Quit(); | |
230 } | |
231 } | |
232 | 121 |
233 void set_num_expected_resumes(int times) { | 122 void set_num_expected_resumes(int times) { |
234 num_expected_resumes_ = times; | 123 num_expected_resumes_ = times; |
235 } | 124 } |
236 void set_num_expected_pauses(int num) { | 125 void set_num_expected_pauses(int num) { |
237 num_expected_pauses_ = num; | 126 num_expected_pauses_ = num; |
238 } | 127 } |
239 void dont_set_initial_sync_ended_on_init() { | 128 void dont_set_initial_sync_ended_on_init() { |
240 set_initial_sync_ended_on_init_ = false; | 129 set_initial_sync_ended_on_init_ = false; |
241 } | 130 } |
242 void set_synchronous_sync_configuration() { | 131 void set_synchronous_sync_configuration() { |
243 synchronous_sync_configuration_ = true; | 132 synchronous_sync_configuration_ = true; |
244 } | 133 } |
245 | 134 |
| 135 browser_sync::TestIdFactory* id_factory() { return &id_factory_; } |
| 136 |
246 private: | 137 private: |
247 // When testing under ChromiumOS, this method must not return an empty | 138 // When testing under ChromiumOS, this method must not return an empty |
248 // value value in order for the profile sync service to start. | 139 // value value in order for the profile sync service to start. |
249 virtual std::string GetLsidForAuthBootstraping() { | 140 virtual std::string GetLsidForAuthBootstraping() { |
250 return "foo"; | 141 return "foo"; |
251 } | 142 } |
252 | 143 |
253 bool synchronous_backend_initialization_; | 144 bool synchronous_backend_initialization_; |
254 | 145 |
255 // Set to true when a mock data type manager is being used and the configure | 146 // Set to true when a mock data type manager is being used and the configure |
256 // step is performed synchronously. | 147 // step is performed synchronously. |
257 bool synchronous_sync_configuration_; | 148 bool synchronous_sync_configuration_; |
258 bool set_expect_resume_expectations_; | 149 bool set_expect_resume_expectations_; |
259 int num_expected_resumes_; | 150 int num_expected_resumes_; |
260 int num_expected_pauses_; | 151 int num_expected_pauses_; |
261 | 152 |
262 scoped_ptr<Task> initial_condition_setup_task_; | 153 scoped_ptr<Task> initial_condition_setup_task_; |
263 bool set_initial_sync_ended_on_init_; | 154 bool set_initial_sync_ended_on_init_; |
| 155 browser_sync::TestIdFactory id_factory_; |
| 156 |
264 }; | 157 }; |
265 | 158 |
266 #endif // CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ | 159 #endif // CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ |
OLD | NEW |