diff options
Diffstat (limited to 'sync/internal_api')
-rw-r--r-- | sync/internal_api/sync_manager.cc | 77 | ||||
-rw-r--r-- | sync/internal_api/sync_manager.h | 38 | ||||
-rw-r--r-- | sync/internal_api/syncapi_unittest.cc | 89 |
3 files changed, 157 insertions, 47 deletions
diff --git a/sync/internal_api/sync_manager.cc b/sync/internal_api/sync_manager.cc index 8a2ff70..4cb5127 100644 --- a/sync/internal_api/sync_manager.cc +++ b/sync/internal_api/sync_manager.cc @@ -59,6 +59,7 @@ using base::TimeDelta; using browser_sync::AllStatus; +using browser_sync::ConfigurationParams; using browser_sync::Cryptographer; using browser_sync::Encryptor; using browser_sync::JsArgList; @@ -397,6 +398,8 @@ class SyncManager::SyncInternal const std::string& name, const JsArgList& args, const WeakHandle<JsReplyHandler>& reply_handler) OVERRIDE; + void SetSyncSchedulerForTest(scoped_ptr<SyncScheduler> scheduler); + private: struct NotificationInfo { int total_count; @@ -816,46 +819,44 @@ bool SyncManager::IsUsingExplicitPassphrase() { return data_ && data_->IsUsingExplicitPassphrase(); } -void SyncManager::RequestCleanupDisabledTypes( - const browser_sync::ModelSafeRoutingInfo& routing_info) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (data_->scheduler()) { - data_->session_context()->set_routing_info(routing_info); - data_->scheduler()->CleanupDisabledTypes(); - } -} - void SyncManager::RequestClearServerData() { DCHECK(thread_checker_.CalledOnValidThread()); if (data_->scheduler()) data_->scheduler()->ClearUserData(); } -void SyncManager::RequestConfig( - const browser_sync::ModelSafeRoutingInfo& routing_info, - const ModelTypeSet& types, ConfigureReason reason) { +void SyncManager::ConfigureSyncer( + ConfigureReason reason, + const syncable::ModelTypeSet& types_to_config, + const browser_sync::ModelSafeRoutingInfo& new_routing_info, + const base::Closure& ready_task, + const base::Closure& retry_task) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!data_->scheduler()) { - LOG(INFO) - << "SyncManager::RequestConfig: bailing out because scheduler is " - << "null"; - return; - } - StartConfigurationMode(base::Closure()); - data_->session_context()->set_routing_info(routing_info); - data_->scheduler()->ScheduleConfiguration(types, GetSourceFromReason(reason)); -} + DCHECK(!ready_task.is_null()); + DCHECK(!retry_task.is_null()); + + // TODO(zea): set this based on whether cryptographer has keystore + // encryption key or not (requires opening a transaction). crbug.com/129665. + ConfigurationParams::KeystoreKeyStatus keystore_key_status = + ConfigurationParams::KEYSTORE_KEY_UNNECESSARY; + + ConfigurationParams params(GetSourceFromReason(reason), + types_to_config, + new_routing_info, + keystore_key_status, + ready_task); -void SyncManager::StartConfigurationMode(const base::Closure& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); if (!data_->scheduler()) { LOG(INFO) - << "SyncManager::StartConfigurationMode: could not start " - << "configuration mode because because scheduler is null"; + << "SyncManager::ConfigureSyncer: could not configure because " + << "scheduler is null"; + params.ready_task.Run(); return; } - data_->scheduler()->Start( - browser_sync::SyncScheduler::CONFIGURATION_MODE, callback); + + data_->scheduler()->Start(SyncScheduler::CONFIGURATION_MODE); + if (!data_->scheduler()->ScheduleConfiguration(params)) + retry_task.Run(); } bool SyncManager::SyncInternal::Init( @@ -941,8 +942,7 @@ bool SyncManager::SyncInternal::Init( if (signed_in) { if (scheduler()) { - scheduler()->Start( - browser_sync::SyncScheduler::CONFIGURATION_MODE, base::Closure()); + scheduler()->Start(SyncScheduler::CONFIGURATION_MODE); } initialized_ = true; @@ -1116,9 +1116,13 @@ void SyncManager::SyncInternal::NotifyCryptographerState( void SyncManager::SyncInternal::StartSyncingNormally( const browser_sync::ModelSafeRoutingInfo& routing_info) { // Start the sync scheduler. - if (scheduler()) { // NULL during certain unittests. + if (scheduler()) { // NULL during certain unittests. + // TODO(sync): We always want the newest set of routes when we switch back + // to normal mode. Figure out how to enforce set_routing_info is always + // appropriately set and that it's only modified when switching to normal + // mode. session_context()->set_routing_info(routing_info); - scheduler()->Start(SyncScheduler::NORMAL_MODE, base::Closure()); + scheduler()->Start(SyncScheduler::NORMAL_MODE); } } @@ -2353,6 +2357,11 @@ void SyncManager::SyncInternal::RemoveObserver( observers_.RemoveObserver(observer); } +void SyncManager::SyncInternal::SetSyncSchedulerForTest( + scoped_ptr<SyncScheduler> sync_scheduler) { + scheduler_ = sync_scheduler.Pass(); +} + SyncStatus SyncManager::GetDetailedStatus() const { return data_->GetStatus(); } @@ -2383,6 +2392,10 @@ TimeDelta SyncManager::GetNudgeDelayTimeDelta( return data_->GetNudgeDelayTimeDelta(model_type); } +void SyncManager::SetSyncSchedulerForTest(scoped_ptr<SyncScheduler> scheduler) { + data_->SetSyncSchedulerForTest(scheduler.Pass()); +} + syncable::ModelTypeSet SyncManager::GetEncryptedDataTypesForTest() const { ReadTransaction trans(FROM_HERE, GetUserShare()); return GetEncryptedTypes(&trans); diff --git a/sync/internal_api/sync_manager.h b/sync/internal_api/sync_manager.h index 04594fd..04181fe 100644 --- a/sync/internal_api/sync_manager.h +++ b/sync/internal_api/sync_manager.h @@ -26,11 +26,13 @@ #include "sync/util/weak_handle.h" namespace browser_sync { +struct ConfigurationParams; class Encryptor; struct Experiments; class ExtensionsActivityMonitor; class JsBackend; class JsEventHandler; +class SyncScheduler; namespace sessions { class SyncSessionSnapshot; @@ -431,24 +433,24 @@ class SyncManager { // error to call this when we don't have pending keys. void SetDecryptionPassphrase(const std::string& passphrase); - // Puts the SyncScheduler into a mode where no normal nudge or poll traffic - // will occur, but calls to RequestConfig will be supported. If |callback| - // is provided, it will be invoked (from the internal SyncScheduler) when - // the thread has changed to configuration mode. - void StartConfigurationMode(const base::Closure& callback); - - // Switches the mode of operation to CONFIGURATION_MODE and - // schedules a config task to fetch updates for |types|. - void RequestConfig(const browser_sync::ModelSafeRoutingInfo& routing_info, - const syncable::ModelTypeSet& types, - sync_api::ConfigureReason reason); - - void RequestCleanupDisabledTypes( - const browser_sync::ModelSafeRoutingInfo& routing_info); - // Request a clearing of all data on the server void RequestClearServerData(); + // Switches the mode of operation to CONFIGURATION_MODE and performs + // any configuration tasks needed as determined by the params. Once complete, + // syncer will remain in CONFIGURATION_MODE until StartSyncingNormally is + // called. + // |ready_task| is invoked when the configuration completes. + // |retry_task| is invoked if the configuration job could not immediately + // execute. |ready_task| will still be called when it eventually + // does finish. + void ConfigureSyncer( + ConfigureReason reason, + const syncable::ModelTypeSet& types_to_config, + const browser_sync::ModelSafeRoutingInfo& new_routing_info, + const base::Closure& ready_task, + const base::Closure& retry_task); + // Adds a listener to be notified of sync events. // NOTE: It is OK (in fact, it's probably a good idea) to call this before // having received OnInitializationCompleted. @@ -543,11 +545,17 @@ class SyncManager { static const FilePath::CharType kSyncDatabaseFilename[]; private: + friend class SyncManagerTest; FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, NudgeDelayTest); // For unit tests. base::TimeDelta GetNudgeDelayTimeDelta(const syncable::ModelType& model_type); + // Set the internal scheduler for testing purposes. + // TODO(sync): Use dependency injection instead. crbug.com/133061 + void SetSyncSchedulerForTest( + scoped_ptr<browser_sync::SyncScheduler> scheduler); + base::ThreadChecker thread_checker_; // An opaque pointer to the nested private class. diff --git a/sync/internal_api/syncapi_unittest.cc b/sync/internal_api/syncapi_unittest.cc index 991aed6..6380db3 100644 --- a/sync/internal_api/syncapi_unittest.cc +++ b/sync/internal_api/syncapi_unittest.cc @@ -24,6 +24,7 @@ #include "base/utf_string_conversions.h" #include "base/values.h" #include "sync/engine/nigori_util.h" +#include "sync/engine/sync_scheduler.h" #include "sync/internal_api/change_record.h" #include "sync/internal_api/http_post_provider_factory.h" #include "sync/internal_api/http_post_provider_interface.h" @@ -54,6 +55,7 @@ #include "sync/sessions/sync_session.h" #include "sync/syncable/syncable.h" #include "sync/syncable/syncable_id.h" +#include "sync/test/callback_counter.h" #include "sync/test/fake_encryptor.h" #include "sync/test/fake_extensions_activity_monitor.h" #include "sync/util/cryptographer.h" @@ -64,6 +66,8 @@ #include "testing/gtest/include/gtest/gtest.h" using base::ExpectDictStringValue; +using browser_sync::CallbackCounter; +using browser_sync::ConfigurationParams; using browser_sync::Cryptographer; using browser_sync::FakeEncryptor; using browser_sync::FakeExtensionsActivityMonitor; @@ -80,6 +84,7 @@ using browser_sync::MockJsReplyHandler; using browser_sync::ModelSafeRoutingInfo; using browser_sync::ModelSafeWorker; using browser_sync::sessions::SyncSessionSnapshot; +using browser_sync::SyncScheduler; using browser_sync::TestUnrecoverableErrorHandler; using browser_sync::WeakHandle; using syncable::IS_DEL; @@ -92,8 +97,10 @@ using syncable::SPECIFICS; using testing::_; using testing::AnyNumber; using testing::AtLeast; +using testing::DoAll; using testing::InSequence; using testing::Invoke; +using testing::Return; using testing::SaveArg; using testing::StrictMock; @@ -926,6 +933,10 @@ class SyncManagerTest : public testing::Test, return true; } + void SetScheduler(scoped_ptr<SyncScheduler> scheduler) { + sync_manager_.SetSyncSchedulerForTest(scheduler.Pass()); + } + private: // Needed by |sync_manager_|. MessageLoop message_loop_; @@ -2507,4 +2518,82 @@ TEST_F(SyncManagerTest, SetPreviouslyEncryptedSpecifics) { } } +namespace { + +class MockSyncScheduler : public SyncScheduler { + public: + MockSyncScheduler() : SyncScheduler("name", NULL, NULL) {} + virtual ~MockSyncScheduler() {} + + MOCK_METHOD1(Start, void(SyncScheduler::Mode)); + MOCK_METHOD1(ScheduleConfiguration, bool(const ConfigurationParams&)); +}; + +} // namespace + +// Test that the configuration params are properly created and sent to +// ScheduleConfigure. No callback should be invoked. +TEST_F(SyncManagerTest, BasicConfiguration) { + ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION; + syncable::ModelTypeSet types_to_download(syncable::BOOKMARKS, + syncable::PREFERENCES); + browser_sync::ModelSafeRoutingInfo new_routing_info; + GetModelSafeRoutingInfo(&new_routing_info); + + scoped_ptr<MockSyncScheduler> scheduler(new MockSyncScheduler()); + ConfigurationParams params; + EXPECT_CALL(*scheduler, Start(SyncScheduler::CONFIGURATION_MODE)); + EXPECT_CALL(*scheduler, ScheduleConfiguration(_)). + WillOnce(DoAll(SaveArg<0>(¶ms), Return(true))); + SetScheduler(scheduler.PassAs<SyncScheduler>()); + + CallbackCounter ready_task_counter, retry_task_counter; + sync_manager_.ConfigureSyncer( + reason, + types_to_download, + new_routing_info, + base::Bind(&CallbackCounter::Callback, + base::Unretained(&ready_task_counter)), + base::Bind(&CallbackCounter::Callback, + base::Unretained(&retry_task_counter))); + EXPECT_EQ(0, ready_task_counter.times_called()); + EXPECT_EQ(0, retry_task_counter.times_called()); + EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, + params.source); + EXPECT_TRUE(types_to_download.Equals(params.types_to_download)); + EXPECT_EQ(new_routing_info, params.routing_info); +} + +// Test that the retry callback is invoked on configuration failure. +TEST_F(SyncManagerTest, ConfigurationRetry) { + ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION; + syncable::ModelTypeSet types_to_download(syncable::BOOKMARKS, + syncable::PREFERENCES); + browser_sync::ModelSafeRoutingInfo new_routing_info; + GetModelSafeRoutingInfo(&new_routing_info); + + scoped_ptr<MockSyncScheduler> scheduler(new MockSyncScheduler()); + ConfigurationParams params; + EXPECT_CALL(*scheduler, Start(SyncScheduler::CONFIGURATION_MODE)); + EXPECT_CALL(*scheduler, ScheduleConfiguration(_)). + WillOnce(DoAll(SaveArg<0>(¶ms), Return(false))); + SetScheduler(scheduler.PassAs<SyncScheduler>()); + + CallbackCounter ready_task_counter, retry_task_counter; + sync_manager_.ConfigureSyncer( + reason, + types_to_download, + new_routing_info, + base::Bind(&CallbackCounter::Callback, + base::Unretained(&ready_task_counter)), + base::Bind(&CallbackCounter::Callback, + base::Unretained(&retry_task_counter))); + EXPECT_EQ(0, ready_task_counter.times_called()); + EXPECT_EQ(1, retry_task_counter.times_called()); + EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, + params.source); + EXPECT_TRUE(types_to_download.Equals(params.types_to_download)); + EXPECT_EQ(new_routing_info, params.routing_info); +} + } // namespace browser_sync |