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

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
akalin 2012/11/28 00:11:42 update comment and test name (version -> state)
dcheng 2012/11/30 01:42:54 Done.
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;
akalin 2012/11/28 00:11:42 upate name
dcheng 2012/11/30 01:42:54 Done.
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;
akalin 2012/11/28 00:11:42 names
dcheng 2012/11/30 01:42:54 Done.
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 232
223 TEST_F(InvalidatorStorageTest, DeserializeFromEmptyList) { 233 TEST_F(InvalidatorStorageTest, DeserializeFromEmptyList) {
224 InvalidationStateMap map; 234 InvalidationStateMap map;
225 base::ListValue list; 235 base::ListValue list;
226 InvalidatorStorage::DeserializeFromList(list, &map); 236 InvalidatorStorage::DeserializeFromList(list, &map);
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) {
akalin 2012/11/28 00:11:42 perhaps split this test up into smaller ones?
dcheng 2012/11/30 01:42:54 Done.
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 previous browser version that
248 // didn't set the field.
237 value = new DictionaryValue(); 249 value = new DictionaryValue();
238 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source())); 250 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source()));
239 value->SetString(kNameKey, kAutofillId_.name()); 251 value->SetString(kNameKey, kAutofillId_.name());
240 value->SetString(kMaxVersionKey, "10"); 252 value->SetString(kMaxVersionKey, "10");
241 list.Append(value); 253 list.Append(value);
254 // A crash between SetMaxVersion() and a callback from GenerateAckHandles()
255 // could result in this state.
242 value = new DictionaryValue(); 256 value = new DictionaryValue();
243 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source())); 257 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source()));
244 value->SetString(kNameKey, kBookmarksId_.name()); 258 value->SetString(kNameKey, kBookmarksId_.name());
245 value->SetString(kMaxVersionKey, "15"); 259 value->SetString(kMaxVersionKey, "15");
260 value->SetString(kPayloadKey, "hello");
261 list.Append(value);
262 syncer::AckHandle ack_handle_1 = syncer::AckHandle::CreateUnique();
263 syncer::AckHandle ack_handle_2 = syncer::AckHandle::CreateUnique();
264 syncer::AckHandle ack_handle_3 = syncer::AckHandle::CreateUnique();
265 syncer::AckHandle ack_handle_4 = syncer::AckHandle::CreateUnique();
266 // We've never received an invalidation for a specific version, so no max
267 // version or payload information.
268 value = new DictionaryValue();
269 value->SetString(kSourceKey, base::IntToString(kPreferencesId_.source()));
270 value->SetString(kNameKey, kPreferencesId_.name());
271 value->Set(kCurrentAckHandleKey, ack_handle_1.ToValue().release());
272 value->Set(kExpectedAckHandleKey, ack_handle_2.ToValue().release());
273 list.Append(value);
274 // All fields set.
275 value = new DictionaryValue();
276 value->SetString(kSourceKey,
277 base::IntToString(kAppNotificationsId_.source()));
278 value->SetString(kNameKey, kAppNotificationsId_.name());
279 value->SetString(kMaxVersionKey, "20");
280 value->SetString(kPayloadKey, "world");
281 value->Set(kCurrentAckHandleKey, ack_handle_3.ToValue().release());
282 value->Set(kExpectedAckHandleKey, ack_handle_4.ToValue().release());
246 list.Append(value); 283 list.Append(value);
247 284
248 InvalidatorStorage::DeserializeFromList(list, &map); 285 InvalidatorStorage::DeserializeFromList(list, &map);
249 EXPECT_EQ(2U, map.size()); 286 EXPECT_EQ(4U, map.size());
250 EXPECT_EQ(10, map[kAutofillId_].version); 287 EXPECT_EQ(10, map[kAutofillId_].version);
288 EXPECT_EQ(std::string(), map[kAutofillId_].payload);
289 EXPECT_FALSE(map[kAutofillId_].current.IsValid());
290 EXPECT_FALSE(map[kAutofillId_].expected.IsValid());
251 EXPECT_EQ(15, map[kBookmarksId_].version); 291 EXPECT_EQ(15, map[kBookmarksId_].version);
292 EXPECT_EQ("hello", map[kBookmarksId_].payload);
293 EXPECT_FALSE(map[kBookmarksId_].current.IsValid());
294 EXPECT_FALSE(map[kBookmarksId_].expected.IsValid());
295 EXPECT_EQ(kint64min, map[kPreferencesId_].version);
296 EXPECT_EQ(std::string(), map[kPreferencesId_].payload);
297 EXPECT_THAT(map[kPreferencesId_].current, Eq(ack_handle_1));
298 EXPECT_THAT(map[kPreferencesId_].expected, Eq(ack_handle_2));
299 EXPECT_EQ(20, map[kAppNotificationsId_].version);
300 EXPECT_EQ("world", map[kAppNotificationsId_].payload);
301 EXPECT_THAT(map[kAppNotificationsId_].current, Eq(ack_handle_3));
302 EXPECT_THAT(map[kAppNotificationsId_].expected, Eq(ack_handle_4));
252 } 303 }
253 304
254 // Tests for legacy deserialization code. 305 // Tests for legacy deserialization code.
255 TEST_F(InvalidatorStorageTest, DeserializeMapOutOfRange) { 306 TEST_F(InvalidatorStorageTest, DeserializeMapOutOfRange) {
256 InvalidationStateMap map; 307 InvalidationStateMap map;
257 base::DictionaryValue dict_with_out_of_range_type; 308 base::DictionaryValue dict_with_out_of_range_type;
258 309
259 dict_with_out_of_range_type.SetString( 310 dict_with_out_of_range_type.SetString(
260 base::IntToString(syncer::TOP_LEVEL_FOLDER), "100"); 311 base::IntToString(syncer::TOP_LEVEL_FOLDER), "100");
261 dict_with_out_of_range_type.SetString( 312 dict_with_out_of_range_type.SetString(
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 384
334 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) { 385 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) {
335 InvalidatorStorage storage(&pref_service_); 386 InvalidatorStorage storage(&pref_service_);
336 const std::string mess("n\0tK\0\0l\344", 8); 387 const std::string mess("n\0tK\0\0l\344", 8);
337 ASSERT_FALSE(IsStringUTF8(mess)); 388 ASSERT_FALSE(IsStringUTF8(mess));
338 389
339 storage.SetBootstrapData(mess); 390 storage.SetBootstrapData(mess);
340 EXPECT_EQ(mess, storage.GetBootstrapData()); 391 EXPECT_EQ(mess, storage.GetBootstrapData());
341 } 392 }
342 393
394 // Test that we correctly generate ack handles, acknowledge them, and persist
395 // them.
396 TEST_F(InvalidatorStorageTest, GenerateAckHandlesAndAcknowledge) {
397 InvalidatorStorage storage(&pref_service_);
398 syncer::ObjectIdSet ids;
399 InvalidationStateMap state_map;
400 syncer::AckHandleMap ack_handle_map;
401 syncer::AckHandleMap::const_iterator it;
402
403 // Test that it works as expected if the key doesn't already exist in the map,
404 // e.g. the first invalidation received for the object ID was not for a
405 // specific version.
406 ids.insert(kAutofillId_);
407 storage.GenerateAckHandles(
408 ids, base::MessageLoopProxy::current(),
409 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
410 loop_.RunUntilIdle();
411 EXPECT_EQ(1U, ack_handle_map.size());
412 it = ack_handle_map.find(kAutofillId_);
413 ASSERT_NE(ack_handle_map.end(), it);
414 EXPECT_TRUE(it->second.IsValid());
415 state_map[kAutofillId_].expected = it->second;
416 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
417
418 storage.Acknowledge(kAutofillId_, it->second);
419 state_map[kAutofillId_].current = it->second;
420 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
421
422 ids.clear();
423
424 // Test that it works as expected if the key already exists.
425 state_map[kBookmarksId_].version = 11;
426 state_map[kBookmarksId_].payload = "hello";
427 storage.SetMaxVersionAndPayload(kBookmarksId_, 11, "hello");
428 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
429 ids.insert(kBookmarksId_);
430 storage.GenerateAckHandles(
431 ids, base::MessageLoopProxy::current(),
432 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
433 loop_.RunUntilIdle();
434 EXPECT_EQ(1U, ack_handle_map.size());
435 it = ack_handle_map.find(kBookmarksId_);
436 ASSERT_NE(ack_handle_map.end(), it);
437 EXPECT_TRUE(it->second.IsValid());
438 state_map[kBookmarksId_].expected = it->second;
439 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
440
441 storage.Acknowledge(kBookmarksId_, it->second);
442 state_map[kBookmarksId_].current = it->second;
443 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
444
445 // Finally, test that the ack handles are updated if we're asked to generate
446 // another ack handle for the same object ID.
447 state_map[kBookmarksId_].version = 12;
448 state_map[kBookmarksId_].payload = "world";
449 storage.SetMaxVersionAndPayload(kBookmarksId_, 12, "world");
450 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
451 ids.insert(kBookmarksId_);
452 storage.GenerateAckHandles(
453 ids, base::MessageLoopProxy::current(),
454 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
455 loop_.RunUntilIdle();
456 EXPECT_EQ(1U, ack_handle_map.size());
457 it = ack_handle_map.find(kBookmarksId_);
458 ASSERT_NE(ack_handle_map.end(), it);
459 EXPECT_TRUE(it->second.IsValid());
460 state_map[kBookmarksId_].expected = it->second;
461 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
462
463 storage.Acknowledge(kBookmarksId_, it->second);
464 state_map[kBookmarksId_].current = it->second;
465 EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
466 }
467
343 } // namespace browser_sync 468 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698