1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/invalidation/unacked_invalidation_set.h"
7 #include "base/json/json_string_value_serializer.h"
8 #include "components/invalidation/object_id_invalidation_map.h"
9 #include "components/invalidation/single_object_invalidation_set.h"
10 #include "components/invalidation/unacked_invalidation_set_test_util.h"
11 #include "testing/gtest/include/gtest/gtest.h"
15 class UnackedInvalidationSetTest
: public testing::Test
{
17 UnackedInvalidationSetTest()
18 : kObjectId_(10, "ASDF"),
19 unacked_invalidations_(kObjectId_
) {}
21 SingleObjectInvalidationSet
GetStoredInvalidations() {
22 ObjectIdInvalidationMap map
;
23 unacked_invalidations_
.ExportInvalidations(
24 base::WeakPtr
<AckHandler
>(),
25 scoped_refptr
<base::SingleThreadTaskRunner
>(),
27 ObjectIdSet ids
= map
.GetObjectIds();
28 if (ids
.find(kObjectId_
) != ids
.end()) {
29 return map
.ForObject(kObjectId_
);
31 return SingleObjectInvalidationSet();
35 const invalidation::ObjectId kObjectId_
;
36 UnackedInvalidationSet unacked_invalidations_
;
41 // Test storage and retrieval of zero invalidations.
42 TEST_F(UnackedInvalidationSetTest
, Empty
) {
43 EXPECT_EQ(0U, GetStoredInvalidations().GetSize());
46 // Test storage and retrieval of a single invalidation.
47 TEST_F(UnackedInvalidationSetTest
, OneInvalidation
) {
48 Invalidation inv1
= Invalidation::Init(kObjectId_
, 10, "payload");
49 unacked_invalidations_
.Add(inv1
);
51 SingleObjectInvalidationSet set
= GetStoredInvalidations();
52 ASSERT_EQ(1U, set
.GetSize());
53 EXPECT_FALSE(set
.StartsWithUnknownVersion());
56 // Test that calling Clear() returns us to the empty state.
57 TEST_F(UnackedInvalidationSetTest
, Clear
) {
58 Invalidation inv1
= Invalidation::Init(kObjectId_
, 10, "payload");
59 unacked_invalidations_
.Add(inv1
);
60 unacked_invalidations_
.Clear();
62 EXPECT_EQ(0U, GetStoredInvalidations().GetSize());
65 // Test that repeated unknown version invalidations are squashed together.
66 TEST_F(UnackedInvalidationSetTest
, UnknownVersions
) {
67 Invalidation inv1
= Invalidation::Init(kObjectId_
, 10, "payload");
68 Invalidation inv2
= Invalidation::InitUnknownVersion(kObjectId_
);
69 Invalidation inv3
= Invalidation::InitUnknownVersion(kObjectId_
);
70 unacked_invalidations_
.Add(inv1
);
71 unacked_invalidations_
.Add(inv2
);
72 unacked_invalidations_
.Add(inv3
);
74 SingleObjectInvalidationSet set
= GetStoredInvalidations();
75 ASSERT_EQ(2U, set
.GetSize());
76 EXPECT_TRUE(set
.StartsWithUnknownVersion());
79 // Tests that no truncation occurs while we're under the limit.
80 TEST_F(UnackedInvalidationSetTest
, NoTruncation
) {
81 size_t kMax
= UnackedInvalidationSet::kMaxBufferedInvalidations
;
83 for (size_t i
= 0; i
< kMax
; ++i
) {
84 Invalidation inv
= Invalidation::Init(kObjectId_
, i
, "payload");
85 unacked_invalidations_
.Add(inv
);
88 SingleObjectInvalidationSet set
= GetStoredInvalidations();
89 ASSERT_EQ(kMax
, set
.GetSize());
90 EXPECT_FALSE(set
.StartsWithUnknownVersion());
91 EXPECT_EQ(0, set
.begin()->version());
92 EXPECT_EQ(kMax
-1, static_cast<size_t>(set
.rbegin()->version()));
95 // Test that truncation happens as we reach the limit.
96 TEST_F(UnackedInvalidationSetTest
, Truncation
) {
97 size_t kMax
= UnackedInvalidationSet::kMaxBufferedInvalidations
;
99 for (size_t i
= 0; i
< kMax
+ 1; ++i
) {
100 Invalidation inv
= Invalidation::Init(kObjectId_
, i
, "payload");
101 unacked_invalidations_
.Add(inv
);
104 SingleObjectInvalidationSet set
= GetStoredInvalidations();
105 ASSERT_EQ(kMax
, set
.GetSize());
106 EXPECT_TRUE(set
.StartsWithUnknownVersion());
107 EXPECT_TRUE(set
.begin()->is_unknown_version());
108 EXPECT_EQ(kMax
, static_cast<size_t>(set
.rbegin()->version()));
111 // Test that we don't truncate while a handler is registered.
112 TEST_F(UnackedInvalidationSetTest
, RegistrationAndTruncation
) {
113 unacked_invalidations_
.SetHandlerIsRegistered();
115 size_t kMax
= UnackedInvalidationSet::kMaxBufferedInvalidations
;
117 for (size_t i
= 0; i
< kMax
+ 1; ++i
) {
118 Invalidation inv
= Invalidation::Init(kObjectId_
, i
, "payload");
119 unacked_invalidations_
.Add(inv
);
122 SingleObjectInvalidationSet set
= GetStoredInvalidations();
123 ASSERT_EQ(kMax
+1, set
.GetSize());
124 EXPECT_FALSE(set
.StartsWithUnknownVersion());
125 EXPECT_EQ(0, set
.begin()->version());
126 EXPECT_EQ(kMax
, static_cast<size_t>(set
.rbegin()->version()));
128 // Unregistering should re-enable truncation.
129 unacked_invalidations_
.SetHandlerIsUnregistered();
130 SingleObjectInvalidationSet set2
= GetStoredInvalidations();
131 ASSERT_EQ(kMax
, set2
.GetSize());
132 EXPECT_TRUE(set2
.StartsWithUnknownVersion());
133 EXPECT_TRUE(set2
.begin()->is_unknown_version());
134 EXPECT_EQ(kMax
, static_cast<size_t>(set2
.rbegin()->version()));
137 // Test acknowledgement.
138 TEST_F(UnackedInvalidationSetTest
, Acknowledge
) {
139 // inv2 is included in this test just to make sure invalidations that
140 // are supposed to be unaffected by this operation will be unaffected.
142 // We don't expect to be receiving acks or drops unless this flag is set.
143 // Not that it makes much of a difference in behavior.
144 unacked_invalidations_
.SetHandlerIsRegistered();
146 Invalidation inv1
= Invalidation::Init(kObjectId_
, 10, "payload");
147 Invalidation inv2
= Invalidation::InitUnknownVersion(kObjectId_
);
148 AckHandle inv1_handle
= inv1
.ack_handle();
150 unacked_invalidations_
.Add(inv1
);
151 unacked_invalidations_
.Add(inv2
);
153 unacked_invalidations_
.Acknowledge(inv1_handle
);
155 SingleObjectInvalidationSet set
= GetStoredInvalidations();
156 EXPECT_EQ(1U, set
.GetSize());
157 EXPECT_TRUE(set
.StartsWithUnknownVersion());
161 TEST_F(UnackedInvalidationSetTest
, Drop
) {
162 // inv2 is included in this test just to make sure invalidations that
163 // are supposed to be unaffected by this operation will be unaffected.
165 // We don't expect to be receiving acks or drops unless this flag is set.
166 // Not that it makes much of a difference in behavior.
167 unacked_invalidations_
.SetHandlerIsRegistered();
169 Invalidation inv1
= Invalidation::Init(kObjectId_
, 10, "payload");
170 Invalidation inv2
= Invalidation::Init(kObjectId_
, 15, "payload");
171 AckHandle inv1_handle
= inv1
.ack_handle();
173 unacked_invalidations_
.Add(inv1
);
174 unacked_invalidations_
.Add(inv2
);
176 unacked_invalidations_
.Drop(inv1_handle
);
178 SingleObjectInvalidationSet set
= GetStoredInvalidations();
179 ASSERT_EQ(2U, set
.GetSize());
180 EXPECT_TRUE(set
.StartsWithUnknownVersion());
181 EXPECT_EQ(15, set
.rbegin()->version());
184 class UnackedInvalidationSetSerializationTest
185 : public UnackedInvalidationSetTest
{
187 UnackedInvalidationSet
SerializeDeserialize() {
188 scoped_ptr
<base::DictionaryValue
> value
= unacked_invalidations_
.ToValue();
189 UnackedInvalidationSet
deserialized(kObjectId_
);
190 deserialized
.ResetFromValue(*value
.get());
195 TEST_F(UnackedInvalidationSetSerializationTest
, Empty
) {
196 UnackedInvalidationSet deserialized
= SerializeDeserialize();
197 EXPECT_THAT(unacked_invalidations_
, test_util::Eq(deserialized
));
200 TEST_F(UnackedInvalidationSetSerializationTest
, OneInvalidation
) {
201 Invalidation inv
= Invalidation::Init(kObjectId_
, 10, "payload");
202 unacked_invalidations_
.Add(inv
);
204 UnackedInvalidationSet deserialized
= SerializeDeserialize();
205 EXPECT_THAT(unacked_invalidations_
, test_util::Eq(deserialized
));
208 TEST_F(UnackedInvalidationSetSerializationTest
, WithUnknownVersion
) {
209 Invalidation inv1
= Invalidation::Init(kObjectId_
, 10, "payload");
210 Invalidation inv2
= Invalidation::InitUnknownVersion(kObjectId_
);
211 Invalidation inv3
= Invalidation::InitUnknownVersion(kObjectId_
);
212 unacked_invalidations_
.Add(inv1
);
213 unacked_invalidations_
.Add(inv2
);
214 unacked_invalidations_
.Add(inv3
);
216 UnackedInvalidationSet deserialized
= SerializeDeserialize();
217 EXPECT_THAT(unacked_invalidations_
, test_util::Eq(deserialized
));
222 } // namespace syncer