[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ |
| 6 | #define CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ |
[email protected] | 32b76ef | 2010-07-26 23:08:24 | [diff] [blame] | 7 | #pragma once |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 8 | |
| 9 | #include <string> |
| 10 | |
| 11 | #include "base/message_loop.h" |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 12 | #include "chrome/browser/sync/engine/syncapi.h" |
[email protected] | e3e43d9 | 2010-02-26 22:02:38 | [diff] [blame] | 13 | #include "chrome/browser/sync/profile_sync_factory.h" |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 14 | #include "chrome/browser/sync/profile_sync_service.h" |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 15 | #include "chrome/browser/sync/glue/data_type_controller.h" |
| 16 | #include "chrome/browser/sync/glue/data_type_manager_impl.h" |
| 17 | #include "chrome/browser/sync/glue/sync_backend_host.h" |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 18 | #include "chrome/browser/sync/sessions/session_state.h" |
| 19 | #include "chrome/browser/sync/syncable/directory_manager.h" |
| 20 | #include "chrome/browser/sync/syncable/syncable.h" |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 21 | #include "chrome/test/profile_mock.h" |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 22 | #include "chrome/test/sync/test_http_bridge_factory.h" |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 23 | #include "testing/gmock/include/gmock/gmock.h" |
| 24 | |
[email protected] | 95f0fe74 | 2010-12-10 01:38:29 | [diff] [blame] | 25 | class Profile; |
| 26 | |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 27 | using browser_sync::ModelSafeRoutingInfo; |
| 28 | using browser_sync::sessions::ErrorCounters; |
| 29 | using browser_sync::sessions::SyncerStatus; |
| 30 | using browser_sync::sessions::SyncSessionSnapshot; |
| 31 | using sync_api::UserShare; |
| 32 | using syncable::DirectoryManager; |
| 33 | using syncable::ModelType; |
| 34 | using syncable::ScopedDirLookup; |
| 35 | |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 36 | ACTION_P(CallOnPaused, core) { |
| 37 | core->OnPaused(); |
| 38 | }; |
| 39 | |
| 40 | ACTION_P(CallOnResumed, core) { |
| 41 | core->OnResumed(); |
| 42 | } |
| 43 | |
| 44 | ACTION(ReturnNewDataTypeManager) { |
| 45 | return new browser_sync::DataTypeManagerImpl(arg0, arg1); |
| 46 | } |
| 47 | |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 48 | namespace browser_sync { |
| 49 | |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 50 | // 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 |
| 52 | // to set up initial nodes to mock out an actual server initial sync |
| 53 | // download. |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 54 | class SyncBackendHostForProfileSyncTest : public SyncBackendHost { |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 55 | public: |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 56 | // |initial_condition_setup_task| can be used to populate nodes before the |
| 57 | // OnBackendInitialized callback fires. |
| 58 | // |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 |
| 60 | // this is false, configuring data types will require a syncer nudge. |
| 61 | // |synchronous_init| causes initialization to block until the syncapi has |
| 62 | // completed setting itself up and called us back. |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 63 | SyncBackendHostForProfileSyncTest(SyncFrontend* frontend, |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 64 | Profile* profile, |
| 65 | const FilePath& profile_path, |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 66 | const DataTypeController::TypeMap& data_type_controllers, |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 67 | Task* initial_condition_setup_task, |
| 68 | int num_expected_resumes, |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 69 | int num_expected_pauses, |
| 70 | bool set_initial_sync_ended_on_init, |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 71 | 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 | } |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 94 | |
| 95 | MOCK_METHOD0(RequestPause, bool()); |
| 96 | MOCK_METHOD0(RequestResume, bool()); |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 97 | MOCK_METHOD0(RequestNudge, void()); |
| 98 | |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 99 | void SetInitialSyncEndedForEnabledTypes() { |
| 100 | UserShare* user_share = core_->syncapi()->GetUserShare(); |
| 101 | DirectoryManager* dir_manager = user_share->dir_manager.get(); |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 102 | |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 103 | ScopedDirLookup dir(dir_manager, user_share->name); |
| 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 | |
[email protected] | 269bb3a69 | 2011-01-05 02:54:41 | [diff] [blame] | 115 | virtual void ConfigureDataTypes(const syncable::ModelTypeSet& types, |
| 116 | CancelableTask* ready_task) { |
| 117 | SetAutofillMigrationState(syncable::MIGRATED); |
| 118 | SyncBackendHost::ConfigureDataTypes(types, ready_task); |
| 119 | } |
| 120 | |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 121 | virtual void HandleInitializationCompletedOnFrontendLoop() { |
| 122 | set_syncapi_initialized(); // Need to do this asap so task below works. |
| 123 | |
| 124 | // Set up any nodes the test wants around before model association. |
| 125 | if (initial_condition_setup_task_) { |
| 126 | initial_condition_setup_task_->Run(); |
| 127 | } |
| 128 | |
| 129 | // Pretend we downloaded initial updates and set initial sync ended bits |
| 130 | // if we were asked to. |
| 131 | if (set_initial_sync_ended_on_init_) |
| 132 | SetInitialSyncEndedForEnabledTypes(); |
| 133 | |
| 134 | SyncBackendHost::HandleInitializationCompletedOnFrontendLoop(); |
| 135 | } |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 136 | |
| 137 | // Called when a nudge comes in. |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 138 | void SimulateSyncCycleCompletedInitialSyncEnded() { |
| 139 | syncable::ModelTypeBitSet sync_ended; |
| 140 | ModelSafeRoutingInfo enabled_types; |
| 141 | GetModelSafeRoutingInfo(&enabled_types); |
| 142 | for (ModelSafeRoutingInfo::const_iterator i = enabled_types.begin(); |
| 143 | i != enabled_types.end(); ++i) { |
| 144 | sync_ended.set(i->first); |
| 145 | } |
| 146 | core_->HandleSyncCycleCompletedOnFrontendLoop(new SyncSessionSnapshot( |
| 147 | SyncerStatus(), ErrorCounters(), 0, 0, false, |
| 148 | sync_ended, false, false, 0, 0, false)); |
| 149 | } |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 150 | |
| 151 | virtual sync_api::HttpPostProviderFactory* MakeHttpBridgeFactory( |
| 152 | URLRequestContextGetter* getter) { |
| 153 | return new browser_sync::TestHttpBridgeFactory; |
| 154 | } |
| 155 | |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 156 | virtual void InitCore(const Core::DoInitializeOptions& options) { |
| 157 | std::wstring user = L"testuser"; |
| 158 | core_loop()->PostTask(FROM_HERE, |
| 159 | NewRunnableMethod(core_.get(), |
| 160 | &SyncBackendHost::Core::DoInitializeForTest, |
| 161 | user, |
| 162 | options.http_bridge_factory, |
| 163 | options.delete_sync_data_folder)); |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 164 | |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 165 | // TODO(akalin): Figure out a better way to do this. |
| 166 | if (synchronous_init_) { |
| 167 | // The SyncBackend posts a task to the current loop when |
| 168 | // initialization completes. |
| 169 | MessageLoop::current()->Run(); |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | static void SetDefaultExpectationsForWorkerCreation(ProfileMock* profile) { |
| 174 | EXPECT_CALL(*profile, GetPasswordStore(testing::_)). |
| 175 | WillOnce(testing::Return((PasswordStore*)NULL)); |
| 176 | EXPECT_CALL(*profile, GetHistoryService(testing::_)). |
| 177 | WillOnce(testing::Return((HistoryService*)NULL)); |
| 178 | } |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 179 | |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 180 | private: |
| 181 | Task* initial_condition_setup_task_; |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 182 | bool set_initial_sync_ended_on_init_; |
| 183 | bool synchronous_init_; |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 184 | }; |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 185 | |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 186 | } // namespace browser_sync |
| 187 | |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 188 | class TestProfileSyncService : public ProfileSyncService { |
| 189 | public: |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 190 | TestProfileSyncService(ProfileSyncFactory* factory, |
| 191 | Profile* profile, |
[email protected] | e8234d3 | 2010-09-09 20:36:39 | [diff] [blame] | 192 | const std::string& test_user, |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 193 | bool synchronous_backend_initialization, |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 194 | Task* initial_condition_setup_task) |
| 195 | : ProfileSyncService(factory, profile, |
| 196 | !test_user.empty() ? |
| 197 | test_user : ""), |
| 198 | synchronous_backend_initialization_( |
| 199 | synchronous_backend_initialization), |
| 200 | synchronous_sync_configuration_(false), |
| 201 | num_expected_resumes_(1), |
| 202 | num_expected_pauses_(1), |
| 203 | initial_condition_setup_task_(initial_condition_setup_task), |
| 204 | set_initial_sync_ended_on_init_(true) { |
| 205 | RegisterPreferences(); |
| 206 | SetSyncSetupCompleted(); |
| 207 | } |
[email protected] | 66761b95 | 2010-06-25 21:30:38 | [diff] [blame] | 208 | virtual ~TestProfileSyncService() { } |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 209 | |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 210 | virtual void CreateBackend() { |
| 211 | backend_.reset(new browser_sync::SyncBackendHostForProfileSyncTest( |
| 212 | this, profile(), |
| 213 | profile()->GetPath(), data_type_controllers(), |
| 214 | initial_condition_setup_task_.release(), |
| 215 | num_expected_resumes_, num_expected_pauses_, |
| 216 | set_initial_sync_ended_on_init_, |
| 217 | synchronous_backend_initialization_)); |
| 218 | } |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 219 | |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 220 | virtual void OnBackendInitialized() { |
| 221 | ProfileSyncService::OnBackendInitialized(); |
| 222 | // TODO(akalin): Figure out a better way to do this. |
| 223 | if (synchronous_backend_initialization_) { |
| 224 | MessageLoop::current()->Quit(); |
| 225 | } |
| 226 | } |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 227 | |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 228 | virtual void Observe(NotificationType type, |
| 229 | const NotificationSource& source, |
[email protected] | ea74cbf | 2010-11-04 23:49:54 | [diff] [blame] | 230 | const NotificationDetails& details) { |
| 231 | ProfileSyncService::Observe(type, source, details); |
| 232 | if (type == NotificationType::SYNC_CONFIGURE_DONE && |
| 233 | !synchronous_sync_configuration_) { |
| 234 | MessageLoop::current()->Quit(); |
| 235 | } |
| 236 | } |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 237 | |
| 238 | void set_num_expected_resumes(int times) { |
| 239 | num_expected_resumes_ = times; |
| 240 | } |
| 241 | void set_num_expected_pauses(int num) { |
| 242 | num_expected_pauses_ = num; |
| 243 | } |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 244 | void dont_set_initial_sync_ended_on_init() { |
| 245 | set_initial_sync_ended_on_init_ = false; |
| 246 | } |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 247 | void set_synchronous_sync_configuration() { |
| 248 | synchronous_sync_configuration_ = true; |
| 249 | } |
| 250 | |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 251 | private: |
| 252 | // When testing under ChromiumOS, this method must not return an empty |
| 253 | // value value in order for the profile sync service to start. |
| 254 | virtual std::string GetLsidForAuthBootstraping() { |
| 255 | return "foo"; |
| 256 | } |
[email protected] | 4c21758 | 2010-05-13 21:37:14 | [diff] [blame] | 257 | |
| 258 | bool synchronous_backend_initialization_; |
[email protected] | 7cef1c44 | 2010-07-07 17:05:22 | [diff] [blame] | 259 | |
| 260 | // Set to true when a mock data type manager is being used and the configure |
| 261 | // step is performed synchronously. |
| 262 | bool synchronous_sync_configuration_; |
| 263 | bool set_expect_resume_expectations_; |
| 264 | int num_expected_resumes_; |
| 265 | int num_expected_pauses_; |
| 266 | |
| 267 | scoped_ptr<Task> initial_condition_setup_task_; |
[email protected] | 18af9a2 | 2010-08-11 00:47:19 | [diff] [blame] | 268 | bool set_initial_sync_ended_on_init_; |
[email protected] | 72a31b4 | 2010-02-17 22:26:33 | [diff] [blame] | 269 | }; |
| 270 | |
| 271 | #endif // CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ |