| Index: sync/notifier/sync_invalidation_listener_unittest.cc
|
| diff --git a/sync/notifier/sync_invalidation_listener_unittest.cc b/sync/notifier/sync_invalidation_listener_unittest.cc
|
| index a335060cbfed4e27bde760a14e0fcb55095634ea..39d7e24e07b8fe66b4ab1b5c1c4ee8a78f27b773 100644
|
| --- a/sync/notifier/sync_invalidation_listener_unittest.cc
|
| +++ b/sync/notifier/sync_invalidation_listener_unittest.cc
|
| @@ -8,9 +8,11 @@
|
|
|
| #include "base/compiler_specific.h"
|
| #include "base/message_loop.h"
|
| +#include "base/time.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/base/invalidation_test_util.h"
|
| #include "sync/internal_api/public/util/weak_handle.h"
|
| #include "sync/notifier/fake_invalidation_state_tracker.h"
|
| #include "sync/notifier/invalidation_util.h"
|
| @@ -19,6 +21,13 @@
|
|
|
| namespace syncer {
|
|
|
| +// TODO(dcheng): Duplicated from invalidator_storage_unittest.cc.
|
| +bool operator==(const LocalState& lhs, const LocalState& rhs) {
|
| + return lhs.version == rhs.version &&
|
| + lhs.expected.Equals(rhs.expected) &&
|
| + rhs.current.Equals(rhs.current);
|
| +}
|
| +
|
| namespace {
|
|
|
| using invalidation::AckHandle;
|
| @@ -131,7 +140,9 @@ class FakeInvalidationClient : public invalidation::InvalidationClient {
|
| // and state.
|
| class FakeDelegate : public SyncInvalidationListener::Delegate {
|
| public:
|
| - FakeDelegate() : state_(TRANSIENT_INVALIDATION_ERROR) {}
|
| + explicit FakeDelegate(SyncInvalidationListener* listener)
|
| + : listener_(listener),
|
| + state_(TRANSIENT_INVALIDATION_ERROR) {}
|
| virtual ~FakeDelegate() {}
|
|
|
| int GetInvalidationCount(const ObjectId& id) const {
|
| @@ -148,6 +159,10 @@ class FakeDelegate : public SyncInvalidationListener::Delegate {
|
| return state_;
|
| }
|
|
|
| + void Acknowledge(const ObjectId& id) {
|
| + listener_->Acknowledge(id, invalidations_[id].ack_handle);
|
| + }
|
| +
|
| // SyncInvalidationListener::Delegate implementation.
|
|
|
| virtual void OnInvalidate(
|
| @@ -167,6 +182,7 @@ class FakeDelegate : public SyncInvalidationListener::Delegate {
|
| typedef std::map<ObjectId, int, ObjectIdLessThan> ObjectIdCountMap;
|
| ObjectIdCountMap invalidation_counts_;
|
| ObjectIdInvalidationMap invalidations_;
|
| + SyncInvalidationListener* listener_;
|
| InvalidatorState state_;
|
| };
|
|
|
| @@ -190,14 +206,15 @@ class SyncInvalidationListenerTest : public testing::Test {
|
| kAppsId_(kChromeSyncSourceId, "APP"),
|
| fake_push_client_(new notifier::FakePushClient()),
|
| fake_invalidation_client_(NULL),
|
| - client_(scoped_ptr<notifier::PushClient>(fake_push_client_)) {}
|
| + listener_(scoped_ptr<notifier::PushClient>(fake_push_client_)),
|
| + fake_delegate_(&listener_) {}
|
|
|
| virtual void SetUp() {
|
| StartClient();
|
|
|
| registered_ids_.insert(kBookmarksId_);
|
| registered_ids_.insert(kPreferencesId_);
|
| - client_.UpdateRegisteredIds(registered_ids_);
|
| + listener_.UpdateRegisteredIds(registered_ids_);
|
| }
|
|
|
| virtual void TearDown() {
|
| @@ -245,31 +262,37 @@ class SyncInvalidationListenerTest : public testing::Test {
|
| }
|
| const AckHandle ack_handle("fakedata");
|
| fake_invalidation_client_->ClearAckedHandles();
|
| - client_.Invalidate(fake_invalidation_client_, inv, ack_handle);
|
| - EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle));
|
| - // Pump message loop to trigger
|
| - // InvalidationStateTracker::SetMaxVersion().
|
| + listener_.Invalidate(fake_invalidation_client_, inv, ack_handle);
|
| + // Pump message loop to trigger InvalidationStateTracker::SetMaxVersion()
|
| + // and callback from InvalidationStateTracker::GenerateAckHandles().
|
| message_loop_.RunAllPending();
|
| + 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();
|
| - client_.InvalidateUnknownVersion(fake_invalidation_client_, object_id,
|
| + listener_.InvalidateUnknownVersion(fake_invalidation_client_, object_id,
|
| ack_handle);
|
| + // Pump message loop to trigger callback from
|
| + // InvalidationStateTracker::GenerateAckHandles().
|
| + message_loop_.RunAllPending();
|
| EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle));
|
| }
|
|
|
| void FireInvalidateAll() {
|
| const AckHandle ack_handle("fakedata_all");
|
| fake_invalidation_client_->ClearAckedHandles();
|
| - client_.InvalidateAll(fake_invalidation_client_, ack_handle);
|
| + listener_.InvalidateAll(fake_invalidation_client_, ack_handle);
|
| + // Pump message loop to trigger callback from
|
| + // InvalidationStateTracker::GenerateAckHandles().
|
| + message_loop_.RunAllPending();
|
| EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle));
|
| }
|
|
|
| void WriteState(const std::string& new_state) {
|
| - client_.WriteState(new_state);
|
| + listener_.WriteState(new_state);
|
| // Pump message loop to trigger
|
| // InvalidationStateTracker::WriteState().
|
| message_loop_.RunAllPending();
|
| @@ -283,6 +306,29 @@ class SyncInvalidationListenerTest : public testing::Test {
|
| fake_push_client_->DisableNotifications(reason);
|
| }
|
|
|
| + void VerifyUnacknowledged(const ObjectId& object_id) {
|
| + InvalidationStateMap state_map = fake_tracker_.GetStateMap();
|
| + EXPECT_THAT(state_map[object_id].current,
|
| + Not(Eq(state_map[object_id].expected)));
|
| + EXPECT_EQ(listener_.GetStateMapForTest(), state_map);
|
| + }
|
| +
|
| + void VerifyAcknowledged(const ObjectId& object_id) {
|
| + InvalidationStateMap state_map = fake_tracker_.GetStateMap();
|
| + EXPECT_THAT(state_map[object_id].current,
|
| + Eq(state_map[object_id].expected));
|
| + EXPECT_EQ(listener_.GetStateMapForTest(), state_map);
|
| + }
|
| +
|
| + void AcknowledgeAndVerify(const ObjectId& object_id) {
|
| + VerifyUnacknowledged(object_id);
|
| + fake_delegate_.Acknowledge(object_id);
|
| + // Pump message loop to trigger
|
| + // InvalidationStateTracker::Acknowledge().
|
| + message_loop_.RunAllPending();
|
| + VerifyAcknowledged(object_id);
|
| + }
|
| +
|
| const ObjectId kBookmarksId_;
|
| const ObjectId kPreferencesId_;
|
| const ObjectId kExtensionsId_;
|
| @@ -293,37 +339,40 @@ class SyncInvalidationListenerTest : public testing::Test {
|
| private:
|
| void StartClient() {
|
| fake_invalidation_client_ = NULL;
|
| - client_.Start(base::Bind(&CreateFakeInvalidationClient,
|
| - &fake_invalidation_client_),
|
| - kClientId, kClientInfo, kState,
|
| - InvalidationVersionMap(),
|
| - MakeWeakHandle(fake_tracker_.AsWeakPtr()),
|
| - &fake_delegate_);
|
| + listener_.Start(base::Bind(&CreateFakeInvalidationClient,
|
| + &fake_invalidation_client_),
|
| + kClientId, kClientInfo, kState,
|
| + fake_tracker_.GetStateMap(),
|
| + MakeWeakHandle(fake_tracker_.AsWeakPtr()),
|
| + &fake_delegate_);
|
| DCHECK(fake_invalidation_client_);
|
| }
|
|
|
| void StopClient() {
|
| - // client_.StopForTest() stops the invalidation scheduler, which
|
| + // 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. client_.StopForTest() does not
|
| + // 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.
|
| message_loop_.RunAllPending();
|
| fake_invalidation_client_ = NULL;
|
| - client_.StopForTest();
|
| + listener_.StopForTest();
|
| }
|
|
|
| MessageLoop message_loop_;
|
|
|
| - FakeDelegate fake_delegate_;
|
| + private:
|
| FakeInvalidationStateTracker fake_tracker_;
|
| notifier::FakePushClient* const fake_push_client_;
|
|
|
| protected:
|
| // Tests need to access these directly.
|
| FakeInvalidationClient* fake_invalidation_client_;
|
| - SyncInvalidationListener client_;
|
| + SyncInvalidationListener listener_;
|
| +
|
| + private:
|
| + FakeDelegate fake_delegate_;
|
| };
|
|
|
| // Write a new state to the client. It should propagate to the
|
| @@ -346,6 +395,7 @@ TEST_F(SyncInvalidationListenerTest, InvalidateNoPayload) {
|
| EXPECT_EQ(1, GetInvalidationCount(id));
|
| EXPECT_EQ("", GetPayload(id));
|
| EXPECT_EQ(kVersion1, GetMaxVersion(id));
|
| + AcknowledgeAndVerify(id);
|
| }
|
|
|
| // Fire an invalidation with an empty payload. It should be
|
| @@ -359,6 +409,7 @@ TEST_F(SyncInvalidationListenerTest, InvalidateEmptyPayload) {
|
| EXPECT_EQ(1, GetInvalidationCount(id));
|
| EXPECT_EQ("", GetPayload(id));
|
| EXPECT_EQ(kVersion1, GetMaxVersion(id));
|
| + AcknowledgeAndVerify(id);
|
| }
|
|
|
| // Fire an invalidation with a payload. It should be processed, and
|
| @@ -371,11 +422,12 @@ TEST_F(SyncInvalidationListenerTest, InvalidateWithPayload) {
|
| EXPECT_EQ(1, GetInvalidationCount(id));
|
| EXPECT_EQ(kPayload1, GetPayload(id));
|
| EXPECT_EQ(kVersion1, GetMaxVersion(id));
|
| + AcknowledgeAndVerify(id);
|
| }
|
|
|
| -// Fire an invalidation with a payload. It should still be processed,
|
| -// and both the payload and the version should be updated.
|
| -TEST_F(SyncInvalidationListenerTest, InvalidateUnregistered) {
|
| +// 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, InvalidateUnregisteredWithPayload) {
|
| const ObjectId kUnregisteredId(
|
| kChromeSyncSourceId, "unregistered");
|
| const ObjectId& id = kUnregisteredId;
|
| @@ -384,11 +436,12 @@ TEST_F(SyncInvalidationListenerTest, InvalidateUnregistered) {
|
| EXPECT_EQ("", GetPayload(id));
|
| EXPECT_EQ(kMinVersion, GetMaxVersion(id));
|
|
|
| - FireInvalidate(id, kVersion1, NULL);
|
| + FireInvalidate(id, kVersion1, "unregistered payload");
|
|
|
| EXPECT_EQ(1, GetInvalidationCount(id));
|
| - EXPECT_EQ("", GetPayload(id));
|
| + EXPECT_EQ("unregistered payload", GetPayload(id));
|
| EXPECT_EQ(kVersion1, GetMaxVersion(id));
|
| + AcknowledgeAndVerify(id);
|
| }
|
|
|
| // Fire an invalidation, then fire another one with a lower version.
|
| @@ -402,12 +455,14 @@ TEST_F(SyncInvalidationListenerTest, InvalidateVersion) {
|
| EXPECT_EQ(1, GetInvalidationCount(id));
|
| EXPECT_EQ(kPayload2, GetPayload(id));
|
| EXPECT_EQ(kVersion2, GetMaxVersion(id));
|
| + AcknowledgeAndVerify(id);
|
|
|
| FireInvalidate(id, kVersion1, kPayload1);
|
|
|
| EXPECT_EQ(1, GetInvalidationCount(id));
|
| EXPECT_EQ(kPayload2, GetPayload(id));
|
| EXPECT_EQ(kVersion2, GetMaxVersion(id));
|
| + VerifyAcknowledged(id);
|
| }
|
|
|
| // Fire an invalidation with an unknown version twice. It shouldn't
|
| @@ -421,12 +476,14 @@ TEST_F(SyncInvalidationListenerTest, InvalidateUnknownVersion) {
|
| EXPECT_EQ(1, GetInvalidationCount(id));
|
| EXPECT_EQ("", GetPayload(id));
|
| EXPECT_EQ(kMinVersion, GetMaxVersion(id));
|
| + AcknowledgeAndVerify(id);
|
|
|
| FireInvalidateUnknownVersion(id);
|
|
|
| EXPECT_EQ(2, GetInvalidationCount(id));
|
| EXPECT_EQ("", GetPayload(id));
|
| EXPECT_EQ(kMinVersion, GetMaxVersion(id));
|
| + AcknowledgeAndVerify(id);
|
| }
|
|
|
| // Fire an invalidation for all enabled IDs. It shouldn't update the
|
| @@ -439,6 +496,7 @@ TEST_F(SyncInvalidationListenerTest, InvalidateAll) {
|
| EXPECT_EQ(1, GetInvalidationCount(*it));
|
| EXPECT_EQ("", GetPayload(*it));
|
| EXPECT_EQ(kMinVersion, GetMaxVersion(*it));
|
| + AcknowledgeAndVerify(*it);
|
| }
|
| }
|
|
|
| @@ -449,12 +507,14 @@ TEST_F(SyncInvalidationListenerTest, InvalidateMultipleIds) {
|
| EXPECT_EQ(1, GetInvalidationCount(kBookmarksId_));
|
| EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| EXPECT_EQ(3, GetMaxVersion(kBookmarksId_));
|
| + AcknowledgeAndVerify(kBookmarksId_);
|
|
|
| FireInvalidate(kExtensionsId_, 2, NULL);
|
|
|
| EXPECT_EQ(1, GetInvalidationCount(kExtensionsId_));
|
| EXPECT_EQ("", GetPayload(kExtensionsId_));
|
| EXPECT_EQ(2, GetMaxVersion(kExtensionsId_));
|
| + AcknowledgeAndVerify(kExtensionsId_);
|
|
|
| // Invalidations with lower version numbers should be ignored.
|
|
|
| @@ -477,14 +537,19 @@ TEST_F(SyncInvalidationListenerTest, InvalidateMultipleIds) {
|
| EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_));
|
| EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| EXPECT_EQ(3, GetMaxVersion(kBookmarksId_));
|
| + AcknowledgeAndVerify(kBookmarksId_);
|
|
|
| EXPECT_EQ(1, GetInvalidationCount(kPreferencesId_));
|
| EXPECT_EQ("", GetPayload(kPreferencesId_));
|
| EXPECT_EQ(kMinVersion, GetMaxVersion(kPreferencesId_));
|
| + AcknowledgeAndVerify(kPreferencesId_);
|
|
|
| + // Note that kExtensionsId_ is not registered, so InvalidateAll() shouldn't
|
| + // affect it.
|
| EXPECT_EQ(1, GetInvalidationCount(kExtensionsId_));
|
| EXPECT_EQ("", GetPayload(kExtensionsId_));
|
| EXPECT_EQ(2, GetMaxVersion(kExtensionsId_));
|
| + VerifyAcknowledged(kExtensionsId_);
|
|
|
| // Invalidations with higher version numbers should be processed.
|
|
|
| @@ -492,16 +557,252 @@ TEST_F(SyncInvalidationListenerTest, InvalidateMultipleIds) {
|
| EXPECT_EQ(2, GetInvalidationCount(kPreferencesId_));
|
| EXPECT_EQ("", GetPayload(kPreferencesId_));
|
| EXPECT_EQ(5, GetMaxVersion(kPreferencesId_));
|
| + AcknowledgeAndVerify(kPreferencesId_);
|
|
|
| FireInvalidate(kExtensionsId_, 3, NULL);
|
| EXPECT_EQ(2, GetInvalidationCount(kExtensionsId_));
|
| EXPECT_EQ("", GetPayload(kExtensionsId_));
|
| EXPECT_EQ(3, GetMaxVersion(kExtensionsId_));
|
| + AcknowledgeAndVerify(kExtensionsId_);
|
|
|
| FireInvalidate(kBookmarksId_, 4, NULL);
|
| EXPECT_EQ(3, GetInvalidationCount(kBookmarksId_));
|
| EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| EXPECT_EQ(4, GetMaxVersion(kBookmarksId_));
|
| + AcknowledgeAndVerify(kBookmarksId_);
|
| +}
|
| +
|
| +// Various tests for the local invalidation feature.
|
| +// Test that timeout behavior for one object ID. The timeout should increase
|
| +// exponentially until it hits the cap. If a new invalidation with a higher
|
| +// version is received, it should reset the timeout period as well.
|
| +TEST_F(SyncInvalidationListenerTest, InvalidateOneTimeout) {
|
| + // The timeout should increase exponentially while unacknowledged.
|
| + base::TimeTicks next_invalidation_time;
|
| + base::TimeTicks start = base::TimeTicks::Now();
|
| + FireInvalidate(kBookmarksId_, 3, NULL);
|
| + EXPECT_EQ(1, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| + EXPECT_EQ(3, GetMaxVersion(kBookmarksId_));
|
| +
|
| + // First timeout.
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(60),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(60, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + // Second timeout.
|
| + start = base::TimeTicks::Now();
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(120),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(3, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(120, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + // Third timeout.
|
| + start = base::TimeTicks::Now();
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(240),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(4, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(240, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| + start = next_invalidation_time;
|
| +
|
| + // Fourth timeout.
|
| + start = base::TimeTicks::Now();
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(480),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(5, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(480, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + // Until it is capped at 600 seconds.
|
| + start = base::TimeTicks::Now();
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(600),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(6, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(600, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + // A new incoming invalidation with the same version should not reset the
|
| + // timer.
|
| + start = base::TimeTicks::Now();
|
| + FireInvalidate(kBookmarksId_, 3, NULL);
|
| + EXPECT_EQ(6, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| + EXPECT_EQ(3, GetMaxVersion(kBookmarksId_));
|
| +
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(600),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(7, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(600, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + // But one with a higher version should.
|
| + start = base::TimeTicks::Now();
|
| + FireInvalidate(kBookmarksId_, 4, NULL);
|
| + EXPECT_EQ(8, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| + EXPECT_EQ(4, GetMaxVersion(kBookmarksId_));
|
| +
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(60),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_NEAR(60, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| + AcknowledgeAndVerify(kBookmarksId_);
|
| +
|
| + // The timer queue should be empty at this point.
|
| + EXPECT_FALSE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| +}
|
| +
|
| +// Test that the timer runs until all pending invalidations are acknowledged.
|
| +TEST_F(SyncInvalidationListenerTest, InvalidateAllTimeout) {
|
| + base::TimeTicks next_invalidation_time;
|
| + base::TimeTicks start = base::TimeTicks::Now();
|
| + FireInvalidateAll();
|
| +
|
| + EXPECT_EQ(1, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| + EXPECT_EQ(kMinVersion, GetMaxVersion(kBookmarksId_));
|
| +
|
| + EXPECT_EQ(1, GetInvalidationCount(kPreferencesId_));
|
| + EXPECT_EQ("", GetPayload(kPreferencesId_));
|
| + EXPECT_EQ(kMinVersion, GetMaxVersion(kPreferencesId_));
|
| +
|
| + // Trigger one timeout where neither is acknowledged.
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + VerifyUnacknowledged(kPreferencesId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(60),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ(2, GetInvalidationCount(kPreferencesId_));
|
| + EXPECT_NEAR(60, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + AcknowledgeAndVerify(kBookmarksId_);
|
| +
|
| + // Trigger another timeout. Now we should only receive one invalidation.
|
| + start = base::TimeTicks::Now();
|
| + VerifyAcknowledged(kBookmarksId_);
|
| + VerifyUnacknowledged(kPreferencesId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(120),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ(3, GetInvalidationCount(kPreferencesId_));
|
| + EXPECT_NEAR(120, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + AcknowledgeAndVerify(kPreferencesId_);
|
| + // The timer queue should be empty at this point.
|
| + EXPECT_FALSE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| +}
|
| +
|
| +// Test that the timer is appropriately updated if we schedule a timeout
|
| +// that occurs before the currently queued timeouts.
|
| +TEST_F(SyncInvalidationListenerTest, InvalidateShortenTimeout) {
|
| + // The timeout should increase exponentially while unacknowledged.
|
| + base::TimeTicks next_invalidation_time;
|
| + base::TimeTicks start = base::TimeTicks::Now();
|
| + FireInvalidate(kBookmarksId_, 3, NULL);
|
| + EXPECT_EQ(1, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| + EXPECT_EQ(3, GetMaxVersion(kBookmarksId_));
|
| +
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(60),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(60, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + // The timeout should now be 120 seconds...
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(120),
|
| + listener_.GetCurrentDelayForTest());
|
| + // But a new invalidation should reset the timeout to 60 seconds.
|
| + start = base::TimeTicks::Now();
|
| + FireInvalidate(kExtensionsId_, 2, NULL);
|
| + EXPECT_EQ(1, GetInvalidationCount(kExtensionsId_));
|
| + EXPECT_EQ("", GetPayload(kExtensionsId_));
|
| + EXPECT_EQ(2, GetMaxVersion(kExtensionsId_));
|
| +
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(60),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(2, GetInvalidationCount(kExtensionsId_));
|
| + EXPECT_NEAR(60, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + // The next timeout should trigger another invalidation for |kBookmarksId_|.
|
| + // Note that we don't check the exact times here, as they will be incorrect in
|
| + // tests, due to the fact that we pretend that the next timeout has elapsed,
|
| + // but then we update the timers based on base::TimeTicks::Now().
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(3, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ(2, GetInvalidationCount(kExtensionsId_));
|
| +
|
| + // Foollowed by |kExtensionsId_| again.
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(3, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ(3, GetInvalidationCount(kExtensionsId_));
|
| +
|
| + AcknowledgeAndVerify(kBookmarksId_);
|
| + AcknowledgeAndVerify(kExtensionsId_);
|
| +
|
| + // The timer queue should be empty at this point.
|
| + EXPECT_FALSE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| +}
|
| +
|
| +// Test that an unacknowledged invalidation triggers reminders if the listener
|
| +// is restarted.
|
| +TEST_F(SyncInvalidationListenerTest, InvalidationTimeoutRestart) {
|
| + base::TimeTicks next_invalidation_time;
|
| + base::TimeTicks start = base::TimeTicks::Now();
|
| + FireInvalidate(kBookmarksId_, 3, NULL);
|
| + EXPECT_EQ(1, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| + EXPECT_EQ(3, GetMaxVersion(kBookmarksId_));
|
| +
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(60),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(60, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(120),
|
| + listener_.GetCurrentDelayForTest());
|
| +
|
| + // Restarting the client should reset the retry count and the timeout period.
|
| + RestartClient();
|
| + // The bookmark invalidation state should not have changed.
|
| + EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_EQ("", GetPayload(kBookmarksId_));
|
| + EXPECT_EQ(3, GetMaxVersion(kBookmarksId_));
|
| +
|
| + // Now trigger a reminder.
|
| + VerifyUnacknowledged(kBookmarksId_);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(60),
|
| + listener_.GetCurrentDelayForTest());
|
| + EXPECT_TRUE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| + EXPECT_EQ(3, GetInvalidationCount(kBookmarksId_));
|
| + EXPECT_NEAR(60, (next_invalidation_time - start).InSecondsF(), 0.5);
|
| +
|
| + AcknowledgeAndVerify(kBookmarksId_);
|
| +
|
| + // The timer queue should be empty at this point.
|
| + EXPECT_FALSE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| +
|
| + // A restart with no unacknowledged invalidations should not have any running
|
| + // timers.
|
| + RestartClient();
|
| + EXPECT_FALSE(listener_.TriggerNextTimeoutForTest(&next_invalidation_time));
|
| }
|
|
|
| // Registration tests.
|
| @@ -516,7 +817,7 @@ TEST_F(SyncInvalidationListenerTest, RegisterEnableReady) {
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
| }
|
| @@ -527,7 +828,7 @@ TEST_F(SyncInvalidationListenerTest, RegisterEnableReady) {
|
| TEST_F(SyncInvalidationListenerTest, RegisterReadyEnable) {
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
|
|
| @@ -540,7 +841,7 @@ TEST_F(SyncInvalidationListenerTest, RegisterReadyEnable) {
|
| // ready the client. The IDs should be registered only after the
|
| // client is readied.
|
| TEST_F(SyncInvalidationListenerTest, EnableRegisterReady) {
|
| - client_.UpdateRegisteredIds(ObjectIdSet());
|
| + listener_.UpdateRegisteredIds(ObjectIdSet());
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| @@ -548,11 +849,11 @@ TEST_F(SyncInvalidationListenerTest, EnableRegisterReady) {
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.UpdateRegisteredIds(registered_ids_);
|
| + listener_.UpdateRegisteredIds(registered_ids_);
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
| }
|
| @@ -561,7 +862,7 @@ TEST_F(SyncInvalidationListenerTest, EnableRegisterReady) {
|
| // re-register the IDs. The IDs should be registered only after the
|
| // client is readied.
|
| TEST_F(SyncInvalidationListenerTest, EnableReadyRegister) {
|
| - client_.UpdateRegisteredIds(ObjectIdSet());
|
| + listener_.UpdateRegisteredIds(ObjectIdSet());
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| @@ -569,11 +870,11 @@ TEST_F(SyncInvalidationListenerTest, EnableReadyRegister) {
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.UpdateRegisteredIds(registered_ids_);
|
| + listener_.UpdateRegisteredIds(registered_ids_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
| }
|
| @@ -582,7 +883,7 @@ TEST_F(SyncInvalidationListenerTest, EnableReadyRegister) {
|
| // re-register the IDs. The IDs should be registered only after the
|
| // client is readied.
|
| TEST_F(SyncInvalidationListenerTest, ReadyEnableRegister) {
|
| - client_.UpdateRegisteredIds(ObjectIdSet());
|
| + listener_.UpdateRegisteredIds(ObjectIdSet());
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| @@ -590,11 +891,11 @@ TEST_F(SyncInvalidationListenerTest, ReadyEnableRegister) {
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.UpdateRegisteredIds(registered_ids_);
|
| + listener_.UpdateRegisteredIds(registered_ids_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
| }
|
| @@ -605,15 +906,15 @@ TEST_F(SyncInvalidationListenerTest, ReadyEnableRegister) {
|
| //
|
| // This test is important: see http://crbug.com/139424.
|
| TEST_F(SyncInvalidationListenerTest, ReadyRegisterEnable) {
|
| - client_.UpdateRegisteredIds(ObjectIdSet());
|
| + listener_.UpdateRegisteredIds(ObjectIdSet());
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.UpdateRegisteredIds(registered_ids_);
|
| + listener_.UpdateRegisteredIds(registered_ids_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
|
|
| @@ -627,7 +928,7 @@ TEST_F(SyncInvalidationListenerTest, ReadyRegisterEnable) {
|
| TEST_F(SyncInvalidationListenerTest, RegisterTypesPreserved) {
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
|
|
| @@ -635,7 +936,7 @@ TEST_F(SyncInvalidationListenerTest, RegisterTypesPreserved) {
|
|
|
| EXPECT_TRUE(GetRegisteredIds().empty());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(registered_ids_, GetRegisteredIds());
|
| }
|
| @@ -669,7 +970,7 @@ TEST_F(SyncInvalidationListenerTest, EnableNotificationsThenReady) {
|
|
|
| EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
|
| }
|
| @@ -679,7 +980,7 @@ TEST_F(SyncInvalidationListenerTest, EnableNotificationsThenReady) {
|
| TEST_F(SyncInvalidationListenerTest, ReadyThenEnableNotifications) {
|
| EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());
|
|
|
| @@ -693,7 +994,7 @@ TEST_F(SyncInvalidationListenerTest, ReadyThenEnableNotifications) {
|
| // delegate should go into an auth error mode and then back out.
|
| TEST_F(SyncInvalidationListenerTest, PushClientAuthError) {
|
| EnableNotifications();
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
|
|
|
| @@ -713,11 +1014,11 @@ TEST_F(SyncInvalidationListenerTest, PushClientAuthError) {
|
| // auth error mode and come out of it only after the client is ready.
|
| TEST_F(SyncInvalidationListenerTest, InvalidationClientAuthError) {
|
| EnableNotifications();
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
|
|
|
| - client_.InformError(
|
| + listener_.InformError(
|
| fake_invalidation_client_,
|
| invalidation::ErrorInfo(
|
| invalidation::ErrorReason::AUTH_FAILURE,
|
| @@ -739,7 +1040,7 @@ TEST_F(SyncInvalidationListenerTest, InvalidationClientAuthError) {
|
|
|
| EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState());
|
|
|
| - client_.Ready(fake_invalidation_client_);
|
| + listener_.Ready(fake_invalidation_client_);
|
|
|
| EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
|
| }
|
|
|