Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1437)

Side by Side Diff: chrome/browser/sync/invalidations/invalidator_storage_unittest.cc

Issue 11415049: Implement features needed for local ack handling in InvalidationStateTracker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ...... Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 5
6 #include "chrome/browser/sync/invalidations/invalidator_storage.h" 6 #include "chrome/browser/sync/invalidations/invalidator_storage.h"
7 7
8 #include "base/bind.h"
8 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/message_loop_proxy.h"
9 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
10 #include "base/string_util.h" 12 #include "base/string_util.h"
11 #include "chrome/common/pref_names.h" 13 #include "chrome/common/pref_names.h"
12 #include "chrome/test/base/testing_pref_service.h" 14 #include "chrome/test/base/testing_pref_service.h"
15 #include "sync/internal_api/public/base/invalidation_test_util.h"
13 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
15 18
16 using syncer::InvalidationStateMap; 19 using syncer::InvalidationStateMap;
17 20
18 namespace browser_sync { 21 namespace browser_sync {
19 22
20 namespace { 23 namespace {
21 24
22 const char kSourceKey[] = "source"; 25 const char kSourceKey[] = "source";
23 const char kNameKey[] = "name"; 26 const char kNameKey[] = "name";
24 const char kMaxVersionKey[] = "max-version"; 27 const char kMaxVersionKey[] = "max-version";
28 const char kPayloadKey[] = "payload";
29 const char kCurrentAckHandleKey[] = "current-ack";
30 const char kExpectedAckHandleKey[] = "expected-ack";
25 31
26 const int kChromeSyncSourceId = 1004; 32 const int kChromeSyncSourceId = 1004;
27 33
34 void GenerateAckHandlesTestHelper(syncer::AckHandleMap* output,
35 const syncer::AckHandleMap& input) {
36 *output = input;
37 }
38
28 } // namespace 39 } // namespace
29 40
30 class InvalidatorStorageTest : public testing::Test { 41 class InvalidatorStorageTest : public testing::Test {
31 public: 42 public:
32 InvalidatorStorageTest() 43 InvalidatorStorageTest()
33 : kBookmarksId_(kChromeSyncSourceId, "BOOKMARK"), 44 : kBookmarksId_(kChromeSyncSourceId, "BOOKMARK"),
34 kPreferencesId_(kChromeSyncSourceId, "PREFERENCE"), 45 kPreferencesId_(kChromeSyncSourceId, "PREFERENCE"),
35 kAppNotificationsId_(kChromeSyncSourceId, "APP_NOTIFICATION"), 46 kAppNotificationsId_(kChromeSyncSourceId, "APP_NOTIFICATION"),
36 kAutofillId_(kChromeSyncSourceId, "AUTOFILL") {} 47 kAutofillId_(kChromeSyncSourceId, "AUTOFILL") {}
37 48
38 protected: 49 protected:
39 TestingPrefService pref_service_; 50 TestingPrefService pref_service_;
40 51
41 const invalidation::ObjectId kBookmarksId_; 52 const invalidation::ObjectId kBookmarksId_;
42 const invalidation::ObjectId kPreferencesId_; 53 const invalidation::ObjectId kPreferencesId_;
43 const invalidation::ObjectId kAppNotificationsId_; 54 const invalidation::ObjectId kAppNotificationsId_;
44 const invalidation::ObjectId kAutofillId_; 55 const invalidation::ObjectId kAutofillId_;
45 56
46 private:
47 MessageLoop loop_; 57 MessageLoop loop_;
48 }; 58 };
49 59
50 // Set max versions for various keys and verify that they are written and read 60 // Set invalidation states for various keys and verify that they are written and
51 // back correctly. 61 // read back correctly.
52 TEST_F(InvalidatorStorageTest, MaxInvalidationVersions) { 62 TEST_F(InvalidatorStorageTest, SetMaxVersionAndPayload) {
53 InvalidatorStorage storage(&pref_service_); 63 InvalidatorStorage storage(&pref_service_);
54 64
55 InvalidationStateMap expected_max_versions; 65 InvalidationStateMap expected_states;
56 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 66 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
57 67
58 expected_max_versions[kBookmarksId_].version = 2; 68 expected_states[kBookmarksId_].version = 2;
59 storage.SetMaxVersion(kBookmarksId_, 2); 69 expected_states[kBookmarksId_].payload = "hello";
60 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 70 storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "hello");
71 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
61 72
62 expected_max_versions[kPreferencesId_].version = 5; 73 expected_states[kPreferencesId_].version = 5;
63 storage.SetMaxVersion(kPreferencesId_, 5); 74 storage.SetMaxVersionAndPayload(kPreferencesId_, 5, std::string());
64 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 75 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
65 76
66 expected_max_versions[kAppNotificationsId_].version = 3; 77 expected_states[kAppNotificationsId_].version = 3;
67 storage.SetMaxVersion(kAppNotificationsId_, 3); 78 expected_states[kAppNotificationsId_].payload = "world";
68 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 79 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 3, "world");
80 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
69 81
70 expected_max_versions[kAppNotificationsId_].version = 4; 82 expected_states[kAppNotificationsId_].version = 4;
71 storage.SetMaxVersion(kAppNotificationsId_, 4); 83 expected_states[kAppNotificationsId_].payload = "again";
72 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 84 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 4, "again");
85 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
73 } 86 }
74 87
75 // Forgetting an entry should cause that entry to be deleted. 88 // Forgetting an entry should cause that entry to be deleted.
76 TEST_F(InvalidatorStorageTest, Forget) { 89 TEST_F(InvalidatorStorageTest, Forget) {
77 InvalidatorStorage storage(&pref_service_); 90 InvalidatorStorage storage(&pref_service_);
78 EXPECT_TRUE(storage.GetAllInvalidationStates().empty()); 91 EXPECT_TRUE(storage.GetAllInvalidationStates().empty());
79 92
80 InvalidationStateMap expected_max_versions; 93 InvalidationStateMap expected_states;
81 expected_max_versions[kBookmarksId_].version = 2; 94 expected_states[kBookmarksId_].version = 2;
82 expected_max_versions[kPreferencesId_].version = 5; 95 expected_states[kBookmarksId_].payload = "a";
83 storage.SetMaxVersion(kBookmarksId_, 2); 96 expected_states[kPreferencesId_].version = 5;
84 storage.SetMaxVersion(kPreferencesId_, 5); 97 expected_states[kPreferencesId_].payload = "b";
85 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 98 storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "a");
99 storage.SetMaxVersionAndPayload(kPreferencesId_, 5, "b");
100 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
86 101
87 expected_max_versions.erase(kPreferencesId_); 102 expected_states.erase(kPreferencesId_);
88 syncer::ObjectIdSet to_forget; 103 syncer::ObjectIdSet to_forget;
89 to_forget.insert(kPreferencesId_); 104 to_forget.insert(kPreferencesId_);
90 storage.Forget(to_forget); 105 storage.Forget(to_forget);
91 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 106 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
92 } 107 }
93 108
94 // Clearing the storage should erase all version map entries and the bootstrap 109 // Clearing the storage should erase all version map entries and the bootstrap
95 // data. 110 // data.
96 TEST_F(InvalidatorStorageTest, Clear) { 111 TEST_F(InvalidatorStorageTest, Clear) {
97 InvalidatorStorage storage(&pref_service_); 112 InvalidatorStorage storage(&pref_service_);
98 EXPECT_TRUE(storage.GetAllInvalidationStates().empty()); 113 EXPECT_TRUE(storage.GetAllInvalidationStates().empty());
99 EXPECT_TRUE(storage.GetBootstrapData().empty()); 114 EXPECT_TRUE(storage.GetBootstrapData().empty());
100 115
101 storage.SetBootstrapData("test"); 116 storage.SetBootstrapData("test");
102 EXPECT_EQ("test", storage.GetBootstrapData()); 117 EXPECT_EQ("test", storage.GetBootstrapData());
103 { 118 {
104 InvalidationStateMap expected_max_versions; 119 InvalidationStateMap expected_states;
105 expected_max_versions[kAppNotificationsId_].version = 3; 120 expected_states[kAppNotificationsId_].version = 3;
106 storage.SetMaxVersion(kAppNotificationsId_, 3); 121 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 3, std::string());
107 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 122 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
108 } 123 }
109 124
110 storage.Clear(); 125 storage.Clear();
111 126
112 EXPECT_TRUE(storage.GetAllInvalidationStates().empty()); 127 EXPECT_TRUE(storage.GetAllInvalidationStates().empty());
113 EXPECT_TRUE(storage.GetBootstrapData().empty()); 128 EXPECT_TRUE(storage.GetBootstrapData().empty());
114 } 129 }
115 130
116 TEST_F(InvalidatorStorageTest, SerializeEmptyMap) { 131 TEST_F(InvalidatorStorageTest, SerializeEmptyMap) {
117 InvalidationStateMap empty_map; 132 InvalidationStateMap empty_map;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 EXPECT_EQ(15, map[kBookmarksId_].version); 235 EXPECT_EQ(15, map[kBookmarksId_].version);
221 } 236 }
222 237
223 TEST_F(InvalidatorStorageTest, DeserializeFromEmptyList) { 238 TEST_F(InvalidatorStorageTest, DeserializeFromEmptyList) {
224 InvalidationStateMap map; 239 InvalidationStateMap map;
225 base::ListValue list; 240 base::ListValue list;
226 InvalidatorStorage::DeserializeFromList(list, &map); 241 InvalidatorStorage::DeserializeFromList(list, &map);
227 EXPECT_TRUE(map.empty()); 242 EXPECT_TRUE(map.empty());
228 } 243 }
229 244
230 // Tests that deserializing a well-formed value results in the expected version 245 // Tests that deserializing a well-formed value results in the expected state
231 // map. 246 // map.
232 TEST_F(InvalidatorStorageTest, DeserializeFromListBasic) { 247 TEST_F(InvalidatorStorageTest, DeserializeFromListBasic) {
233 InvalidationStateMap map; 248 InvalidationStateMap map;
234 base::ListValue list; 249 base::ListValue list;
235 DictionaryValue* value; 250 DictionaryValue* value;
251 syncer::AckHandle ack_handle_1 = syncer::AckHandle::CreateUnique();
252 syncer::AckHandle ack_handle_2 = syncer::AckHandle::CreateUnique();
236 253
237 value = new DictionaryValue(); 254 value = new DictionaryValue();
255 value->SetString(kSourceKey,
256 base::IntToString(kAppNotificationsId_.source()));
257 value->SetString(kNameKey, kAppNotificationsId_.name());
258 value->SetString(kMaxVersionKey, "20");
259 value->SetString(kPayloadKey, "testing");
260 value->Set(kCurrentAckHandleKey, ack_handle_1.ToValue().release());
261 value->Set(kExpectedAckHandleKey, ack_handle_2.ToValue().release());
262 list.Append(value);
263
264 InvalidatorStorage::DeserializeFromList(list, &map);
265 EXPECT_EQ(1U, map.size());
266 EXPECT_EQ(20, map[kAppNotificationsId_].version);
267 EXPECT_EQ("testing", map[kAppNotificationsId_].payload);
268 EXPECT_THAT(map[kAppNotificationsId_].current, Eq(ack_handle_1));
269 EXPECT_THAT(map[kAppNotificationsId_].expected, Eq(ack_handle_2));
270 }
271
272 // Tests that deserializing well-formed values when optional parameters are
273 // omitted works.
274 TEST_F(InvalidatorStorageTest, DeserializeFromListMissingOptionalValues) {
275 InvalidationStateMap map;
276 base::ListValue list;
277 DictionaryValue* value;
278 syncer::AckHandle ack_handle = syncer::AckHandle::CreateUnique();
279
280 // Payload missing because of an upgrade from a previous browser version that
281 // didn't set the field.
282 value = new DictionaryValue();
238 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source())); 283 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source()));
239 value->SetString(kNameKey, kAutofillId_.name()); 284 value->SetString(kNameKey, kAutofillId_.name());
240 value->SetString(kMaxVersionKey, "10"); 285 value->SetString(kMaxVersionKey, "10");
241 list.Append(value); 286 list.Append(value);
287 // A crash between SetMaxVersion() and a callback from GenerateAckHandles()
288 // could result in this state.
242 value = new DictionaryValue(); 289 value = new DictionaryValue();
243 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source())); 290 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source()));
244 value->SetString(kNameKey, kBookmarksId_.name()); 291 value->SetString(kNameKey, kBookmarksId_.name());
245 value->SetString(kMaxVersionKey, "15"); 292 value->SetString(kMaxVersionKey, "15");
293 value->SetString(kPayloadKey, "hello");
294 list.Append(value);
295 // Never acknowledged, so current ack handle is unset.
296 value = new DictionaryValue();
297 value->SetString(kSourceKey, base::IntToString(kPreferencesId_.source()));
298 value->SetString(kNameKey, kPreferencesId_.name());
299 value->SetString(kMaxVersionKey, "20");
300 value->SetString(kPayloadKey, "world");
301 value->Set(kExpectedAckHandleKey, ack_handle.ToValue().release());
246 list.Append(value); 302 list.Append(value);
247 303
248 InvalidatorStorage::DeserializeFromList(list, &map); 304 InvalidatorStorage::DeserializeFromList(list, &map);
249 EXPECT_EQ(2U, map.size()); 305 EXPECT_EQ(3U, map.size());
306
250 EXPECT_EQ(10, map[kAutofillId_].version); 307 EXPECT_EQ(10, map[kAutofillId_].version);
308 EXPECT_EQ("", map[kAutofillId_].payload);
309 EXPECT_FALSE(map[kAutofillId_].current.IsValid());
310 EXPECT_FALSE(map[kAutofillId_].expected.IsValid());
311
251 EXPECT_EQ(15, map[kBookmarksId_].version); 312 EXPECT_EQ(15, map[kBookmarksId_].version);
313 EXPECT_EQ("hello", map[kBookmarksId_].payload);
314 EXPECT_FALSE(map[kBookmarksId_].current.IsValid());
315 EXPECT_FALSE(map[kBookmarksId_].expected.IsValid());
316
317 EXPECT_EQ(20, map[kPreferencesId_].version);
318 EXPECT_EQ("world", map[kPreferencesId_].payload);
319 EXPECT_FALSE(map[kPreferencesId_].current.IsValid());
320 EXPECT_THAT(map[kPreferencesId_].expected, Eq(ack_handle));
252 } 321 }
253 322
254 // Tests for legacy deserialization code. 323 // Tests for legacy deserialization code.
255 TEST_F(InvalidatorStorageTest, DeserializeMapOutOfRange) { 324 TEST_F(InvalidatorStorageTest, DeserializeMapOutOfRange) {
256 InvalidationStateMap map; 325 InvalidationStateMap map;
257 base::DictionaryValue dict_with_out_of_range_type; 326 base::DictionaryValue dict_with_out_of_range_type;
258 327
259 dict_with_out_of_range_type.SetString( 328 dict_with_out_of_range_type.SetString(
260 base::IntToString(syncer::TOP_LEVEL_FOLDER), "100"); 329 base::IntToString(syncer::TOP_LEVEL_FOLDER), "100");
261 dict_with_out_of_range_type.SetString( 330 dict_with_out_of_range_type.SetString(
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 402
334 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) { 403 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) {
335 InvalidatorStorage storage(&pref_service_); 404 InvalidatorStorage storage(&pref_service_);
336 const std::string mess("n\0tK\0\0l\344", 8); 405 const std::string mess("n\0tK\0\0l\344", 8);
337 ASSERT_FALSE(IsStringUTF8(mess)); 406 ASSERT_FALSE(IsStringUTF8(mess));
338 407
339 storage.SetBootstrapData(mess); 408 storage.SetBootstrapData(mess);
340 EXPECT_EQ(mess, storage.GetBootstrapData()); 409 EXPECT_EQ(mess, storage.GetBootstrapData());
341 } 410 }
342 411
412 // Test that we correctly generate ack handles, acknowledge them, and persist
413 // them.
414 TEST_F(InvalidatorStorageTest, GenerateAckHandlesAndAcknowledge) {
415 InvalidatorStorage storage(&pref_service_);
416 syncer::ObjectIdSet ids;
417 InvalidationStateMap state_map;
418 syncer::AckHandleMap ack_handle_map;
419 syncer::AckHandleMap::const_iterator it;
420
421 // Test that it works as expected if the key doesn't already exist in the map,
422 // e.g. the first invalidation received for the object ID was not for a
423 // specific version.
424 ids.insert(kAutofillId_);
425 storage.GenerateAckHandles(
426 ids, base::MessageLoopProxy::current(),
427 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
428 loop_.RunUntilIdle();
429 EXPECT_EQ(1U, ack_handle_map.size());
430 it = ack_handle_map.find(kAutofillId_);
431 // Android STL appears to be buggy and causes gtest's IsContainerTest<> to
432 // treat an iterator as a STL container so we use != instead of ASSERT_NE.
433 ASSERT_TRUE(ack_handle_map.end() != it);
434 EXPECT_TRUE(it->second.IsValid());
435 state_map[kAutofillId_].expected = it->second;
436 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
437
438 storage.Acknowledge(kAutofillId_, it->second);
439 state_map[kAutofillId_].current = it->second;
440 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
441
442 ids.clear();
443
444 // Test that it works as expected if the key already exists.
445 state_map[kBookmarksId_].version = 11;
446 state_map[kBookmarksId_].payload = "hello";
447 storage.SetMaxVersionAndPayload(kBookmarksId_, 11, "hello");
448 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
449 ids.insert(kBookmarksId_);
450 storage.GenerateAckHandles(
451 ids, base::MessageLoopProxy::current(),
452 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
453 loop_.RunUntilIdle();
454 EXPECT_EQ(1U, ack_handle_map.size());
455 it = ack_handle_map.find(kBookmarksId_);
456 ASSERT_TRUE(ack_handle_map.end() != it);
457 EXPECT_TRUE(it->second.IsValid());
458 state_map[kBookmarksId_].expected = it->second;
459 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
460
461 storage.Acknowledge(kBookmarksId_, it->second);
462 state_map[kBookmarksId_].current = it->second;
463 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
464
465 // Finally, test that the ack handles are updated if we're asked to generate
466 // another ack handle for the same object ID.
467 state_map[kBookmarksId_].version = 12;
468 state_map[kBookmarksId_].payload = "world";
469 storage.SetMaxVersionAndPayload(kBookmarksId_, 12, "world");
470 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
471 ids.insert(kBookmarksId_);
472 storage.GenerateAckHandles(
473 ids, base::MessageLoopProxy::current(),
474 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
475 loop_.RunUntilIdle();
476 EXPECT_EQ(1U, ack_handle_map.size());
477 it = ack_handle_map.find(kBookmarksId_);
478 ASSERT_TRUE(ack_handle_map.end() != it);
479 EXPECT_TRUE(it->second.IsValid());
480 state_map[kBookmarksId_].expected = it->second;
481 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
482
483 storage.Acknowledge(kBookmarksId_, it->second);
484 state_map[kBookmarksId_].current = it->second;
485 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
486 }
487
343 } // namespace browser_sync 488 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/invalidations/invalidator_storage.cc ('k') | sync/internal_api/public/base/invalidation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698