blob: df56ae73f276ae2b26608e5ae48d40814b0bf1d0 [file] [log] [blame]
// Copyright 2014 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 "components/invalidation/impl/unacked_invalidation_set.h"
#include <stddef.h>
#include <memory>
#include "base/json/json_string_value_serializer.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "components/invalidation/public/single_object_invalidation_set.h"
#include "components/invalidation/public/topic_invalidation_map.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
class UnackedInvalidationSetTest : public testing::Test {
public:
UnackedInvalidationSetTest() : unacked_invalidations_(kTopic) {}
SingleObjectInvalidationSet GetStoredInvalidations() {
TopicInvalidationMap map;
unacked_invalidations_.ExportInvalidations(
base::WeakPtr<AckHandler>(),
scoped_refptr<base::SingleThreadTaskRunner>(),
&map);
if (map.Empty()) {
return SingleObjectInvalidationSet();
} else {
return map.ForTopic(kTopic);
}
}
const Topic kTopic = "ASDF";
UnackedInvalidationSet unacked_invalidations_;
};
namespace {
// Test storage and retrieval of zero invalidations.
TEST_F(UnackedInvalidationSetTest, Empty) {
EXPECT_EQ(0U, GetStoredInvalidations().GetSize());
}
// Test storage and retrieval of a single invalidation.
TEST_F(UnackedInvalidationSetTest, OneInvalidation) {
Invalidation inv1 = Invalidation::Init(kTopic, 10, "payload");
unacked_invalidations_.Add(inv1);
SingleObjectInvalidationSet set = GetStoredInvalidations();
ASSERT_EQ(1U, set.GetSize());
EXPECT_FALSE(set.StartsWithUnknownVersion());
}
// Test that calling Clear() returns us to the empty state.
TEST_F(UnackedInvalidationSetTest, Clear) {
Invalidation inv1 = Invalidation::Init(kTopic, 10, "payload");
unacked_invalidations_.Add(inv1);
unacked_invalidations_.Clear();
EXPECT_EQ(0U, GetStoredInvalidations().GetSize());
}
// Test that repeated unknown version invalidations are squashed together.
TEST_F(UnackedInvalidationSetTest, UnknownVersions) {
Invalidation inv1 = Invalidation::Init(kTopic, 10, "payload");
Invalidation inv2 = Invalidation::InitUnknownVersion(kTopic);
Invalidation inv3 = Invalidation::InitUnknownVersion(kTopic);
unacked_invalidations_.Add(inv1);
unacked_invalidations_.Add(inv2);
unacked_invalidations_.Add(inv3);
SingleObjectInvalidationSet set = GetStoredInvalidations();
ASSERT_EQ(2U, set.GetSize());
EXPECT_TRUE(set.StartsWithUnknownVersion());
}
// Tests that no truncation occurs while we're under the limit.
TEST_F(UnackedInvalidationSetTest, NoTruncation) {
size_t kMax = UnackedInvalidationSet::kMaxBufferedInvalidations;
for (size_t i = 0; i < kMax; ++i) {
Invalidation inv = Invalidation::Init(kTopic, i, "payload");
unacked_invalidations_.Add(inv);
}
SingleObjectInvalidationSet set = GetStoredInvalidations();
ASSERT_EQ(kMax, set.GetSize());
EXPECT_FALSE(set.StartsWithUnknownVersion());
EXPECT_EQ(0, set.begin()->version());
EXPECT_EQ(kMax-1, static_cast<size_t>(set.rbegin()->version()));
}
// Test that truncation happens as we reach the limit.
TEST_F(UnackedInvalidationSetTest, Truncation) {
size_t kMax = UnackedInvalidationSet::kMaxBufferedInvalidations;
for (size_t i = 0; i < kMax + 1; ++i) {
Invalidation inv = Invalidation::Init(kTopic, i, "payload");
unacked_invalidations_.Add(inv);
}
SingleObjectInvalidationSet set = GetStoredInvalidations();
ASSERT_EQ(kMax, set.GetSize());
EXPECT_TRUE(set.StartsWithUnknownVersion());
EXPECT_TRUE(set.begin()->is_unknown_version());
EXPECT_EQ(kMax, static_cast<size_t>(set.rbegin()->version()));
}
// Test that we don't truncate while a handler is registered.
TEST_F(UnackedInvalidationSetTest, RegistrationAndTruncation) {
unacked_invalidations_.SetHandlerIsRegistered();
size_t kMax = UnackedInvalidationSet::kMaxBufferedInvalidations;
for (size_t i = 0; i < kMax + 1; ++i) {
Invalidation inv = Invalidation::Init(kTopic, i, "payload");
unacked_invalidations_.Add(inv);
}
SingleObjectInvalidationSet set = GetStoredInvalidations();
ASSERT_EQ(kMax+1, set.GetSize());
EXPECT_FALSE(set.StartsWithUnknownVersion());
EXPECT_EQ(0, set.begin()->version());
EXPECT_EQ(kMax, static_cast<size_t>(set.rbegin()->version()));
// Unregistering should re-enable truncation.
unacked_invalidations_.SetHandlerIsUnregistered();
SingleObjectInvalidationSet set2 = GetStoredInvalidations();
ASSERT_EQ(kMax, set2.GetSize());
EXPECT_TRUE(set2.StartsWithUnknownVersion());
EXPECT_TRUE(set2.begin()->is_unknown_version());
EXPECT_EQ(kMax, static_cast<size_t>(set2.rbegin()->version()));
}
// Test acknowledgement.
TEST_F(UnackedInvalidationSetTest, Acknowledge) {
// inv2 is included in this test just to make sure invalidations that
// are supposed to be unaffected by this operation will be unaffected.
// We don't expect to be receiving acks or drops unless this flag is set.
// Not that it makes much of a difference in behavior.
unacked_invalidations_.SetHandlerIsRegistered();
Invalidation inv1 = Invalidation::Init(kTopic, 10, "payload");
Invalidation inv2 = Invalidation::InitUnknownVersion(kTopic);
AckHandle inv1_handle = inv1.ack_handle();
unacked_invalidations_.Add(inv1);
unacked_invalidations_.Add(inv2);
unacked_invalidations_.Acknowledge(inv1_handle);
SingleObjectInvalidationSet set = GetStoredInvalidations();
EXPECT_EQ(1U, set.GetSize());
EXPECT_TRUE(set.StartsWithUnknownVersion());
}
// Test drops.
TEST_F(UnackedInvalidationSetTest, Drop) {
// inv2 is included in this test just to make sure invalidations that
// are supposed to be unaffected by this operation will be unaffected.
// We don't expect to be receiving acks or drops unless this flag is set.
// Not that it makes much of a difference in behavior.
unacked_invalidations_.SetHandlerIsRegistered();
Invalidation inv1 = Invalidation::Init(kTopic, 10, "payload");
Invalidation inv2 = Invalidation::Init(kTopic, 15, "payload");
AckHandle inv1_handle = inv1.ack_handle();
unacked_invalidations_.Add(inv1);
unacked_invalidations_.Add(inv2);
unacked_invalidations_.Drop(inv1_handle);
SingleObjectInvalidationSet set = GetStoredInvalidations();
ASSERT_EQ(2U, set.GetSize());
EXPECT_TRUE(set.StartsWithUnknownVersion());
EXPECT_EQ(15, set.rbegin()->version());
}
} // namespace
} // namespace syncer