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

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, 1 month 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 max versions for various keys and verify that they are written and read
51 // back correctly. 61 // back correctly.
52 TEST_F(InvalidatorStorageTest, MaxInvalidationVersions) { 62 TEST_F(InvalidatorStorageTest, MaxInvalidationVersions) {
53 InvalidatorStorage storage(&pref_service_); 63 InvalidatorStorage storage(&pref_service_);
54 64
55 InvalidationStateMap expected_max_versions; 65 InvalidationStateMap expected_max_versions;
56 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 66 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
57 67
58 expected_max_versions[kBookmarksId_].version = 2; 68 expected_max_versions[kBookmarksId_].version = 2;
59 storage.SetMaxVersion(kBookmarksId_, 2); 69 expected_max_versions[kBookmarksId_].payload = "hello";
70 storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "hello");
60 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 71 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
61 72
62 expected_max_versions[kPreferencesId_].version = 5; 73 expected_max_versions[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_max_versions, storage.GetAllInvalidationStates());
65 76
66 expected_max_versions[kAppNotificationsId_].version = 3; 77 expected_max_versions[kAppNotificationsId_].version = 3;
67 storage.SetMaxVersion(kAppNotificationsId_, 3); 78 expected_max_versions[kAppNotificationsId_].payload = "world";
79 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 3, "world");
68 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 80 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
69 81
70 expected_max_versions[kAppNotificationsId_].version = 4; 82 expected_max_versions[kAppNotificationsId_].version = 4;
71 storage.SetMaxVersion(kAppNotificationsId_, 4); 83 expected_max_versions[kAppNotificationsId_].payload = "again";
84 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 4, "again");
72 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 85 EXPECT_EQ(expected_max_versions, 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_max_versions;
81 expected_max_versions[kBookmarksId_].version = 2; 94 expected_max_versions[kBookmarksId_].version = 2;
95 expected_max_versions[kBookmarksId_].payload = "a";
82 expected_max_versions[kPreferencesId_].version = 5; 96 expected_max_versions[kPreferencesId_].version = 5;
83 storage.SetMaxVersion(kBookmarksId_, 2); 97 expected_max_versions[kPreferencesId_].payload = "b";
84 storage.SetMaxVersion(kPreferencesId_, 5); 98 storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "a");
99 storage.SetMaxVersionAndPayload(kPreferencesId_, 5, "b");
85 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates()); 100 EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
86 101
87 expected_max_versions.erase(kPreferencesId_); 102 expected_max_versions.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_max_versions, 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_max_versions;
105 expected_max_versions[kAppNotificationsId_].version = 3; 120 expected_max_versions[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_max_versions, 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) {
(...skipping 26 matching lines...) Expand all
143 value = new DictionaryValue(); 158 value = new DictionaryValue();
144 value->SetString(kNameKey, "missing source and version"); 159 value->SetString(kNameKey, "missing source and version");
145 list_with_invalid_format.Append(value); 160 list_with_invalid_format.Append(value);
146 161
147 value = new DictionaryValue(); 162 value = new DictionaryValue();
148 value->SetString(kMaxVersionKey, "3"); 163 value->SetString(kMaxVersionKey, "3");
149 list_with_invalid_format.Append(value); 164 list_with_invalid_format.Append(value);
150 165
151 // Missing one required field 166 // Missing one required field
152 value = new DictionaryValue(); 167 value = new DictionaryValue();
153 value->SetString(kSourceKey, "14");
154 value->SetString(kNameKey, "missing version");
155 list_with_invalid_format.Append(value);
156
157 value = new DictionaryValue();
158 value->SetString(kSourceKey, "233"); 168 value->SetString(kSourceKey, "233");
159 value->SetString(kMaxVersionKey, "5"); 169 value->SetString(kMaxVersionKey, "5");
160 list_with_invalid_format.Append(value); 170 list_with_invalid_format.Append(value);
161 171
162 value = new DictionaryValue(); 172 value = new DictionaryValue();
163 value->SetString(kNameKey, "missing source"); 173 value->SetString(kNameKey, "missing source");
164 value->SetString(kMaxVersionKey, "25"); 174 value->SetString(kMaxVersionKey, "25");
165 list_with_invalid_format.Append(value); 175 list_with_invalid_format.Append(value);
166 176
167 // Invalid values in fields 177 // Invalid values in fields
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 EXPECT_TRUE(map.empty()); 237 EXPECT_TRUE(map.empty());
228 } 238 }
229 239
230 // Tests that deserializing a well-formed value results in the expected version 240 // Tests that deserializing a well-formed value results in the expected version
231 // map. 241 // map.
232 TEST_F(InvalidatorStorageTest, DeserializeFromListBasic) { 242 TEST_F(InvalidatorStorageTest, DeserializeFromListBasic) {
233 InvalidationStateMap map; 243 InvalidationStateMap map;
234 base::ListValue list; 244 base::ListValue list;
235 DictionaryValue* value; 245 DictionaryValue* value;
236 246
247 // Payload missing because of an upgrade from a version that didn't set it.
237 value = new DictionaryValue(); 248 value = new DictionaryValue();
238 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source())); 249 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source()));
239 value->SetString(kNameKey, kAutofillId_.name()); 250 value->SetString(kNameKey, kAutofillId_.name());
240 value->SetString(kMaxVersionKey, "10"); 251 value->SetString(kMaxVersionKey, "10");
241 list.Append(value); 252 list.Append(value);
253 // Crash between SetMaxVersion() and a callback from GenerateAckHandles()
254 // could result in this state.
242 value = new DictionaryValue(); 255 value = new DictionaryValue();
243 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source())); 256 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source()));
244 value->SetString(kNameKey, kBookmarksId_.name()); 257 value->SetString(kNameKey, kBookmarksId_.name());
245 value->SetString(kMaxVersionKey, "15"); 258 value->SetString(kMaxVersionKey, "15");
259 value->SetString(kPayloadKey, "hello");
260 list.Append(value);
261 syncer::AckHandle ack_handle_1 = syncer::AckHandle::CreateUnique();
262 syncer::AckHandle ack_handle_2 = syncer::AckHandle::CreateUnique();
263 syncer::AckHandle ack_handle_3 = syncer::AckHandle::CreateUnique();
264 syncer::AckHandle ack_handle_4 = syncer::AckHandle::CreateUnique();
265 // We've never received an invalidation for a specific version, so no max
266 // version or payload information.
267 value = new DictionaryValue();
268 value->SetString(kSourceKey, base::IntToString(kPreferencesId_.source()));
269 value->SetString(kNameKey, kPreferencesId_.name());
270 value->Set(kCurrentAckHandleKey, ack_handle_1.ToValue().release());
271 value->Set(kExpectedAckHandleKey, ack_handle_2.ToValue().release());
272 list.Append(value);
273 // All fields set.
274 value = new DictionaryValue();
275 value->SetString(kSourceKey,
276 base::IntToString(kAppNotificationsId_.source()));
277 value->SetString(kNameKey, kAppNotificationsId_.name());
278 value->SetString(kMaxVersionKey, "20");
279 value->SetString(kPayloadKey, "world");
280 value->Set(kCurrentAckHandleKey, ack_handle_3.ToValue().release());
281 value->Set(kExpectedAckHandleKey, ack_handle_4.ToValue().release());
246 list.Append(value); 282 list.Append(value);
247 283
248 InvalidatorStorage::DeserializeFromList(list, &map); 284 InvalidatorStorage::DeserializeFromList(list, &map);
249 EXPECT_EQ(2U, map.size()); 285 EXPECT_EQ(4U, map.size());
250 EXPECT_EQ(10, map[kAutofillId_].version); 286 EXPECT_EQ(10, map[kAutofillId_].version);
287 EXPECT_EQ(std::string(), map[kAutofillId_].payload);
288 EXPECT_FALSE(map[kAutofillId_].current.IsValid());
289 EXPECT_FALSE(map[kAutofillId_].expected.IsValid());
251 EXPECT_EQ(15, map[kBookmarksId_].version); 290 EXPECT_EQ(15, map[kBookmarksId_].version);
291 EXPECT_EQ("hello", map[kBookmarksId_].payload);
292 EXPECT_FALSE(map[kBookmarksId_].current.IsValid());
293 EXPECT_FALSE(map[kBookmarksId_].expected.IsValid());
294 EXPECT_EQ(kint64min, map[kPreferencesId_].version);
295 EXPECT_EQ(std::string(), map[kPreferencesId_].payload);
296 EXPECT_THAT(map[kPreferencesId_].current, Eq(ack_handle_1));
297 EXPECT_THAT(map[kPreferencesId_].expected, Eq(ack_handle_2));
298 EXPECT_EQ(20, map[kAppNotificationsId_].version);
299 EXPECT_EQ("world", map[kAppNotificationsId_].payload);
300 EXPECT_THAT(map[kAppNotificationsId_].current, Eq(ack_handle_3));
301 EXPECT_THAT(map[kAppNotificationsId_].expected, Eq(ack_handle_4));
252 } 302 }
253 303
254 // Tests for legacy deserialization code. 304 // Tests for legacy deserialization code.
255 TEST_F(InvalidatorStorageTest, DeserializeMapOutOfRange) { 305 TEST_F(InvalidatorStorageTest, DeserializeMapOutOfRange) {
256 InvalidationStateMap map; 306 InvalidationStateMap map;
257 base::DictionaryValue dict_with_out_of_range_type; 307 base::DictionaryValue dict_with_out_of_range_type;
258 308
259 dict_with_out_of_range_type.SetString( 309 dict_with_out_of_range_type.SetString(
260 base::IntToString(syncer::TOP_LEVEL_FOLDER), "100"); 310 base::IntToString(syncer::TOP_LEVEL_FOLDER), "100");
261 dict_with_out_of_range_type.SetString( 311 dict_with_out_of_range_type.SetString(
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 383
334 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) { 384 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) {
335 InvalidatorStorage storage(&pref_service_); 385 InvalidatorStorage storage(&pref_service_);
336 const std::string mess("n\0tK\0\0l\344", 8); 386 const std::string mess("n\0tK\0\0l\344", 8);
337 ASSERT_FALSE(IsStringUTF8(mess)); 387 ASSERT_FALSE(IsStringUTF8(mess));
338 388
339 storage.SetBootstrapData(mess); 389 storage.SetBootstrapData(mess);
340 EXPECT_EQ(mess, storage.GetBootstrapData()); 390 EXPECT_EQ(mess, storage.GetBootstrapData());
341 } 391 }
342 392
393 // Test that we correctly generate ack handles, acknowledge them, and persist
394 // them.
395 TEST_F(InvalidatorStorageTest, GenerateAckHandlesAndAcknowledge) {
396 InvalidatorStorage storage(&pref_service_);
397 syncer::ObjectIdSet ids;
398 InvalidationStateMap state_map;
399 syncer::AckHandleMap ack_handle_map;
400 syncer::AckHandleMap::const_iterator it;
401
402 // Test that it works as expected if the key doesn't already exist in the map,
403 // e.g. the first invalidation received for the object ID was not for a
404 // specific version.
405 ids.insert(kAutofillId_);
406 storage.GenerateAckHandles(
407 ids, base::MessageLoopProxy::current(),
408 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
409 loop_.RunUntilIdle();
410 EXPECT_EQ(1U, ack_handle_map.size());
411 it = ack_handle_map.find(kAutofillId_);
412 ASSERT_NE(ack_handle_map.end(), it);
413 EXPECT_TRUE(it->second.IsValid());
414 state_map[kAutofillId_].expected = it->second;
415 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
416
417 storage.Acknowledge(kAutofillId_, it->second);
418 state_map[kAutofillId_].current = it->second;
419 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
420
421 ids.clear();
422
423 // Test that it works as expected if the key already exists.
424 state_map[kBookmarksId_].version = 11;
425 state_map[kBookmarksId_].payload = "hello";
426 storage.SetMaxVersionAndPayload(kBookmarksId_, 11, "hello");
427 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
428 ids.insert(kBookmarksId_);
429 storage.GenerateAckHandles(
430 ids, base::MessageLoopProxy::current(),
431 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
432 loop_.RunUntilIdle();
433 EXPECT_EQ(1U, ack_handle_map.size());
434 it = ack_handle_map.find(kBookmarksId_);
435 ASSERT_NE(ack_handle_map.end(), it);
436 EXPECT_TRUE(it->second.IsValid());
437 state_map[kBookmarksId_].expected = it->second;
438 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
439
440 storage.Acknowledge(kBookmarksId_, it->second);
441 state_map[kBookmarksId_].current = it->second;
442 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
443
444 // Finally, test that the ack handles are updated on if we're asked to
445 // generate another ack handle for the same key.
446 state_map[kBookmarksId_].version = 12;
447 state_map[kBookmarksId_].payload = "world";
448 storage.SetMaxVersionAndPayload(kBookmarksId_, 12, "world");
449 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
450 ids.insert(kBookmarksId_);
451 storage.GenerateAckHandles(
452 ids, base::MessageLoopProxy::current(),
453 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
454 loop_.RunUntilIdle();
455 EXPECT_EQ(1U, ack_handle_map.size());
456 it = ack_handle_map.find(kBookmarksId_);
457 ASSERT_NE(ack_handle_map.end(), it);
458 EXPECT_TRUE(it->second.IsValid());
459 state_map[kBookmarksId_].expected = it->second;
460 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
461
462 storage.Acknowledge(kBookmarksId_, it->second);
463 state_map[kBookmarksId_].current = it->second;
464 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
465 }
466
343 } // namespace browser_sync 467 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698