diff options
Diffstat (limited to 'sync/sessions')
-rw-r--r-- | sync/sessions/sync_session.cc | 136 | ||||
-rw-r--r-- | sync/sessions/sync_session.h | 39 | ||||
-rw-r--r-- | sync/sessions/sync_session_unittest.cc | 225 |
3 files changed, 20 insertions, 380 deletions
diff --git a/sync/sessions/sync_session.cc b/sync/sessions/sync_session.cc index f9241d9..11c95eb 100644 --- a/sync/sessions/sync_session.cc +++ b/sync/sessions/sync_session.cc @@ -15,136 +15,24 @@ namespace syncer { namespace sessions { -namespace { - -std::set<ModelSafeGroup> ComputeEnabledGroups( - const ModelSafeRoutingInfo& routing_info, - const std::vector<ModelSafeWorker*>& workers) { - std::set<ModelSafeGroup> enabled_groups; - // Project the list of enabled types (i.e., types in the routing - // info) to a list of enabled groups. - for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin(); - it != routing_info.end(); ++it) { - enabled_groups.insert(it->second); - } - // GROUP_PASSIVE is always enabled, since that's the group that - // top-level folders map to. - enabled_groups.insert(GROUP_PASSIVE); - if (DCHECK_IS_ON()) { - // We sometimes create dummy SyncSession objects (see - // SyncScheduler::InitialSnapshot) so don't check in that case. - if (!routing_info.empty() || !workers.empty()) { - std::set<ModelSafeGroup> groups_with_workers; - for (std::vector<ModelSafeWorker*>::const_iterator it = workers.begin(); - it != workers.end(); ++it) { - groups_with_workers.insert((*it)->GetModelSafeGroup()); - } - // All enabled groups should have a corresponding worker. - DCHECK(std::includes( - groups_with_workers.begin(), groups_with_workers.end(), - enabled_groups.begin(), enabled_groups.end())); - } - } - return enabled_groups; -} - -void PurgeStaleStates(ModelTypeInvalidationMap* original, - const ModelSafeRoutingInfo& routing_info) { - std::vector<ModelTypeInvalidationMap::iterator> iterators_to_delete; - for (ModelTypeInvalidationMap::iterator i = original->begin(); - i != original->end(); ++i) { - if (routing_info.end() == routing_info.find(i->first)) { - iterators_to_delete.push_back(i); - } - } - - for (std::vector<ModelTypeInvalidationMap::iterator>::iterator - it = iterators_to_delete.begin(); it != iterators_to_delete.end(); - ++it) { - original->erase(*it); - } -} - -} // namesepace - -SyncSession::SyncSession(SyncSessionContext* context, Delegate* delegate, - const SyncSourceInfo& source, - const ModelSafeRoutingInfo& routing_info, - const std::vector<ModelSafeWorker*>& workers) +SyncSession::SyncSession( + SyncSessionContext* context, + Delegate* delegate, + const SyncSourceInfo& source) : context_(context), source_(source), write_transaction_(NULL), - delegate_(delegate), - workers_(workers), - routing_info_(routing_info), - enabled_groups_(ComputeEnabledGroups(routing_info_, workers_)) { - status_controller_.reset(new StatusController(routing_info_)); - std::sort(workers_.begin(), workers_.end()); + delegate_(delegate) { + status_controller_.reset(new StatusController(context_->routing_info())); debug_info_sources_list_.push_back(source_); } SyncSession::~SyncSession() {} -void SyncSession::Coalesce(const SyncSession& session) { - if (context_ != session.context() || delegate_ != session.delegate_) { - NOTREACHED(); - return; - } - - // When we coalesce sessions, the sync update source gets overwritten with the - // most recent, while the type/state map gets merged. - debug_info_sources_list_.push_back(session.source_); - CoalesceStates(&source_.types, session.source_.types); - source_.updates_source = session.source_.updates_source; - - std::vector<ModelSafeWorker*> temp; - std::set_union(workers_.begin(), workers_.end(), - session.workers_.begin(), session.workers_.end(), - std::back_inserter(temp)); - workers_.swap(temp); - - // We have to update the model safe routing info to the union. In case the - // same key is present in both pick the one from session. - for (ModelSafeRoutingInfo::const_iterator it = - session.routing_info_.begin(); - it != session.routing_info_.end(); - ++it) { - routing_info_[it->first] = it->second; - } - - // Now update enabled groups. - enabled_groups_ = ComputeEnabledGroups(routing_info_, workers_); -} - -void SyncSession::RebaseRoutingInfoWithLatest( - const ModelSafeRoutingInfo& routing_info, - const std::vector<ModelSafeWorker*>& workers) { - ModelSafeRoutingInfo temp_routing_info; - - // Take the intersection and also set the routing info(it->second) from the - // passed in session. - for (ModelSafeRoutingInfo::const_iterator it = - routing_info.begin(); it != routing_info.end(); - ++it) { - if (routing_info_.find(it->first) != routing_info_.end()) { - temp_routing_info[it->first] = it->second; - } - } - routing_info_.swap(temp_routing_info); - - PurgeStaleStates(&source_.types, routing_info); - - // Now update the workers. - std::vector<ModelSafeWorker*> temp; - std::vector<ModelSafeWorker*> sorted_workers = workers; - std::sort(sorted_workers.begin(), sorted_workers.end()); - std::set_intersection(workers_.begin(), workers_.end(), - sorted_workers.begin(), sorted_workers.end(), - std::back_inserter(temp)); - workers_.swap(temp); - - // Now update enabled groups. - enabled_groups_ = ComputeEnabledGroups(routing_info_, workers_); +void SyncSession::CoalesceSources(const SyncSourceInfo& source) { + debug_info_sources_list_.push_back(source); + CoalesceStates(source.types, &source_.types); + source_.updates_source = source.updates_source; } SyncSessionSnapshot SyncSession::TakeSnapshot() const { @@ -187,10 +75,6 @@ void SyncSession::SendEventNotification(SyncEngineEvent::EventCause cause) { context()->NotifyListeners(event); } -const std::set<ModelSafeGroup>& SyncSession::GetEnabledGroups() const { - return enabled_groups_; -} - bool SyncSession::DidReachServer() const { const ModelNeutralState& state = status_controller_->model_neutral_state(); return state.last_get_key_result >= FIRST_SERVER_RETURN_VALUE || diff --git a/sync/sessions/sync_session.h b/sync/sessions/sync_session.h index 901e3b5..7271b5f 100644 --- a/sync/sessions/sync_session.h +++ b/sync/sessions/sync_session.h @@ -97,9 +97,7 @@ class SYNC_EXPORT_PRIVATE SyncSession { SyncSession(SyncSessionContext* context, Delegate* delegate, - const SyncSourceInfo& source, - const ModelSafeRoutingInfo& routing_info, - const std::vector<ModelSafeWorker*>& workers); + const SyncSourceInfo& source); ~SyncSession(); // Builds a thread-safe and read-only copy of the current session state. @@ -114,20 +112,9 @@ class SYNC_EXPORT_PRIVATE SyncSession { // See SERVER_RETURN_* in the SyncerError enum for values. bool DidReachServer() const; - // Collects all state pertaining to how and why |s| originated and unions it - // with corresponding state in |this|, leaving |s| unchanged. Allows |this| - // to take on the responsibilities |s| had (e.g. certain data types) in the - // next SyncShare operation using |this|, rather than needed two separate - // sessions. - void Coalesce(const SyncSession& session); - - // Compares the routing_info_, workers and payload map with those passed in. - // Purges types from the above 3 which are not present in latest. Useful - // to update the sync session when the user has disabled some types from - // syncing. - void RebaseRoutingInfoWithLatest( - const ModelSafeRoutingInfo& routing_info, - const std::vector<ModelSafeWorker*>& workers); + // Overwrite the sync update source with the most recent and merge the + // type/state map. + void CoalesceSources(const SyncSourceInfo& source); // TODO(akalin): Split this into context() and mutable_context(). SyncSessionContext* context() const { return context_; } @@ -147,13 +134,8 @@ class SYNC_EXPORT_PRIVATE SyncSession { return &extensions_activity_; } - const std::vector<ModelSafeWorker*>& workers() const { return workers_; } - const ModelSafeRoutingInfo& routing_info() const { return routing_info_; } const SyncSourceInfo& source() const { return source_; } - // Returns the set of groups which have enabled types. - const std::set<ModelSafeGroup>& GetEnabledGroups() const; - private: // Extend the encapsulation boundary to utilities for internal member // assignments. This way, the scope of these actions is explicit, they can't @@ -182,19 +164,6 @@ class SYNC_EXPORT_PRIVATE SyncSession { // Our controller for various status and error counters. scoped_ptr<StatusController> status_controller_; - // The set of active ModelSafeWorkers for the duration of this session. - // This can change if this session is Coalesce()'d with another. - std::vector<ModelSafeWorker*> workers_; - - // The routing info for the duration of this session, dictating which - // datatypes should be synced and which workers should be used when working - // on those datatypes. - ModelSafeRoutingInfo routing_info_; - - // The set of groups with enabled types. Computed from - // |routing_info_|. - std::set<ModelSafeGroup> enabled_groups_; - DISALLOW_COPY_AND_ASSIGN(SyncSession); }; diff --git a/sync/sessions/sync_session_unittest.cc b/sync/sessions/sync_session_unittest.cc index 8044113..008e893 100644 --- a/sync/sessions/sync_session_unittest.cc +++ b/sync/sessions/sync_session_unittest.cc @@ -33,10 +33,7 @@ class SyncSessionTest : public testing::Test, SyncSessionTest() : controller_invocations_allowed_(false) {} SyncSession* MakeSession() { - std::vector<ModelSafeWorker*> workers; - GetWorkers(&workers); - return new SyncSession(context_.get(), this, SyncSourceInfo(), - routes_, workers); + return new SyncSession(context_.get(), this, SyncSourceInfo()); } virtual void SetUp() { @@ -142,24 +139,6 @@ class SyncSessionTest : public testing::Test, scoped_ptr<ThrottledDataTypeTracker> throttled_data_type_tracker_; }; -TEST_F(SyncSessionTest, EnabledGroupsEmpty) { - routes_.clear(); - workers_.clear(); - scoped_ptr<SyncSession> session(MakeSession()); - std::set<ModelSafeGroup> expected_enabled_groups; - expected_enabled_groups.insert(GROUP_PASSIVE); - EXPECT_EQ(expected_enabled_groups, session->GetEnabledGroups()); -} - -TEST_F(SyncSessionTest, EnabledGroups) { - scoped_ptr<SyncSession> session(MakeSession()); - std::set<ModelSafeGroup> expected_enabled_groups; - expected_enabled_groups.insert(GROUP_PASSIVE); - expected_enabled_groups.insert(GROUP_UI); - expected_enabled_groups.insert(GROUP_DB); - EXPECT_EQ(expected_enabled_groups, session->GetEnabledGroups()); -} - TEST_F(SyncSessionTest, SetWriteTransaction) { TestDirectorySetterUpper dir_maker; dir_maker.SetUp(); @@ -206,9 +185,7 @@ TEST_F(SyncSessionTest, MoreToDownloadIfGotNoChangesRemaining) { EXPECT_TRUE(status()->download_updates_succeeded()); } -TEST_F(SyncSessionTest, Coalesce) { - std::vector<ModelSafeWorker*> workers_one, workers_two; - ModelSafeRoutingInfo routes_one, routes_two; +TEST_F(SyncSessionTest, CoalesceSources) { ModelTypeInvalidationMap one_type = ModelTypeSetToInvalidationMap( ParamsMeaningJustOneEnabledType(), @@ -220,204 +197,14 @@ TEST_F(SyncSessionTest, Coalesce) { SyncSourceInfo source_one(sync_pb::GetUpdatesCallerInfo::PERIODIC, one_type); SyncSourceInfo source_two(sync_pb::GetUpdatesCallerInfo::LOCAL, all_types); - scoped_refptr<ModelSafeWorker> passive_worker( - new FakeModelWorker(GROUP_PASSIVE)); - scoped_refptr<ModelSafeWorker> db_worker(new FakeModelWorker(GROUP_DB)); - scoped_refptr<ModelSafeWorker> ui_worker(new FakeModelWorker(GROUP_UI)); - workers_one.push_back(passive_worker); - workers_one.push_back(db_worker); - workers_two.push_back(passive_worker); - workers_two.push_back(db_worker); - workers_two.push_back(ui_worker); - routes_one[AUTOFILL] = GROUP_DB; - routes_two[AUTOFILL] = GROUP_DB; - routes_two[BOOKMARKS] = GROUP_UI; - SyncSession one(context_.get(), this, source_one, routes_one, workers_one); - SyncSession two(context_.get(), this, source_two, routes_two, workers_two); - - std::set<ModelSafeGroup> expected_enabled_groups_one; - expected_enabled_groups_one.insert(GROUP_PASSIVE); - expected_enabled_groups_one.insert(GROUP_DB); - - std::set<ModelSafeGroup> expected_enabled_groups_two; - expected_enabled_groups_two.insert(GROUP_PASSIVE); - expected_enabled_groups_two.insert(GROUP_DB); - expected_enabled_groups_two.insert(GROUP_UI); - - EXPECT_EQ(expected_enabled_groups_one, one.GetEnabledGroups()); - EXPECT_EQ(expected_enabled_groups_two, two.GetEnabledGroups()); - - one.Coalesce(two); - - EXPECT_EQ(expected_enabled_groups_two, one.GetEnabledGroups()); - EXPECT_EQ(expected_enabled_groups_two, two.GetEnabledGroups()); - - EXPECT_EQ(two.source().updates_source, one.source().updates_source); - EXPECT_THAT(all_types, Eq(one.source().types)); - std::vector<ModelSafeWorker*>::const_iterator it_db = - std::find(one.workers().begin(), one.workers().end(), db_worker); - std::vector<ModelSafeWorker*>::const_iterator it_ui = - std::find(one.workers().begin(), one.workers().end(), ui_worker); - EXPECT_NE(it_db, one.workers().end()); - EXPECT_NE(it_ui, one.workers().end()); - EXPECT_EQ(routes_two, one.routing_info()); -} - -TEST_F(SyncSessionTest, RebaseRoutingInfoWithLatestRemoveOneType) { - std::vector<ModelSafeWorker*> workers_one, workers_two; - ModelSafeRoutingInfo routes_one, routes_two; - ModelTypeInvalidationMap one_type = - ModelTypeSetToInvalidationMap( - ParamsMeaningJustOneEnabledType(), - std::string()); - ModelTypeInvalidationMap all_types = - ModelTypeSetToInvalidationMap( - ParamsMeaningAllEnabledTypes(), - std::string()); - SyncSourceInfo source_one(sync_pb::GetUpdatesCallerInfo::PERIODIC, one_type); - SyncSourceInfo source_two(sync_pb::GetUpdatesCallerInfo::LOCAL, all_types); + SyncSession session(context_.get(), this, source_one); - scoped_refptr<ModelSafeWorker> passive_worker( - new FakeModelWorker(GROUP_PASSIVE)); - scoped_refptr<ModelSafeWorker> db_worker(new FakeModelWorker(GROUP_DB)); - scoped_refptr<ModelSafeWorker> ui_worker(new FakeModelWorker(GROUP_UI)); - workers_one.push_back(passive_worker); - workers_one.push_back(db_worker); - workers_two.push_back(passive_worker); - workers_two.push_back(db_worker); - workers_two.push_back(ui_worker); - routes_one[AUTOFILL] = GROUP_DB; - routes_two[AUTOFILL] = GROUP_DB; - routes_two[BOOKMARKS] = GROUP_UI; - SyncSession one(context_.get(), this, source_one, routes_one, workers_one); - SyncSession two(context_.get(), this, source_two, routes_two, workers_two); - - std::set<ModelSafeGroup> expected_enabled_groups_one; - expected_enabled_groups_one.insert(GROUP_PASSIVE); - expected_enabled_groups_one.insert(GROUP_DB); - - std::set<ModelSafeGroup> expected_enabled_groups_two; - expected_enabled_groups_two.insert(GROUP_PASSIVE); - expected_enabled_groups_two.insert(GROUP_DB); - expected_enabled_groups_two.insert(GROUP_UI); - - EXPECT_EQ(expected_enabled_groups_one, one.GetEnabledGroups()); - EXPECT_EQ(expected_enabled_groups_two, two.GetEnabledGroups()); - - two.RebaseRoutingInfoWithLatest(one.routing_info(), one.workers()); - - EXPECT_EQ(expected_enabled_groups_one, one.GetEnabledGroups()); - EXPECT_EQ(expected_enabled_groups_one, two.GetEnabledGroups()); - - // Make sure the source has not been touched. - EXPECT_EQ(two.source().updates_source, - sync_pb::GetUpdatesCallerInfo::LOCAL); - - // Make sure the payload is reduced to one. - EXPECT_THAT(one_type, Eq(two.source().types)); - - // Make sure the workers are udpated. - std::vector<ModelSafeWorker*>::const_iterator it_db = - std::find(two.workers().begin(), two.workers().end(), db_worker); - std::vector<ModelSafeWorker*>::const_iterator it_ui = - std::find(two.workers().begin(), two.workers().end(), ui_worker); - EXPECT_NE(it_db, two.workers().end()); - EXPECT_EQ(it_ui, two.workers().end()); - EXPECT_EQ(two.workers().size(), 2U); - - // Make sure the model safe routing info is reduced to one type. - ModelSafeRoutingInfo::const_iterator it = - two.routing_info().find(AUTOFILL); - // Note that attempting to use EXPECT_NE would fail for an Android build due - // to seeming incompatibility with gtest and stlport. - EXPECT_TRUE(it != two.routing_info().end()); - EXPECT_EQ(it->second, GROUP_DB); - EXPECT_EQ(two.routing_info().size(), 1U); -} + session.CoalesceSources(source_two); -TEST_F(SyncSessionTest, RebaseRoutingInfoWithLatestWithSameType) { - std::vector<ModelSafeWorker*> workers_first, workers_second; - ModelSafeRoutingInfo routes_first, routes_second; - ModelTypeInvalidationMap all_types = - ModelTypeSetToInvalidationMap( - ParamsMeaningAllEnabledTypes(), - std::string()); - SyncSourceInfo source_first(sync_pb::GetUpdatesCallerInfo::PERIODIC, - all_types); - SyncSourceInfo source_second(sync_pb::GetUpdatesCallerInfo::LOCAL, - all_types); - - scoped_refptr<ModelSafeWorker> passive_worker( - new FakeModelWorker(GROUP_PASSIVE)); - scoped_refptr<FakeModelWorker> db_worker(new FakeModelWorker(GROUP_DB)); - scoped_refptr<FakeModelWorker> ui_worker(new FakeModelWorker(GROUP_UI)); - workers_first.push_back(passive_worker); - workers_first.push_back(db_worker); - workers_first.push_back(ui_worker); - workers_second.push_back(passive_worker); - workers_second.push_back(db_worker); - workers_second.push_back(ui_worker); - routes_first[AUTOFILL] = GROUP_DB; - routes_first[BOOKMARKS] = GROUP_UI; - routes_second[AUTOFILL] = GROUP_DB; - routes_second[BOOKMARKS] = GROUP_UI; - SyncSession first(context_.get(), this, source_first, routes_first, - workers_first); - SyncSession second(context_.get(), this, source_second, routes_second, - workers_second); - - std::set<ModelSafeGroup> expected_enabled_groups; - expected_enabled_groups.insert(GROUP_PASSIVE); - expected_enabled_groups.insert(GROUP_DB); - expected_enabled_groups.insert(GROUP_UI); - - EXPECT_EQ(expected_enabled_groups, first.GetEnabledGroups()); - EXPECT_EQ(expected_enabled_groups, second.GetEnabledGroups()); - - second.RebaseRoutingInfoWithLatest(first.routing_info(), first.workers()); - - EXPECT_EQ(expected_enabled_groups, first.GetEnabledGroups()); - EXPECT_EQ(expected_enabled_groups, second.GetEnabledGroups()); - - // Make sure the source has not been touched. - EXPECT_EQ(second.source().updates_source, - sync_pb::GetUpdatesCallerInfo::LOCAL); - - // Make sure our payload is still the same. - EXPECT_THAT(all_types, Eq(second.source().types)); - - // Make sure the workers are still the same. - std::vector<ModelSafeWorker*>::const_iterator it_passive = - std::find(second.workers().begin(), second.workers().end(), - passive_worker); - std::vector<ModelSafeWorker*>::const_iterator it_db = - std::find(second.workers().begin(), second.workers().end(), db_worker); - std::vector<ModelSafeWorker*>::const_iterator it_ui = - std::find(second.workers().begin(), second.workers().end(), ui_worker); - EXPECT_NE(it_passive, second.workers().end()); - EXPECT_NE(it_db, second.workers().end()); - EXPECT_NE(it_ui, second.workers().end()); - EXPECT_EQ(second.workers().size(), 3U); - - // Make sure the model safe routing info is reduced to first type. - ModelSafeRoutingInfo::const_iterator it1 = - second.routing_info().find(AUTOFILL); - ModelSafeRoutingInfo::const_iterator it2 = - second.routing_info().find(BOOKMARKS); - - // Note that attempting to use EXPECT_NE would fail for an Android build due - // to seeming incompatibility with gtest and stlport. - EXPECT_TRUE(it1 != second.routing_info().end()); - EXPECT_EQ(it1->second, GROUP_DB); - - // Note that attempting to use EXPECT_NE would fail for an Android build due - // to seeming incompatibility with gtest and stlport. - EXPECT_TRUE(it2 != second.routing_info().end()); - EXPECT_EQ(it2->second, GROUP_UI); - EXPECT_EQ(second.routing_info().size(), 2U); + EXPECT_EQ(source_two.updates_source, session.source().updates_source); + EXPECT_THAT(all_types, Eq(session.source().types)); } - TEST_F(SyncSessionTest, MakeTypeInvalidationMapFromBitSet) { ModelTypeSet types; std::string payload = "test"; |