diff options
Diffstat (limited to 'chromium/sync/notifier/sync_invalidation_listener_unittest.cc')
-rw-r--r-- | chromium/sync/notifier/sync_invalidation_listener_unittest.cc | 1127 |
1 files changed, 0 insertions, 1127 deletions
diff --git a/chromium/sync/notifier/sync_invalidation_listener_unittest.cc b/chromium/sync/notifier/sync_invalidation_listener_unittest.cc deleted file mode 100644 index 2808b9727a7..00000000000 --- a/chromium/sync/notifier/sync_invalidation_listener_unittest.cc +++ /dev/null @@ -1,1127 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <cstddef> -#include <map> -#include <set> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/message_loop/message_loop.h" -#include "base/stl_util.h" -#include "google/cacheinvalidation/include/invalidation-client.h" -#include "google/cacheinvalidation/include/types.h" -#include "jingle/notifier/listener/fake_push_client.h" -#include "sync/internal_api/public/util/weak_handle.h" -#include "sync/notifier/dropped_invalidation_tracker.h" -#include "sync/notifier/fake_invalidation_state_tracker.h" -#include "sync/notifier/invalidation_util.h" -#include "sync/notifier/object_id_invalidation_map.h" -#include "sync/notifier/sync_invalidation_listener.h" -#include "sync/notifier/unacked_invalidation_set_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace syncer { - -namespace { - -using invalidation::AckHandle; -using invalidation::ObjectId; - -const char kClientId[] = "client_id"; -const char kClientInfo[] = "client_info"; - -const char kState[] = "state"; -const char kNewState[] = "new_state"; - -const char kPayload1[] = "payload1"; -const char kPayload2[] = "payload2"; - -const int64 kVersion1 = 1LL; -const int64 kVersion2 = 2LL; - -const int kChromeSyncSourceId = 1004; - -struct AckHandleLessThan { - bool operator()(const AckHandle& lhs, const AckHandle& rhs) const { - return lhs.handle_data() < rhs.handle_data(); - } -}; - -typedef std::set<AckHandle, AckHandleLessThan> AckHandleSet; - -// Fake invalidation::InvalidationClient implementation that keeps -// track of registered IDs and acked handles. -class FakeInvalidationClient : public invalidation::InvalidationClient { - public: - FakeInvalidationClient() : started_(false) {} - virtual ~FakeInvalidationClient() {} - - const ObjectIdSet& GetRegisteredIds() const { - return registered_ids_; - } - - void ClearAckedHandles() { - acked_handles_.clear(); - } - - bool IsAckedHandle(const AckHandle& ack_handle) const { - return (acked_handles_.find(ack_handle) != acked_handles_.end()); - } - - // invalidation::InvalidationClient implementation. - - virtual void Start() OVERRIDE { - started_ = true; - } - - virtual void Stop() OVERRIDE { - started_ = false; - } - - virtual void Register(const ObjectId& object_id) OVERRIDE { - if (!started_) { - ADD_FAILURE(); - return; - } - registered_ids_.insert(object_id); - } - - virtual void Register( - const invalidation::vector<ObjectId>& object_ids) OVERRIDE { - if (!started_) { - ADD_FAILURE(); - return; - } - registered_ids_.insert(object_ids.begin(), object_ids.end()); - } - - virtual void Unregister(const ObjectId& object_id) OVERRIDE { - if (!started_) { - ADD_FAILURE(); - return; - } - registered_ids_.erase(object_id); - } - - virtual void Unregister( - const invalidation::vector<ObjectId>& object_ids) OVERRIDE { - if (!started_) { - ADD_FAILURE(); - return; - } - for (invalidation::vector<ObjectId>::const_iterator - it = object_ids.begin(); it != object_ids.end(); ++it) { - registered_ids_.erase(*it); - } - } - - virtual void Acknowledge(const AckHandle& ack_handle) OVERRIDE { - if (!started_) { - ADD_FAILURE(); - return; - } - acked_handles_.insert(ack_handle); - } - - private: - bool started_; - ObjectIdSet registered_ids_; - AckHandleSet acked_handles_; -}; - -// Fake delegate tkat keeps track of invalidation counts, payloads, -// and state. -class FakeDelegate : public SyncInvalidationListener::Delegate { - public: - explicit FakeDelegate(SyncInvalidationListener* listener) - : state_(TRANSIENT_INVALIDATION_ERROR), - drop_handlers_deleter_(&drop_handlers_) {} - virtual ~FakeDelegate() {} - - size_t GetInvalidationCount(const ObjectId& id) const { - Map::const_iterator it = invalidations_.find(id); - if (it == invalidations_.end()) { - return 0; - } else { - return it->second.size(); - } - } - - int64 GetVersion(const ObjectId& id) const { - Map::const_iterator it = invalidations_.find(id); - if (it == invalidations_.end()) { - ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id); - return 0; - } else { - return it->second.back().version(); - } - } - - std::string GetPayload(const ObjectId& id) const { - Map::const_iterator it = invalidations_.find(id); - if (it == invalidations_.end()) { - ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id); - return 0; - } else { - return it->second.back().payload(); - } - } - - bool IsUnknownVersion(const ObjectId& id) const { - Map::const_iterator it = invalidations_.find(id); - if (it == invalidations_.end()) { - ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id); - return false; - } else { - return it->second.back().is_unknown_version(); - } - } - - bool StartsWithUnknownVersion(const ObjectId& id) const { - Map::const_iterator it = invalidations_.find(id); - if (it == invalidations_.end()) { - ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id); - return false; - } else { - return it->second.front().is_unknown_version(); - } - } - - InvalidatorState GetInvalidatorState() const { - return state_; - } - - DroppedInvalidationTracker* GetDropTrackerForObject(const ObjectId& id) { - DropHandlers::iterator it = drop_handlers_.find(id); - if (it == drop_handlers_.end()) { - drop_handlers_.insert( - std::make_pair(id, new DroppedInvalidationTracker(id))); - return drop_handlers_.find(id)->second; - } else { - return it->second; - } - } - - void AcknowledgeNthInvalidation(const ObjectId& id, size_t n) { - List& list = invalidations_[id]; - List::iterator it = list.begin() + n; - it->Acknowledge(); - } - - void AcknowledgeAll(const ObjectId& id) { - List& list = invalidations_[id]; - for (List::iterator it = list.begin(); it != list.end(); ++it) { - it->Acknowledge(); - } - } - - void DropNthInvalidation(const ObjectId& id, size_t n) { - DroppedInvalidationTracker* drop_tracker = GetDropTrackerForObject(id); - List& list = invalidations_[id]; - List::iterator it = list.begin() + n; - it->Drop(drop_tracker); - } - - void RecoverFromDropEvent(const ObjectId& id) { - DroppedInvalidationTracker* drop_tracker = GetDropTrackerForObject(id); - drop_tracker->RecordRecoveryFromDropEvent(); - } - - // SyncInvalidationListener::Delegate implementation. - virtual void OnInvalidate( - const ObjectIdInvalidationMap& invalidation_map) OVERRIDE { - ObjectIdSet ids = invalidation_map.GetObjectIds(); - for (ObjectIdSet::iterator it = ids.begin(); it != ids.end(); ++it) { - const SingleObjectInvalidationSet& incoming = - invalidation_map.ForObject(*it); - List& list = invalidations_[*it]; - list.insert(list.end(), incoming.begin(), incoming.end()); - } - } - - virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE { - state_ = state; - } - - private: - typedef std::vector<Invalidation> List; - typedef std::map<ObjectId, List, ObjectIdLessThan> Map; - typedef std::map<ObjectId, - DroppedInvalidationTracker*, - ObjectIdLessThan> DropHandlers; - - Map invalidations_; - InvalidatorState state_; - DropHandlers drop_handlers_; - STLValueDeleter<DropHandlers> drop_handlers_deleter_; -}; - -invalidation::InvalidationClient* CreateFakeInvalidationClient( - FakeInvalidationClient** fake_invalidation_client, - invalidation::SystemResources* resources, - int client_type, - const invalidation::string& client_name, - const invalidation::string& application_name, - invalidation::InvalidationListener* listener) { - *fake_invalidation_client = new FakeInvalidationClient(); - return *fake_invalidation_client; -} - -class SyncInvalidationListenerTest : public testing::Test { - protected: - SyncInvalidationListenerTest() - : kBookmarksId_(kChromeSyncSourceId, "BOOKMARK"), - kPreferencesId_(kChromeSyncSourceId, "PREFERENCE"), - kExtensionsId_(kChromeSyncSourceId, "EXTENSION"), - kAppsId_(kChromeSyncSourceId, "APP"), - fake_push_client_(new notifier::FakePushClient()), - fake_invalidation_client_(NULL), - listener_(scoped_ptr<notifier::PushClient>(fake_push_client_)), - fake_delegate_(&listener_) {} - - virtual void SetUp() { - StartClient(); - - registered_ids_.insert(kBookmarksId_); - registered_ids_.insert(kPreferencesId_); - listener_.UpdateRegisteredIds(registered_ids_); - } - - virtual void TearDown() { - StopClient(); - } - - // Restart client without re-registering IDs. - void RestartClient() { - StopClient(); - StartClient(); - } - - void StartClient() { - fake_invalidation_client_ = NULL; - listener_.Start(base::Bind(&CreateFakeInvalidationClient, - &fake_invalidation_client_), - kClientId, kClientInfo, kState, - fake_tracker_.GetSavedInvalidations(), - MakeWeakHandle(fake_tracker_.AsWeakPtr()), - &fake_delegate_); - DCHECK(fake_invalidation_client_); - } - - void StopClient() { - // listener_.StopForTest() stops the invalidation scheduler, which - // deletes any pending tasks without running them. Some tasks - // "run and delete" another task, so they must be run in order to - // avoid leaking the inner task. listener_.StopForTest() does not - // schedule any tasks, so it's both necessary and sufficient to - // drain the task queue before calling it. - FlushPendingWrites(); - fake_invalidation_client_ = NULL; - listener_.StopForTest(); - } - - size_t GetInvalidationCount(const ObjectId& id) const { - return fake_delegate_.GetInvalidationCount(id); - } - - int64 GetVersion(const ObjectId& id) const { - return fake_delegate_.GetVersion(id); - } - - std::string GetPayload(const ObjectId& id) const { - return fake_delegate_.GetPayload(id); - } - - bool IsUnknownVersion(const ObjectId& id) const { - return fake_delegate_.IsUnknownVersion(id); - } - - bool StartsWithUnknownVersion(const ObjectId& id) const { - return fake_delegate_.StartsWithUnknownVersion(id); - } - - void AcknowledgeNthInvalidation(const ObjectId& id, size_t n) { - fake_delegate_.AcknowledgeNthInvalidation(id, n); - } - - void DropNthInvalidation(const ObjectId& id, size_t n) { - return fake_delegate_.DropNthInvalidation(id, n); - } - - void RecoverFromDropEvent(const ObjectId& id) { - return fake_delegate_.RecoverFromDropEvent(id); - } - - void AcknowledgeAll(const ObjectId& id) { - fake_delegate_.AcknowledgeAll(id); - } - - InvalidatorState GetInvalidatorState() const { - return fake_delegate_.GetInvalidatorState(); - } - - std::string GetInvalidatorClientId() const { - return fake_tracker_.GetInvalidatorClientId(); - } - - std::string GetBootstrapData() const { - return fake_tracker_.GetBootstrapData(); - } - - UnackedInvalidationsMap GetSavedInvalidations() { - // Allow any queued writes to go through first. - FlushPendingWrites(); - return fake_tracker_.GetSavedInvalidations(); - } - - SingleObjectInvalidationSet GetSavedInvalidationsForType(const ObjectId& id) { - const UnackedInvalidationsMap& saved_state = GetSavedInvalidations(); - UnackedInvalidationsMap::const_iterator it = - saved_state.find(kBookmarksId_); - if (it == saved_state.end()) { - ADD_FAILURE() << "No state saved for ID " << ObjectIdToString(id); - return SingleObjectInvalidationSet(); - } - ObjectIdInvalidationMap map; - it->second.ExportInvalidations(WeakHandle<AckHandler>(), &map); - if (map.Empty()) { - return SingleObjectInvalidationSet(); - } else { - return map.ForObject(id); - } - } - - ObjectIdSet GetRegisteredIds() const { - return fake_invalidation_client_->GetRegisteredIds(); - } - - // |payload| can be NULL. - void FireInvalidate(const ObjectId& object_id, - int64 version, const char* payload) { - invalidation::Invalidation inv; - if (payload) { - inv = invalidation::Invalidation(object_id, version, payload); - } else { - inv = invalidation::Invalidation(object_id, version); - } - const AckHandle ack_handle("fakedata"); - fake_invalidation_client_->ClearAckedHandles(); - listener_.Invalidate(fake_invalidation_client_, inv, ack_handle); - EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle)); - } - - // |payload| can be NULL, but not |type_name|. - void FireInvalidateUnknownVersion(const ObjectId& object_id) { - const AckHandle ack_handle("fakedata_unknown"); - fake_invalidation_client_->ClearAckedHandles(); - listener_.InvalidateUnknownVersion(fake_invalidation_client_, - object_id, - ack_handle); - EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle)); - } - - void FireInvalidateAll() { - const AckHandle ack_handle("fakedata_all"); - fake_invalidation_client_->ClearAckedHandles(); - listener_.InvalidateAll(fake_invalidation_client_, ack_handle); - EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle)); - } - - void WriteState(const std::string& new_state) { - listener_.WriteState(new_state); - - // Pump message loop to trigger - // InvalidationStateTracker::WriteState(). - FlushPendingWrites(); - } - - void FlushPendingWrites() { - message_loop_.RunUntilIdle(); - } - - void EnableNotifications() { - fake_push_client_->EnableNotifications(); - } - - void DisableNotifications(notifier::NotificationsDisabledReason reason) { - fake_push_client_->DisableNotifications(reason); - } - - const ObjectId kBookmarksId_; - const ObjectId kPreferencesId_; - const ObjectId kExtensionsId_; - const ObjectId kAppsId_; - - ObjectIdSet registered_ids_; - - private: - base::MessageLoop message_loop_; - notifier::FakePushClient* const fake_push_client_; - - protected: - // A derrived test needs direct access to this. - FakeInvalidationStateTracker fake_tracker_; - - // Tests need to access these directly. - FakeInvalidationClient* fake_invalidation_client_; - SyncInvalidationListener listener_; - - private: - FakeDelegate fake_delegate_; -}; - -// Write a new state to the client. It should propagate to the -// tracker. -TEST_F(SyncInvalidationListenerTest, WriteState) { - WriteState(kNewState); - - EXPECT_EQ(kNewState, GetBootstrapData()); -} - -// Invalidation tests. - -// Fire an invalidation without a payload. It should be processed, -// the payload should remain empty, and the version should be updated. -TEST_F(SyncInvalidationListenerTest, InvalidateNoPayload) { - const ObjectId& id = kBookmarksId_; - - FireInvalidate(id, kVersion1, NULL); - - ASSERT_EQ(1U, GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - EXPECT_EQ(kVersion1, GetVersion(id)); - EXPECT_EQ("", GetPayload(id)); -} - -// Fire an invalidation with an empty payload. It should be -// processed, the payload should remain empty, and the version should -// be updated. -TEST_F(SyncInvalidationListenerTest, InvalidateEmptyPayload) { - const ObjectId& id = kBookmarksId_; - - FireInvalidate(id, kVersion1, ""); - - ASSERT_EQ(1U, GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - EXPECT_EQ(kVersion1, GetVersion(id)); - EXPECT_EQ("", GetPayload(id)); -} - -// Fire an invalidation with a payload. It should be processed, and -// both the payload and the version should be updated. -TEST_F(SyncInvalidationListenerTest, InvalidateWithPayload) { - const ObjectId& id = kPreferencesId_; - - FireInvalidate(id, kVersion1, kPayload1); - - ASSERT_EQ(1U, GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - EXPECT_EQ(kVersion1, GetVersion(id)); - EXPECT_EQ(kPayload1, GetPayload(id)); -} - -// Fire ten invalidations in a row. All should be received. -TEST_F(SyncInvalidationListenerTest, ManyInvalidations_NoDrop) { - const int kRepeatCount = 10; - const ObjectId& id = kPreferencesId_; - int64 initial_version = kVersion1; - for (int64 i = initial_version; i < initial_version + kRepeatCount; ++i) { - FireInvalidate(id, i, kPayload1); - } - ASSERT_EQ(static_cast<size_t>(kRepeatCount), GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - EXPECT_EQ(kPayload1, GetPayload(id)); - EXPECT_EQ(initial_version + kRepeatCount - 1, GetVersion(id)); -} - -// Fire an invalidation for an unregistered object ID with a payload. It should -// still be processed, and both the payload and the version should be updated. -TEST_F(SyncInvalidationListenerTest, InvalidateBeforeRegistration_Simple) { - const ObjectId kUnregisteredId(kChromeSyncSourceId, "unregistered"); - const ObjectId& id = kUnregisteredId; - ObjectIdSet ids; - ids.insert(id); - - EXPECT_EQ(0U, GetInvalidationCount(id)); - - FireInvalidate(id, kVersion1, kPayload1); - - ASSERT_EQ(0U, GetInvalidationCount(id)); - - EnableNotifications(); - listener_.Ready(fake_invalidation_client_); - listener_.UpdateRegisteredIds(ids); - - ASSERT_EQ(1U, GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - EXPECT_EQ(kVersion1, GetVersion(id)); - EXPECT_EQ(kPayload1, GetPayload(id)); -} - -// Fire ten invalidations before an object registers. Some invalidations will -// be dropped an replaced with an unknown version invalidation. -TEST_F(SyncInvalidationListenerTest, InvalidateBeforeRegistration_Drop) { - const int kRepeatCount = - UnackedInvalidationSet::kMaxBufferedInvalidations + 1; - const ObjectId kUnregisteredId(kChromeSyncSourceId, "unregistered"); - const ObjectId& id = kUnregisteredId; - ObjectIdSet ids; - ids.insert(id); - - EXPECT_EQ(0U, GetInvalidationCount(id)); - - int64 initial_version = kVersion1; - for (int64 i = initial_version; i < initial_version + kRepeatCount; ++i) { - FireInvalidate(id, i, kPayload1); - } - - EnableNotifications(); - listener_.Ready(fake_invalidation_client_); - listener_.UpdateRegisteredIds(ids); - - ASSERT_EQ(UnackedInvalidationSet::kMaxBufferedInvalidations, - GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - EXPECT_EQ(initial_version + kRepeatCount - 1, GetVersion(id)); - EXPECT_EQ(kPayload1, GetPayload(id)); - EXPECT_TRUE(StartsWithUnknownVersion(id)); -} - -// Fire an invalidation, then fire another one with a lower version. Both -// should be received. -TEST_F(SyncInvalidationListenerTest, InvalidateVersion) { - const ObjectId& id = kPreferencesId_; - - FireInvalidate(id, kVersion2, kPayload2); - - ASSERT_EQ(1U, GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - EXPECT_EQ(kVersion2, GetVersion(id)); - EXPECT_EQ(kPayload2, GetPayload(id)); - - FireInvalidate(id, kVersion1, kPayload1); - - ASSERT_EQ(2U, GetInvalidationCount(id)); - ASSERT_FALSE(IsUnknownVersion(id)); - - EXPECT_EQ(kVersion1, GetVersion(id)); - EXPECT_EQ(kPayload1, GetPayload(id)); -} - -// Fire an invalidation with an unknown version. -TEST_F(SyncInvalidationListenerTest, InvalidateUnknownVersion) { - const ObjectId& id = kBookmarksId_; - - FireInvalidateUnknownVersion(id); - - ASSERT_EQ(1U, GetInvalidationCount(id)); - EXPECT_TRUE(IsUnknownVersion(id)); -} - -// Fire an invalidation for all enabled IDs. -TEST_F(SyncInvalidationListenerTest, InvalidateAll) { - FireInvalidateAll(); - - for (ObjectIdSet::const_iterator it = registered_ids_.begin(); - it != registered_ids_.end(); ++it) { - ASSERT_EQ(1U, GetInvalidationCount(*it)); - EXPECT_TRUE(IsUnknownVersion(*it)); - } -} - -// Test a simple scenario for multiple IDs. -TEST_F(SyncInvalidationListenerTest, InvalidateMultipleIds) { - FireInvalidate(kBookmarksId_, 3, NULL); - - ASSERT_EQ(1U, GetInvalidationCount(kBookmarksId_)); - ASSERT_FALSE(IsUnknownVersion(kBookmarksId_)); - EXPECT_EQ(3, GetVersion(kBookmarksId_)); - EXPECT_EQ("", GetPayload(kBookmarksId_)); - - // kExtensionId is not registered, so the invalidation should not get through. - FireInvalidate(kExtensionsId_, 2, NULL); - ASSERT_EQ(0U, GetInvalidationCount(kExtensionsId_)); -} - -// Registration tests. - -// With IDs already registered, enable notifications then ready the -// client. The IDs should be registered only after the client is -// readied. -TEST_F(SyncInvalidationListenerTest, RegisterEnableReady) { - EXPECT_TRUE(GetRegisteredIds().empty()); - - EnableNotifications(); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); -} - -// With IDs already registered, ready the client then enable -// notifications. The IDs should be registered after the client is -// readied. -TEST_F(SyncInvalidationListenerTest, RegisterReadyEnable) { - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); - - EnableNotifications(); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); -} - -// Unregister the IDs, enable notifications, re-register the IDs, then -// ready the client. The IDs should be registered only after the -// client is readied. -TEST_F(SyncInvalidationListenerTest, EnableRegisterReady) { - listener_.UpdateRegisteredIds(ObjectIdSet()); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - EnableNotifications(); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.UpdateRegisteredIds(registered_ids_); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); -} - -// Unregister the IDs, enable notifications, ready the client, then -// re-register the IDs. The IDs should be registered only after the -// client is readied. -TEST_F(SyncInvalidationListenerTest, EnableReadyRegister) { - listener_.UpdateRegisteredIds(ObjectIdSet()); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - EnableNotifications(); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.UpdateRegisteredIds(registered_ids_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); -} - -// Unregister the IDs, ready the client, enable notifications, then -// re-register the IDs. The IDs should be registered only after the -// client is readied. -TEST_F(SyncInvalidationListenerTest, ReadyEnableRegister) { - listener_.UpdateRegisteredIds(ObjectIdSet()); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - EnableNotifications(); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.UpdateRegisteredIds(registered_ids_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); -} - -// Unregister the IDs, ready the client, re-register the IDs, then -// enable notifications. The IDs should be registered only after the -// client is readied. -// -// This test is important: see http://crbug.com/139424. -TEST_F(SyncInvalidationListenerTest, ReadyRegisterEnable) { - listener_.UpdateRegisteredIds(ObjectIdSet()); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.UpdateRegisteredIds(registered_ids_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); - - EnableNotifications(); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); -} - -// With IDs already registered, ready the client, restart the client, -// then re-ready it. The IDs should still be registered. -TEST_F(SyncInvalidationListenerTest, RegisterTypesPreserved) { - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); - - RestartClient(); - - EXPECT_TRUE(GetRegisteredIds().empty()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(registered_ids_, GetRegisteredIds()); -} - -// Make sure that state is correctly purged from the local invalidation state -// map cache when an ID is unregistered. -TEST_F(SyncInvalidationListenerTest, UnregisterCleansUpStateMapCache) { - const ObjectId& id = kBookmarksId_; - listener_.Ready(fake_invalidation_client_); - - EXPECT_TRUE(GetSavedInvalidations().empty()); - FireInvalidate(id, 1, "hello"); - EXPECT_EQ(1U, GetSavedInvalidations().size()); - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id)); - FireInvalidate(kPreferencesId_, 2, "world"); - EXPECT_EQ(2U, GetSavedInvalidations().size()); - - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id)); - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), kPreferencesId_)); - - ObjectIdSet ids; - ids.insert(id); - listener_.UpdateRegisteredIds(ids); - EXPECT_EQ(1U, GetSavedInvalidations().size()); - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id)); -} - -TEST_F(SyncInvalidationListenerTest, DuplicateInvaldiations_Simple) { - const ObjectId& id = kBookmarksId_; - listener_.Ready(fake_invalidation_client_); - - // Send a stream of invalidations, including two copies of the second. - FireInvalidate(id, 1, "one"); - FireInvalidate(id, 2, "two"); - FireInvalidate(id, 3, "three"); - FireInvalidate(id, 2, "two"); - - // Expect that the duplicate was discarded. - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - EXPECT_EQ(3U, list.GetSize()); - SingleObjectInvalidationSet::const_iterator it = list.begin(); - EXPECT_EQ(1, it->version()); - it++; - EXPECT_EQ(2, it->version()); - it++; - EXPECT_EQ(3, it->version()); -} - -TEST_F(SyncInvalidationListenerTest, DuplicateInvalidations_NearBufferLimit) { - const size_t kPairsToSend = UnackedInvalidationSet::kMaxBufferedInvalidations; - const ObjectId& id = kBookmarksId_; - listener_.Ready(fake_invalidation_client_); - - // We will have enough buffer space in the state tracker for all these - // invalidations only if duplicates are ignored. - for (size_t i = 0; i < kPairsToSend; ++i) { - FireInvalidate(id, i, "payload"); - FireInvalidate(id, i, "payload"); - } - - // Expect that the state map ignored duplicates. - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - EXPECT_EQ(kPairsToSend, list.GetSize()); - EXPECT_FALSE(list.begin()->is_unknown_version()); - - // Expect that all invalidations (including duplicates) were emitted. - EXPECT_EQ(kPairsToSend*2, GetInvalidationCount(id)); - - // Acknowledge all invalidations to clear the internal state. - AcknowledgeAll(id); - EXPECT_TRUE(GetSavedInvalidationsForType(id).IsEmpty()); -} - -TEST_F(SyncInvalidationListenerTest, DuplicateInvalidations_UnknownVersion) { - const ObjectId& id = kBookmarksId_; - listener_.Ready(fake_invalidation_client_); - - FireInvalidateUnknownVersion(id); - FireInvalidateUnknownVersion(id); - - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - EXPECT_EQ(1U, list.GetSize()); - } - - // Acknowledge the second. There should be no effect on the stored list. - ASSERT_EQ(2U, GetInvalidationCount(id)); - AcknowledgeNthInvalidation(id, 1); - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - EXPECT_EQ(1U, list.GetSize()); - } - - // Acknowledge the first. This should remove the invalidation from the list. - ASSERT_EQ(2U, GetInvalidationCount(id)); - AcknowledgeNthInvalidation(id, 0); - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - EXPECT_EQ(0U, list.GetSize()); - } -} - -// Make sure that acknowledgements erase items from the local store. -TEST_F(SyncInvalidationListenerTest, AcknowledgementsCleanUpStateMapCache) { - const ObjectId& id = kBookmarksId_; - listener_.Ready(fake_invalidation_client_); - - EXPECT_TRUE(GetSavedInvalidations().empty()); - FireInvalidate(id, 10, "hello"); - FireInvalidate(id, 20, "world"); - FireInvalidateUnknownVersion(id); - - // Expect that all three invalidations have been saved to permanent storage. - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - ASSERT_EQ(3U, list.GetSize()); - EXPECT_TRUE(list.begin()->is_unknown_version()); - EXPECT_EQ(20, list.back().version()); - } - - // Acknowledge the second sent invaldiation (version 20) and verify it was - // removed from storage. - AcknowledgeNthInvalidation(id, 1); - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - ASSERT_EQ(2U, list.GetSize()); - EXPECT_TRUE(list.begin()->is_unknown_version()); - EXPECT_EQ(10, list.back().version()); - } - - // Acknowledge the last sent invalidation (unknown version) and verify it was - // removed from storage. - AcknowledgeNthInvalidation(id, 2); - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - ASSERT_EQ(1U, list.GetSize()); - EXPECT_FALSE(list.begin()->is_unknown_version()); - EXPECT_EQ(10, list.back().version()); - } -} - -// Make sure that drops erase items from the local store. -TEST_F(SyncInvalidationListenerTest, DropsCleanUpStateMapCache) { - const ObjectId& id = kBookmarksId_; - listener_.Ready(fake_invalidation_client_); - - EXPECT_TRUE(GetSavedInvalidations().empty()); - FireInvalidate(id, 10, "hello"); - FireInvalidate(id, 20, "world"); - FireInvalidateUnknownVersion(id); - - // Expect that all three invalidations have been saved to permanent storage. - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - ASSERT_EQ(3U, list.GetSize()); - EXPECT_TRUE(list.begin()->is_unknown_version()); - EXPECT_EQ(20, list.back().version()); - } - - // Drop the second sent invalidation (version 20) and verify it was removed - // from storage. Also verify we still have an unknown version invalidation. - DropNthInvalidation(id, 1); - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - ASSERT_EQ(2U, list.GetSize()); - EXPECT_TRUE(list.begin()->is_unknown_version()); - EXPECT_EQ(10, list.back().version()); - } - - // Drop the remaining invalidation. Verify an unknown version is all that - // remains. - DropNthInvalidation(id, 0); - { - SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id); - ASSERT_EQ(1U, list.GetSize()); - EXPECT_TRUE(list.begin()->is_unknown_version()); - } - - // Announce that the delegate has recovered from the drop. Verify no - // invalidations remain saved. - RecoverFromDropEvent(id); - EXPECT_TRUE(GetSavedInvalidationsForType(id).IsEmpty()); - - RecoverFromDropEvent(id); -} - -// Without readying the client, disable notifications, then enable -// them. The listener should still think notifications are disabled. -TEST_F(SyncInvalidationListenerTest, EnableNotificationsNotReady) { - EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, - GetInvalidatorState()); - - DisableNotifications( - notifier::TRANSIENT_NOTIFICATION_ERROR); - - EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState()); - - DisableNotifications(notifier::NOTIFICATION_CREDENTIALS_REJECTED); - - EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState()); - - EnableNotifications(); - - EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState()); -} - -// Enable notifications then Ready the invalidation client. The -// delegate should then be ready. -TEST_F(SyncInvalidationListenerTest, EnableNotificationsThenReady) { - EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState()); - - EnableNotifications(); - - EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState()); -} - -// Ready the invalidation client then enable notifications. The -// delegate should then be ready. -TEST_F(SyncInvalidationListenerTest, ReadyThenEnableNotifications) { - EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState()); - - EnableNotifications(); - - EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState()); -} - -// Enable notifications and ready the client. Then disable -// notifications with an auth error and re-enable notifications. The -// delegate should go into an auth error mode and then back out. -TEST_F(SyncInvalidationListenerTest, PushClientAuthError) { - EnableNotifications(); - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState()); - - DisableNotifications( - notifier::NOTIFICATION_CREDENTIALS_REJECTED); - - EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState()); - - EnableNotifications(); - - EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState()); -} - -// Enable notifications and ready the client. Then simulate an auth -// error from the invalidation client. Simulate some notification -// events, then re-ready the client. The delegate should go into an -// auth error mode and come out of it only after the client is ready. -TEST_F(SyncInvalidationListenerTest, InvalidationClientAuthError) { - EnableNotifications(); - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState()); - - listener_.InformError( - fake_invalidation_client_, - invalidation::ErrorInfo( - invalidation::ErrorReason::AUTH_FAILURE, - false /* is_transient */, - "auth error", - invalidation::ErrorContext())); - - EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState()); - - DisableNotifications(notifier::TRANSIENT_NOTIFICATION_ERROR); - - EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState()); - - DisableNotifications(notifier::TRANSIENT_NOTIFICATION_ERROR); - - EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState()); - - EnableNotifications(); - - EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState()); - - listener_.Ready(fake_invalidation_client_); - - EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState()); -} - -// A variant of SyncInvalidationListenerTest that starts with some initial -// state. We make not attempt to abstract away the contents of this state. The -// tests that make use of this harness depend on its implementation details. -class SyncInvalidationListenerTest_WithInitialState - : public SyncInvalidationListenerTest { - public: - virtual void SetUp() { - UnackedInvalidationSet bm_state(kBookmarksId_); - UnackedInvalidationSet ext_state(kExtensionsId_); - - Invalidation bm_unknown = Invalidation::InitUnknownVersion(kBookmarksId_); - Invalidation bm_v100 = Invalidation::Init(kBookmarksId_, 100, "hundred"); - bm_state.Add(bm_unknown); - bm_state.Add(bm_v100); - - Invalidation ext_v10 = Invalidation::Init(kExtensionsId_, 10, "ten"); - Invalidation ext_v20 = Invalidation::Init(kExtensionsId_, 20, "twenty"); - ext_state.Add(ext_v10); - ext_state.Add(ext_v20); - - initial_state.insert(std::make_pair(kBookmarksId_, bm_state)); - initial_state.insert(std::make_pair(kExtensionsId_, ext_state)); - - fake_tracker_.SetSavedInvalidations(initial_state); - - SyncInvalidationListenerTest::SetUp(); - } - - UnackedInvalidationsMap initial_state; -}; - -// Verify that saved invalidations are forwarded when handlers register. -TEST_F(SyncInvalidationListenerTest_WithInitialState, - ReceiveSavedInvalidations) { - EnableNotifications(); - listener_.Ready(fake_invalidation_client_); - - EXPECT_THAT(initial_state, test_util::Eq(GetSavedInvalidations())); - - ASSERT_EQ(2U, GetInvalidationCount(kBookmarksId_)); - EXPECT_EQ(100, GetVersion(kBookmarksId_)); - - ASSERT_EQ(0U, GetInvalidationCount(kExtensionsId_)); - - FireInvalidate(kExtensionsId_, 30, "thirty"); - - ObjectIdSet ids = GetRegisteredIds(); - ids.insert(kExtensionsId_); - listener_.UpdateRegisteredIds(ids); - - ASSERT_EQ(3U, GetInvalidationCount(kExtensionsId_)); - EXPECT_EQ(30, GetVersion(kExtensionsId_)); -} - -} // namespace - -} // namespace syncer |