Get foreground tab on Android
[chromium-blink-merge.git] / sync / notifier / unacked_invalidation_set_unittest.cc
blob70cd232b8a5bf0f3d084deaf0ae2c2692d631648
1 // Copyright 2013 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 "sync/notifier/unacked_invalidation_set.h"
7 #include "base/json/json_string_value_serializer.h"
8 #include "sync/notifier/object_id_invalidation_map.h"
9 #include "sync/notifier/single_object_invalidation_set.h"
10 #include "testing/gmock/include/gmock/gmock-matchers.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace syncer {
15 // Start with some helper functions and classes.
17 using ::testing::MakeMatcher;
18 using ::testing::MatchResultListener;
19 using ::testing::Matcher;
20 using ::testing::MatcherInterface;
21 using ::testing::PrintToString;
23 void PrintTo(
24 const UnackedInvalidationSet& invalidations, ::std::ostream* os);
26 void PrintTo(
27 const UnackedInvalidationsMap& map, ::std::ostream* os);
29 ::testing::Matcher<const UnackedInvalidationSet&> Eq(
30 const UnackedInvalidationSet& expected);
32 ::testing::Matcher<const UnackedInvalidationsMap&> Eq(
33 const UnackedInvalidationsMap& expected);
35 class UnackedInvalidationSetEqMatcher
36 : public testing::MatcherInterface<const UnackedInvalidationSet&> {
37 public:
38 explicit UnackedInvalidationSetEqMatcher(
39 const UnackedInvalidationSet& expected);
41 virtual bool MatchAndExplain(
42 const UnackedInvalidationSet& actual,
43 MatchResultListener* listener) const OVERRIDE;
44 virtual void DescribeTo(::std::ostream* os) const OVERRIDE;
45 virtual void DescribeNegationTo(::std::ostream* os) const OVERRIDE;
47 private:
48 const UnackedInvalidationSet expected_;
50 DISALLOW_COPY_AND_ASSIGN(UnackedInvalidationSetEqMatcher);
53 UnackedInvalidationSetEqMatcher::UnackedInvalidationSetEqMatcher(
54 const UnackedInvalidationSet& expected)
55 : expected_(expected) {}
57 namespace {
59 struct InvalidationEq {
60 bool operator()(const syncer::Invalidation& a,
61 const syncer::Invalidation& b) const {
62 return a.Equals(b);
66 } // namespace
68 bool UnackedInvalidationSetEqMatcher::MatchAndExplain(
69 const UnackedInvalidationSet& actual,
70 MatchResultListener* listener) const {
71 // Use our friendship with this class to compare the internals of two
72 // instances.
74 // Note that the registration status is intentionally not considered
75 // when performing this comparison.
76 return expected_.object_id_ == actual.object_id_
77 && std::equal(expected_.invalidations_.begin(),
78 expected_.invalidations_.end(),
79 actual.invalidations_.begin(),
80 InvalidationEq());
83 void UnackedInvalidationSetEqMatcher::DescribeTo(::std::ostream* os) const {
84 *os << " is equal to " << PrintToString(expected_);
87 void UnackedInvalidationSetEqMatcher::DescribeNegationTo(
88 ::std::ostream* os) const {
89 *os << " isn't equal to " << PrintToString(expected_);
92 namespace {
94 ObjectIdInvalidationMap UnackedInvalidationsMapToObjectIdInvalidationMap(
95 const UnackedInvalidationsMap& state_map) {
96 ObjectIdInvalidationMap object_id_invalidation_map;
97 for (UnackedInvalidationsMap::const_iterator it = state_map.begin();
98 it != state_map.end(); ++it) {
99 it->second.ExportInvalidations(syncer::WeakHandle<AckHandler>(),
100 &object_id_invalidation_map);
102 return object_id_invalidation_map;
105 class UnackedInvalidationsMapEqMatcher
106 : public testing::MatcherInterface<const UnackedInvalidationsMap&> {
107 public:
108 explicit UnackedInvalidationsMapEqMatcher(
109 const UnackedInvalidationsMap& expected);
111 virtual bool MatchAndExplain(const UnackedInvalidationsMap& actual,
112 MatchResultListener* listener) const;
113 virtual void DescribeTo(::std::ostream* os) const;
114 virtual void DescribeNegationTo(::std::ostream* os) const;
116 private:
117 const UnackedInvalidationsMap expected_;
119 DISALLOW_COPY_AND_ASSIGN(UnackedInvalidationsMapEqMatcher);
122 UnackedInvalidationsMapEqMatcher::UnackedInvalidationsMapEqMatcher(
123 const UnackedInvalidationsMap& expected)
124 : expected_(expected) {
127 bool UnackedInvalidationsMapEqMatcher::MatchAndExplain(
128 const UnackedInvalidationsMap& actual,
129 MatchResultListener* listener) const {
130 ObjectIdInvalidationMap expected_inv =
131 UnackedInvalidationsMapToObjectIdInvalidationMap(expected_);
132 ObjectIdInvalidationMap actual_inv =
133 UnackedInvalidationsMapToObjectIdInvalidationMap(actual);
135 return expected_inv == actual_inv;
138 void UnackedInvalidationsMapEqMatcher::DescribeTo(
139 ::std::ostream* os) const {
140 *os << " is equal to " << PrintToString(expected_);
143 void UnackedInvalidationsMapEqMatcher::DescribeNegationTo(
144 ::std::ostream* os) const {
145 *os << " isn't equal to " << PrintToString(expected_);
148 } // namespace
150 void PrintTo(const UnackedInvalidationSet& invalidations,
151 ::std::ostream* os) {
152 scoped_ptr<base::DictionaryValue> value = invalidations.ToValue();
154 std::string output;
155 JSONStringValueSerializer serializer(&output);
156 serializer.set_pretty_print(true);
157 serializer.Serialize(*value.get());
159 (*os) << output;
162 void PrintTo(const UnackedInvalidationsMap& map, ::std::ostream* os) {
163 scoped_ptr<base::ListValue> list(new base::ListValue);
164 for (UnackedInvalidationsMap::const_iterator it = map.begin();
165 it != map.end(); ++it) {
166 list->Append(it->second.ToValue().release());
169 std::string output;
170 JSONStringValueSerializer serializer(&output);
171 serializer.set_pretty_print(true);
172 serializer.Serialize(*list.get());
174 (*os) << output;
177 Matcher<const UnackedInvalidationSet&> Eq(
178 const UnackedInvalidationSet& expected) {
179 return MakeMatcher(new UnackedInvalidationSetEqMatcher(expected));
182 Matcher<const UnackedInvalidationsMap&> Eq(
183 const UnackedInvalidationsMap& expected) {
184 return MakeMatcher(new UnackedInvalidationsMapEqMatcher(expected));
187 class UnackedInvalidationSetTest : public testing::Test {
188 public:
189 UnackedInvalidationSetTest()
190 : kObjectId_(10, "ASDF"),
191 unacked_invalidations_(kObjectId_) {}
193 SingleObjectInvalidationSet GetStoredInvalidations() {
194 ObjectIdInvalidationMap map;
195 unacked_invalidations_.ExportInvalidations(WeakHandle<AckHandler>(), &map);
196 ObjectIdSet ids = map.GetObjectIds();
197 if (ids.find(kObjectId_) != ids.end()) {
198 return map.ForObject(kObjectId_);
199 } else {
200 return SingleObjectInvalidationSet();
204 const invalidation::ObjectId kObjectId_;
205 UnackedInvalidationSet unacked_invalidations_;
208 namespace {
210 // Test storage and retrieval of zero invalidations.
211 TEST_F(UnackedInvalidationSetTest, Empty) {
212 EXPECT_EQ(0U, GetStoredInvalidations().GetSize());
215 // Test storage and retrieval of a single invalidation.
216 TEST_F(UnackedInvalidationSetTest, OneInvalidation) {
217 Invalidation inv1 = Invalidation::Init(kObjectId_, 10, "payload");
218 unacked_invalidations_.Add(inv1);
220 SingleObjectInvalidationSet set = GetStoredInvalidations();
221 ASSERT_EQ(1U, set.GetSize());
222 EXPECT_FALSE(set.StartsWithUnknownVersion());
225 // Test that calling Clear() returns us to the empty state.
226 TEST_F(UnackedInvalidationSetTest, Clear) {
227 Invalidation inv1 = Invalidation::Init(kObjectId_, 10, "payload");
228 unacked_invalidations_.Add(inv1);
229 unacked_invalidations_.Clear();
231 EXPECT_EQ(0U, GetStoredInvalidations().GetSize());
234 // Test that repeated unknown version invalidations are squashed together.
235 TEST_F(UnackedInvalidationSetTest, UnknownVersions) {
236 Invalidation inv1 = Invalidation::Init(kObjectId_, 10, "payload");
237 Invalidation inv2 = Invalidation::InitUnknownVersion(kObjectId_);
238 Invalidation inv3 = Invalidation::InitUnknownVersion(kObjectId_);
239 unacked_invalidations_.Add(inv1);
240 unacked_invalidations_.Add(inv2);
241 unacked_invalidations_.Add(inv3);
243 SingleObjectInvalidationSet set = GetStoredInvalidations();
244 ASSERT_EQ(2U, set.GetSize());
245 EXPECT_TRUE(set.StartsWithUnknownVersion());
248 // Tests that no truncation occurs while we're under the limit.
249 TEST_F(UnackedInvalidationSetTest, NoTruncation) {
250 size_t kMax = UnackedInvalidationSet::kMaxBufferedInvalidations;
252 for (size_t i = 0; i < kMax; ++i) {
253 Invalidation inv = Invalidation::Init(kObjectId_, i, "payload");
254 unacked_invalidations_.Add(inv);
257 SingleObjectInvalidationSet set = GetStoredInvalidations();
258 ASSERT_EQ(kMax, set.GetSize());
259 EXPECT_FALSE(set.StartsWithUnknownVersion());
260 EXPECT_EQ(0, set.begin()->version());
261 EXPECT_EQ(kMax-1, static_cast<size_t>(set.rbegin()->version()));
264 // Test that truncation happens as we reach the limit.
265 TEST_F(UnackedInvalidationSetTest, Truncation) {
266 size_t kMax = UnackedInvalidationSet::kMaxBufferedInvalidations;
268 for (size_t i = 0; i < kMax + 1; ++i) {
269 Invalidation inv = Invalidation::Init(kObjectId_, i, "payload");
270 unacked_invalidations_.Add(inv);
273 SingleObjectInvalidationSet set = GetStoredInvalidations();
274 ASSERT_EQ(kMax, set.GetSize());
275 EXPECT_TRUE(set.StartsWithUnknownVersion());
276 EXPECT_TRUE(set.begin()->is_unknown_version());
277 EXPECT_EQ(kMax, static_cast<size_t>(set.rbegin()->version()));
280 // Test that we don't truncate while a handler is registered.
281 TEST_F(UnackedInvalidationSetTest, RegistrationAndTruncation) {
282 unacked_invalidations_.SetHandlerIsRegistered();
284 size_t kMax = UnackedInvalidationSet::kMaxBufferedInvalidations;
286 for (size_t i = 0; i < kMax + 1; ++i) {
287 Invalidation inv = Invalidation::Init(kObjectId_, i, "payload");
288 unacked_invalidations_.Add(inv);
291 SingleObjectInvalidationSet set = GetStoredInvalidations();
292 ASSERT_EQ(kMax+1, set.GetSize());
293 EXPECT_FALSE(set.StartsWithUnknownVersion());
294 EXPECT_EQ(0, set.begin()->version());
295 EXPECT_EQ(kMax, static_cast<size_t>(set.rbegin()->version()));
297 // Unregistering should re-enable truncation.
298 unacked_invalidations_.SetHandlerIsUnregistered();
299 SingleObjectInvalidationSet set2 = GetStoredInvalidations();
300 ASSERT_EQ(kMax, set2.GetSize());
301 EXPECT_TRUE(set2.StartsWithUnknownVersion());
302 EXPECT_TRUE(set2.begin()->is_unknown_version());
303 EXPECT_EQ(kMax, static_cast<size_t>(set2.rbegin()->version()));
306 // Test acknowledgement.
307 TEST_F(UnackedInvalidationSetTest, Acknowledge) {
308 // inv2 is included in this test just to make sure invalidations that
309 // are supposed to be unaffected by this operation will be unaffected.
311 // We don't expect to be receiving acks or drops unless this flag is set.
312 // Not that it makes much of a difference in behavior.
313 unacked_invalidations_.SetHandlerIsRegistered();
315 Invalidation inv1 = Invalidation::Init(kObjectId_, 10, "payload");
316 Invalidation inv2 = Invalidation::InitUnknownVersion(kObjectId_);
317 AckHandle inv1_handle = inv1.ack_handle();
319 unacked_invalidations_.Add(inv1);
320 unacked_invalidations_.Add(inv2);
322 unacked_invalidations_.Acknowledge(inv1_handle);
324 SingleObjectInvalidationSet set = GetStoredInvalidations();
325 EXPECT_EQ(1U, set.GetSize());
326 EXPECT_TRUE(set.StartsWithUnknownVersion());
329 // Test drops.
330 TEST_F(UnackedInvalidationSetTest, Drop) {
331 // inv2 is included in this test just to make sure invalidations that
332 // are supposed to be unaffected by this operation will be unaffected.
334 // We don't expect to be receiving acks or drops unless this flag is set.
335 // Not that it makes much of a difference in behavior.
336 unacked_invalidations_.SetHandlerIsRegistered();
338 Invalidation inv1 = Invalidation::Init(kObjectId_, 10, "payload");
339 Invalidation inv2 = Invalidation::Init(kObjectId_, 15, "payload");
340 AckHandle inv1_handle = inv1.ack_handle();
342 unacked_invalidations_.Add(inv1);
343 unacked_invalidations_.Add(inv2);
345 unacked_invalidations_.Drop(inv1_handle);
347 SingleObjectInvalidationSet set = GetStoredInvalidations();
348 ASSERT_EQ(2U, set.GetSize());
349 EXPECT_TRUE(set.StartsWithUnknownVersion());
350 EXPECT_EQ(15, set.rbegin()->version());
353 class UnackedInvalidationSetSerializationTest
354 : public UnackedInvalidationSetTest {
355 public:
356 UnackedInvalidationSet SerializeDeserialize() {
357 scoped_ptr<base::DictionaryValue> value = unacked_invalidations_.ToValue();
358 UnackedInvalidationSet deserialized(kObjectId_);
359 deserialized.ResetFromValue(*value.get());
360 return deserialized;
364 TEST_F(UnackedInvalidationSetSerializationTest, Empty) {
365 UnackedInvalidationSet deserialized = SerializeDeserialize();
366 EXPECT_THAT(unacked_invalidations_, Eq(deserialized));
369 TEST_F(UnackedInvalidationSetSerializationTest, OneInvalidation) {
370 Invalidation inv = Invalidation::Init(kObjectId_, 10, "payload");
371 unacked_invalidations_.Add(inv);
373 UnackedInvalidationSet deserialized = SerializeDeserialize();
374 EXPECT_THAT(unacked_invalidations_, Eq(deserialized));
377 TEST_F(UnackedInvalidationSetSerializationTest, WithUnknownVersion) {
378 Invalidation inv1 = Invalidation::Init(kObjectId_, 10, "payload");
379 Invalidation inv2 = Invalidation::InitUnknownVersion(kObjectId_);
380 Invalidation inv3 = Invalidation::InitUnknownVersion(kObjectId_);
381 unacked_invalidations_.Add(inv1);
382 unacked_invalidations_.Add(inv2);
383 unacked_invalidations_.Add(inv3);
385 UnackedInvalidationSet deserialized = SerializeDeserialize();
386 EXPECT_THAT(unacked_invalidations_, Eq(deserialized));
389 } // namespace
391 } // namespace syncer