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 "chrome/browser/sync/test_profile_sync_service.h" 6 7#include "chrome/browser/sync/abstract_profile_sync_service_test.h" 8#include "chrome/browser/sync/engine/syncapi.h" 9#include "chrome/browser/sync/glue/data_type_controller.h" 10#include "chrome/browser/sync/glue/sync_backend_host.h" 11#include "chrome/browser/sync/profile_sync_factory.h" 12#include "chrome/browser/sync/sessions/session_state.h" 13#include "chrome/browser/sync/syncable/directory_manager.h" 14#include "chrome/browser/sync/syncable/syncable.h" 15#include "chrome/test/sync/test_http_bridge_factory.h" 16 17using browser_sync::ModelSafeRoutingInfo; 18using browser_sync::sessions::ErrorCounters; 19using browser_sync::sessions::SyncSourceInfo; 20using browser_sync::sessions::SyncerStatus; 21using browser_sync::sessions::SyncSessionSnapshot; 22using syncable::DirectoryManager; 23using syncable::ModelType; 24using syncable::ScopedDirLookup; 25using sync_api::UserShare; 26 27namespace browser_sync { 28 29using ::testing::_; 30SyncBackendHostForProfileSyncTest::SyncBackendHostForProfileSyncTest( 31 Profile* profile, 32 bool set_initial_sync_ended_on_init, 33 bool synchronous_init) 34 : browser_sync::SyncBackendHost(profile), 35 synchronous_init_(synchronous_init) { 36 ON_CALL(*this, RequestNudge(_)).WillByDefault( 37 testing::Invoke(this, 38 &SyncBackendHostForProfileSyncTest:: 39 SimulateSyncCycleCompletedInitialSyncEnded)); 40 EXPECT_CALL(*this, RequestNudge(_)).Times(testing::AnyNumber()); 41} 42 43SyncBackendHostForProfileSyncTest::~SyncBackendHostForProfileSyncTest() {} 44 45void SyncBackendHostForProfileSyncTest::ConfigureDataTypes( 46 const DataTypeController::TypeMap& data_type_controllers, 47 const syncable::ModelTypeSet& types, 48 CancelableTask* ready_task) { 49 SetAutofillMigrationState(syncable::MIGRATED); 50 SyncBackendHost::ConfigureDataTypes( 51 data_type_controllers, types, ready_task); 52} 53 54void SyncBackendHostForProfileSyncTest:: 55 SimulateSyncCycleCompletedInitialSyncEnded( 56 const tracked_objects::Location& location) { 57 syncable::ModelTypeBitSet sync_ended; 58 ModelSafeRoutingInfo enabled_types; 59 GetModelSafeRoutingInfo(&enabled_types); 60 std::string download_progress_markers[syncable::MODEL_TYPE_COUNT]; 61 for (ModelSafeRoutingInfo::const_iterator i = enabled_types.begin(); 62 i != enabled_types.end(); ++i) { 63 sync_ended.set(i->first); 64 } 65 core_->HandleSyncCycleCompletedOnFrontendLoop(new SyncSessionSnapshot( 66 SyncerStatus(), ErrorCounters(), 0, false, 67 sync_ended, download_progress_markers, false, false, 0, 0, false, 68 SyncSourceInfo())); 69} 70 71sync_api::HttpPostProviderFactory* 72 SyncBackendHostForProfileSyncTest::MakeHttpBridgeFactory( 73 net::URLRequestContextGetter* getter) { 74 return new browser_sync::TestHttpBridgeFactory; 75} 76 77void SyncBackendHostForProfileSyncTest::InitCore( 78 const Core::DoInitializeOptions& options) { 79 std::wstring user = L"testuser@gmail.com"; 80 core_loop()->PostTask( 81 FROM_HERE, 82 NewRunnableMethod(core_.get(), 83 &SyncBackendHost::Core::DoInitializeForTest, 84 user, 85 options.http_bridge_factory, 86 options.delete_sync_data_folder)); 87 88 // TODO(akalin): Figure out a better way to do this. 89 if (synchronous_init_) { 90 // The SyncBackend posts a task to the current loop when 91 // initialization completes. 92 MessageLoop::current()->Run(); 93 } 94} 95 96JsBackend* SyncBackendHostForProfileSyncTest::GetJsBackend() { 97 // Return a non-NULL result only when the overridden function does. 98 if (SyncBackendHost::GetJsBackend()) { 99 return this; 100 } else { 101 NOTREACHED(); 102 return NULL; 103 } 104} 105 106void SyncBackendHostForProfileSyncTest::SetParentJsEventRouter( 107 JsEventRouter* router) { 108 core_->SetParentJsEventRouter(router); 109} 110 111void SyncBackendHostForProfileSyncTest::RemoveParentJsEventRouter() { 112 core_->RemoveParentJsEventRouter(); 113} 114 115const JsEventRouter* 116 SyncBackendHostForProfileSyncTest::GetParentJsEventRouter() const { 117 return core_->GetParentJsEventRouter(); 118} 119 120void SyncBackendHostForProfileSyncTest::ProcessMessage( 121 const std::string& name, const JsArgList& args, 122 const JsEventHandler* sender) { 123 if (name.find("delay") != name.npos) { 124 core_->RouteJsEvent(name, args, sender); 125 } else { 126 core_->RouteJsEventOnFrontendLoop(name, args, sender); 127 } 128} 129 130void SyncBackendHostForProfileSyncTest::StartConfiguration(Callback0::Type*) { 131 SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop(); 132} 133 134void SyncBackendHostForProfileSyncTest:: 135 SetDefaultExpectationsForWorkerCreation(ProfileMock* profile) { 136 EXPECT_CALL(*profile, GetPasswordStore(testing::_)). 137 WillOnce(testing::Return((PasswordStore*)NULL)); 138} 139 140void SyncBackendHostForProfileSyncTest::SetHistoryServiceExpectations( 141 ProfileMock* profile) { 142 EXPECT_CALL(*profile, GetHistoryService(testing::_)). 143 WillOnce(testing::Return((HistoryService*)NULL)); 144} 145 146} // namespace browser_sync 147 148browser_sync::TestIdFactory* TestProfileSyncService::id_factory() { 149 return &id_factory_; 150} 151 152browser_sync::SyncBackendHostForProfileSyncTest* 153 TestProfileSyncService::GetBackendForTest() { 154 return static_cast<browser_sync::SyncBackendHostForProfileSyncTest*>( 155 ProfileSyncService::GetBackendForTest()); 156} 157 158TestProfileSyncService::TestProfileSyncService( 159 ProfileSyncFactory* factory, 160 Profile* profile, 161 const std::string& test_user, 162 bool synchronous_backend_initialization, 163 Task* initial_condition_setup_task) 164 : ProfileSyncService(factory, profile, test_user), 165 synchronous_backend_initialization_( 166 synchronous_backend_initialization), 167 synchronous_sync_configuration_(false), 168 initial_condition_setup_task_(initial_condition_setup_task), 169 set_initial_sync_ended_on_init_(true) { 170 RegisterPreferences(); 171 SetSyncSetupCompleted(); 172} 173 174TestProfileSyncService::~TestProfileSyncService() {} 175 176void TestProfileSyncService::SetInitialSyncEndedForEnabledTypes() { 177 UserShare* user_share = GetUserShare(); 178 DirectoryManager* dir_manager = user_share->dir_manager.get(); 179 180 ScopedDirLookup dir(dir_manager, user_share->name); 181 if (!dir.good()) 182 FAIL(); 183 184 ModelSafeRoutingInfo enabled_types; 185 backend_->GetModelSafeRoutingInfo(&enabled_types); 186 for (ModelSafeRoutingInfo::const_iterator i = enabled_types.begin(); 187 i != enabled_types.end(); ++i) { 188 dir->set_initial_sync_ended_for_type(i->first, true); 189 } 190} 191 192void TestProfileSyncService::OnBackendInitialized() { 193 // Set this so below code can access GetUserShare(). 194 backend_initialized_ = true; 195 196 // Set up any nodes the test wants around before model association. 197 if (initial_condition_setup_task_) { 198 initial_condition_setup_task_->Run(); 199 initial_condition_setup_task_ = NULL; 200 } 201 202 // Pretend we downloaded initial updates and set initial sync ended bits 203 // if we were asked to. 204 bool send_passphrase_required = false; 205 if (set_initial_sync_ended_on_init_) { 206 UserShare* user_share = GetUserShare(); 207 DirectoryManager* dir_manager = user_share->dir_manager.get(); 208 209 ScopedDirLookup dir(dir_manager, user_share->name); 210 if (!dir.good()) 211 FAIL(); 212 213 if (!dir->initial_sync_ended_for_type(syncable::NIGORI)) { 214 ProfileSyncServiceTestHelper::CreateRoot( 215 syncable::NIGORI, GetUserShare(), 216 id_factory()); 217 218 // A side effect of adding the NIGORI mode (normally done by the syncer) 219 // is a decryption attempt, which will fail the first time. 220 send_passphrase_required = true; 221 } 222 223 SetInitialSyncEndedForEnabledTypes(); 224 } 225 226 ProfileSyncService::OnBackendInitialized(); 227 if (send_passphrase_required) 228 OnPassphraseRequired(true); 229 230 // TODO(akalin): Figure out a better way to do this. 231 if (synchronous_backend_initialization_) { 232 MessageLoop::current()->Quit(); 233 } 234} 235 236void TestProfileSyncService::Observe(NotificationType type, 237 const NotificationSource& source, 238 const NotificationDetails& details) { 239 ProfileSyncService::Observe(type, source, details); 240 if (type == NotificationType::SYNC_CONFIGURE_DONE && 241 !synchronous_sync_configuration_) { 242 MessageLoop::current()->Quit(); 243 } 244} 245 246void TestProfileSyncService::dont_set_initial_sync_ended_on_init() { 247 set_initial_sync_ended_on_init_ = false; 248} 249void TestProfileSyncService::set_synchronous_sync_configuration() { 250 synchronous_sync_configuration_ = true; 251} 252 253void TestProfileSyncService::CreateBackend() { 254 backend_.reset(new browser_sync::SyncBackendHostForProfileSyncTest( 255 profile(), 256 set_initial_sync_ended_on_init_, 257 synchronous_backend_initialization_)); 258} 259 260std::string TestProfileSyncService::GetLsidForAuthBootstraping() { 261 return "foo"; 262} 263