OLD | NEW |
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 #include "chrome/browser/invalidation/invalidator_storage.h" | 5 #include "chrome/browser/invalidation/invalidator_storage.h" |
6 | 6 |
7 #include "base/bind.h" | |
8 #include "base/message_loop/message_loop.h" | |
9 #include "base/message_loop/message_loop_proxy.h" | |
10 #include "base/prefs/pref_service.h" | 7 #include "base/prefs/pref_service.h" |
11 #include "base/strings/string_number_conversions.h" | |
12 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
13 #include "chrome/common/pref_names.h" | 9 #include "chrome/common/pref_names.h" |
14 #include "chrome/test/base/testing_pref_service_syncable.h" | 10 #include "chrome/test/base/testing_pref_service_syncable.h" |
15 #include "sync/internal_api/public/base/invalidation_test_util.h" | 11 #include "sync/notifier/unacked_invalidation_set_test_util.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
18 | 13 |
19 using syncer::InvalidationStateMap; | |
20 | |
21 namespace { | |
22 | |
23 const char kSourceKey[] = "source"; | |
24 const char kNameKey[] = "name"; | |
25 const char kMaxVersionKey[] = "max-version"; | |
26 const char kPayloadKey[] = "payload"; | |
27 const char kCurrentAckHandleKey[] = "current-ack"; | |
28 const char kExpectedAckHandleKey[] = "expected-ack"; | |
29 | |
30 const int kChromeSyncSourceId = 1004; | |
31 | |
32 void GenerateAckHandlesTestHelper(syncer::AckHandleMap* output, | |
33 const syncer::AckHandleMap& input) { | |
34 *output = input; | |
35 } | |
36 | |
37 } // namespace | |
38 | |
39 namespace invalidation { | 14 namespace invalidation { |
40 | 15 |
41 class InvalidatorStorageTest : public testing::Test { | 16 class InvalidatorStorageTest : public testing::Test { |
42 public: | 17 public: |
43 InvalidatorStorageTest() | 18 InvalidatorStorageTest() {} |
44 : kBookmarksId_(kChromeSyncSourceId, "BOOKMARK"), | |
45 kPreferencesId_(kChromeSyncSourceId, "PREFERENCE"), | |
46 kAppNotificationsId_(kChromeSyncSourceId, "APP_NOTIFICATION"), | |
47 kAutofillId_(kChromeSyncSourceId, "AUTOFILL") {} | |
48 | 19 |
49 virtual void SetUp() { | 20 virtual void SetUp() { |
50 InvalidatorStorage::RegisterProfilePrefs(pref_service_.registry()); | 21 InvalidatorStorage::RegisterProfilePrefs(pref_service_.registry()); |
51 } | 22 } |
52 | 23 |
53 protected: | 24 protected: |
54 TestingPrefServiceSyncable pref_service_; | 25 TestingPrefServiceSyncable pref_service_; |
55 | |
56 const invalidation::ObjectId kBookmarksId_; | |
57 const invalidation::ObjectId kPreferencesId_; | |
58 const invalidation::ObjectId kAppNotificationsId_; | |
59 const invalidation::ObjectId kAutofillId_; | |
60 | |
61 base::MessageLoop loop_; | |
62 }; | 26 }; |
63 | 27 |
64 // Set invalidation states for various keys and verify that they are written and | |
65 // read back correctly. | |
66 TEST_F(InvalidatorStorageTest, SetMaxVersionAndPayload) { | |
67 InvalidatorStorage storage(&pref_service_); | |
68 | |
69 InvalidationStateMap expected_states; | |
70 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
71 | |
72 expected_states[kBookmarksId_].version = 2; | |
73 expected_states[kBookmarksId_].payload = "hello"; | |
74 storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "hello"); | |
75 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
76 | |
77 expected_states[kPreferencesId_].version = 5; | |
78 storage.SetMaxVersionAndPayload(kPreferencesId_, 5, std::string()); | |
79 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
80 | |
81 expected_states[kAppNotificationsId_].version = 3; | |
82 expected_states[kAppNotificationsId_].payload = "world"; | |
83 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 3, "world"); | |
84 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
85 | |
86 expected_states[kAppNotificationsId_].version = 4; | |
87 expected_states[kAppNotificationsId_].payload = "again"; | |
88 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 4, "again"); | |
89 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
90 } | |
91 | |
92 // Forgetting an entry should cause that entry to be deleted. | |
93 TEST_F(InvalidatorStorageTest, Forget) { | |
94 InvalidatorStorage storage(&pref_service_); | |
95 EXPECT_TRUE(storage.GetAllInvalidationStates().empty()); | |
96 | |
97 InvalidationStateMap expected_states; | |
98 expected_states[kBookmarksId_].version = 2; | |
99 expected_states[kBookmarksId_].payload = "a"; | |
100 expected_states[kPreferencesId_].version = 5; | |
101 expected_states[kPreferencesId_].payload = "b"; | |
102 storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "a"); | |
103 storage.SetMaxVersionAndPayload(kPreferencesId_, 5, "b"); | |
104 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
105 | |
106 expected_states.erase(kPreferencesId_); | |
107 syncer::ObjectIdSet to_forget; | |
108 to_forget.insert(kPreferencesId_); | |
109 storage.Forget(to_forget); | |
110 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
111 } | |
112 | |
113 // Clearing the storage should erase all version map entries, bootstrap data, | 28 // Clearing the storage should erase all version map entries, bootstrap data, |
114 // and the client ID. | 29 // and the client ID. |
115 TEST_F(InvalidatorStorageTest, Clear) { | 30 TEST_F(InvalidatorStorageTest, Clear) { |
116 InvalidatorStorage storage(&pref_service_); | 31 InvalidatorStorage storage(&pref_service_); |
117 EXPECT_TRUE(storage.GetAllInvalidationStates().empty()); | |
118 EXPECT_TRUE(storage.GetBootstrapData().empty()); | 32 EXPECT_TRUE(storage.GetBootstrapData().empty()); |
119 EXPECT_TRUE(storage.GetInvalidatorClientId().empty()); | 33 EXPECT_TRUE(storage.GetInvalidatorClientId().empty()); |
120 | 34 |
121 storage.SetInvalidatorClientId("fake_id"); | 35 storage.SetInvalidatorClientId("fake_id"); |
122 EXPECT_EQ("fake_id", storage.GetInvalidatorClientId()); | 36 EXPECT_EQ("fake_id", storage.GetInvalidatorClientId()); |
123 | 37 |
124 storage.SetBootstrapData("test"); | 38 storage.SetBootstrapData("test"); |
125 EXPECT_EQ("test", storage.GetBootstrapData()); | 39 EXPECT_EQ("test", storage.GetBootstrapData()); |
126 | 40 |
127 { | |
128 InvalidationStateMap expected_states; | |
129 expected_states[kAppNotificationsId_].version = 3; | |
130 storage.SetMaxVersionAndPayload(kAppNotificationsId_, 3, std::string()); | |
131 EXPECT_EQ(expected_states, storage.GetAllInvalidationStates()); | |
132 } | |
133 | |
134 storage.Clear(); | 41 storage.Clear(); |
135 | 42 |
136 EXPECT_TRUE(storage.GetAllInvalidationStates().empty()); | |
137 EXPECT_TRUE(storage.GetBootstrapData().empty()); | 43 EXPECT_TRUE(storage.GetBootstrapData().empty()); |
138 EXPECT_TRUE(storage.GetInvalidatorClientId().empty()); | 44 EXPECT_TRUE(storage.GetInvalidatorClientId().empty()); |
139 } | 45 } |
140 | 46 |
141 TEST_F(InvalidatorStorageTest, SerializeEmptyMap) { | |
142 InvalidationStateMap empty_map; | |
143 base::ListValue list; | |
144 InvalidatorStorage::SerializeToList(empty_map, &list); | |
145 EXPECT_TRUE(list.empty()); | |
146 } | |
147 | |
148 // Make sure we don't choke on a variety of malformed input. | |
149 TEST_F(InvalidatorStorageTest, DeserializeFromListInvalidFormat) { | |
150 InvalidationStateMap map; | |
151 base::ListValue list_with_invalid_format; | |
152 DictionaryValue* value; | |
153 | |
154 // The various cases below use distinct values to make it easier to track down | |
155 // failures. | |
156 value = new DictionaryValue(); | |
157 list_with_invalid_format.Append(value); | |
158 | |
159 value = new DictionaryValue(); | |
160 value->SetString("completely", "invalid"); | |
161 list_with_invalid_format.Append(value); | |
162 | |
163 // Missing two required fields | |
164 value = new DictionaryValue(); | |
165 value->SetString(kSourceKey, "10"); | |
166 list_with_invalid_format.Append(value); | |
167 | |
168 value = new DictionaryValue(); | |
169 value->SetString(kNameKey, "missing source and version"); | |
170 list_with_invalid_format.Append(value); | |
171 | |
172 value = new DictionaryValue(); | |
173 value->SetString(kMaxVersionKey, "3"); | |
174 list_with_invalid_format.Append(value); | |
175 | |
176 // Missing one required field | |
177 value = new DictionaryValue(); | |
178 value->SetString(kSourceKey, "14"); | |
179 value->SetString(kNameKey, "missing version"); | |
180 list_with_invalid_format.Append(value); | |
181 | |
182 value = new DictionaryValue(); | |
183 value->SetString(kSourceKey, "233"); | |
184 value->SetString(kMaxVersionKey, "5"); | |
185 list_with_invalid_format.Append(value); | |
186 | |
187 value = new DictionaryValue(); | |
188 value->SetString(kNameKey, "missing source"); | |
189 value->SetString(kMaxVersionKey, "25"); | |
190 list_with_invalid_format.Append(value); | |
191 | |
192 // Invalid values in fields | |
193 value = new DictionaryValue(); | |
194 value->SetString(kSourceKey, "a"); | |
195 value->SetString(kNameKey, "bad source"); | |
196 value->SetString(kMaxVersionKey, "12"); | |
197 list_with_invalid_format.Append(value); | |
198 | |
199 value = new DictionaryValue(); | |
200 value->SetString(kSourceKey, "1"); | |
201 value->SetString(kNameKey, "bad max version"); | |
202 value->SetString(kMaxVersionKey, "a"); | |
203 list_with_invalid_format.Append(value); | |
204 | |
205 // And finally something that should work. | |
206 invalidation::ObjectId valid_id(42, "this should work"); | |
207 value = new DictionaryValue(); | |
208 value->SetString(kSourceKey, "42"); | |
209 value->SetString(kNameKey, valid_id.name()); | |
210 value->SetString(kMaxVersionKey, "20"); | |
211 list_with_invalid_format.Append(value); | |
212 | |
213 InvalidatorStorage::DeserializeFromList(list_with_invalid_format, &map); | |
214 | |
215 EXPECT_EQ(1U, map.size()); | |
216 EXPECT_EQ(20, map[valid_id].version); | |
217 } | |
218 | |
219 // Tests behavior when there are duplicate entries for a single key. The value | |
220 // of the last entry with that key should be used in the version map. | |
221 TEST_F(InvalidatorStorageTest, DeserializeFromListWithDuplicates) { | |
222 InvalidationStateMap map; | |
223 base::ListValue list; | |
224 DictionaryValue* value; | |
225 | |
226 value = new DictionaryValue(); | |
227 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source())); | |
228 value->SetString(kNameKey, kBookmarksId_.name()); | |
229 value->SetString(kMaxVersionKey, "20"); | |
230 list.Append(value); | |
231 value = new DictionaryValue(); | |
232 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source())); | |
233 value->SetString(kNameKey, kAutofillId_.name()); | |
234 value->SetString(kMaxVersionKey, "10"); | |
235 list.Append(value); | |
236 value = new DictionaryValue(); | |
237 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source())); | |
238 value->SetString(kNameKey, kBookmarksId_.name()); | |
239 value->SetString(kMaxVersionKey, "15"); | |
240 list.Append(value); | |
241 | |
242 InvalidatorStorage::DeserializeFromList(list, &map); | |
243 EXPECT_EQ(2U, map.size()); | |
244 EXPECT_EQ(10, map[kAutofillId_].version); | |
245 EXPECT_EQ(15, map[kBookmarksId_].version); | |
246 } | |
247 | |
248 TEST_F(InvalidatorStorageTest, DeserializeFromEmptyList) { | |
249 InvalidationStateMap map; | |
250 base::ListValue list; | |
251 InvalidatorStorage::DeserializeFromList(list, &map); | |
252 EXPECT_TRUE(map.empty()); | |
253 } | |
254 | |
255 // Tests that deserializing a well-formed value results in the expected state | |
256 // map. | |
257 TEST_F(InvalidatorStorageTest, DeserializeFromListBasic) { | |
258 InvalidationStateMap map; | |
259 base::ListValue list; | |
260 DictionaryValue* value; | |
261 syncer::AckHandle ack_handle_1 = syncer::AckHandle::CreateUnique(); | |
262 syncer::AckHandle ack_handle_2 = syncer::AckHandle::CreateUnique(); | |
263 | |
264 value = new DictionaryValue(); | |
265 value->SetString(kSourceKey, | |
266 base::IntToString(kAppNotificationsId_.source())); | |
267 value->SetString(kNameKey, kAppNotificationsId_.name()); | |
268 value->SetString(kMaxVersionKey, "20"); | |
269 value->SetString(kPayloadKey, "testing"); | |
270 value->Set(kCurrentAckHandleKey, ack_handle_1.ToValue().release()); | |
271 value->Set(kExpectedAckHandleKey, ack_handle_2.ToValue().release()); | |
272 list.Append(value); | |
273 | |
274 InvalidatorStorage::DeserializeFromList(list, &map); | |
275 EXPECT_EQ(1U, map.size()); | |
276 EXPECT_EQ(20, map[kAppNotificationsId_].version); | |
277 EXPECT_EQ("testing", map[kAppNotificationsId_].payload); | |
278 EXPECT_THAT(map[kAppNotificationsId_].current, syncer::Eq(ack_handle_1)); | |
279 EXPECT_THAT(map[kAppNotificationsId_].expected, syncer::Eq(ack_handle_2)); | |
280 } | |
281 | |
282 // Tests that deserializing well-formed values when optional parameters are | |
283 // omitted works. | |
284 TEST_F(InvalidatorStorageTest, DeserializeFromListMissingOptionalValues) { | |
285 InvalidationStateMap map; | |
286 base::ListValue list; | |
287 DictionaryValue* value; | |
288 syncer::AckHandle ack_handle = syncer::AckHandle::CreateUnique(); | |
289 | |
290 // Payload missing because of an upgrade from a previous browser version that | |
291 // didn't set the field. | |
292 value = new DictionaryValue(); | |
293 value->SetString(kSourceKey, base::IntToString(kAutofillId_.source())); | |
294 value->SetString(kNameKey, kAutofillId_.name()); | |
295 value->SetString(kMaxVersionKey, "10"); | |
296 list.Append(value); | |
297 // A crash between SetMaxVersion() and a callback from GenerateAckHandles() | |
298 // could result in this state. | |
299 value = new DictionaryValue(); | |
300 value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source())); | |
301 value->SetString(kNameKey, kBookmarksId_.name()); | |
302 value->SetString(kMaxVersionKey, "15"); | |
303 value->SetString(kPayloadKey, "hello"); | |
304 list.Append(value); | |
305 // Never acknowledged, so current ack handle is unset. | |
306 value = new DictionaryValue(); | |
307 value->SetString(kSourceKey, base::IntToString(kPreferencesId_.source())); | |
308 value->SetString(kNameKey, kPreferencesId_.name()); | |
309 value->SetString(kMaxVersionKey, "20"); | |
310 value->SetString(kPayloadKey, "world"); | |
311 value->Set(kExpectedAckHandleKey, ack_handle.ToValue().release()); | |
312 list.Append(value); | |
313 | |
314 InvalidatorStorage::DeserializeFromList(list, &map); | |
315 EXPECT_EQ(3U, map.size()); | |
316 | |
317 EXPECT_EQ(10, map[kAutofillId_].version); | |
318 EXPECT_EQ("", map[kAutofillId_].payload); | |
319 EXPECT_FALSE(map[kAutofillId_].current.IsValid()); | |
320 EXPECT_FALSE(map[kAutofillId_].expected.IsValid()); | |
321 | |
322 EXPECT_EQ(15, map[kBookmarksId_].version); | |
323 EXPECT_EQ("hello", map[kBookmarksId_].payload); | |
324 EXPECT_FALSE(map[kBookmarksId_].current.IsValid()); | |
325 EXPECT_FALSE(map[kBookmarksId_].expected.IsValid()); | |
326 | |
327 EXPECT_EQ(20, map[kPreferencesId_].version); | |
328 EXPECT_EQ("world", map[kPreferencesId_].payload); | |
329 EXPECT_FALSE(map[kPreferencesId_].current.IsValid()); | |
330 EXPECT_THAT(map[kPreferencesId_].expected, Eq(ack_handle)); | |
331 } | |
332 | |
333 // Tests for legacy deserialization code. | |
334 TEST_F(InvalidatorStorageTest, DeserializeMapOutOfRange) { | |
335 InvalidationStateMap map; | |
336 base::DictionaryValue dict_with_out_of_range_type; | |
337 | |
338 dict_with_out_of_range_type.SetString( | |
339 base::IntToString(syncer::TOP_LEVEL_FOLDER), "100"); | |
340 dict_with_out_of_range_type.SetString( | |
341 base::IntToString(syncer::BOOKMARKS), "5"); | |
342 | |
343 InvalidatorStorage::DeserializeMap(&dict_with_out_of_range_type, &map); | |
344 | |
345 EXPECT_EQ(1U, map.size()); | |
346 EXPECT_EQ(5, map[kBookmarksId_].version); | |
347 } | |
348 | |
349 TEST_F(InvalidatorStorageTest, DeserializeMapInvalidFormat) { | |
350 InvalidationStateMap map; | |
351 base::DictionaryValue dict_with_invalid_format; | |
352 | |
353 dict_with_invalid_format.SetString("whoops", "5"); | |
354 dict_with_invalid_format.SetString("ohnoes", "whoops"); | |
355 dict_with_invalid_format.SetString( | |
356 base::IntToString(syncer::BOOKMARKS), "ohnoes"); | |
357 dict_with_invalid_format.SetString( | |
358 base::IntToString(syncer::AUTOFILL), "10"); | |
359 | |
360 InvalidatorStorage::DeserializeMap(&dict_with_invalid_format, &map); | |
361 | |
362 EXPECT_EQ(1U, map.size()); | |
363 EXPECT_EQ(10, map[kAutofillId_].version); | |
364 } | |
365 | |
366 TEST_F(InvalidatorStorageTest, DeserializeMapEmptyDictionary) { | |
367 InvalidationStateMap map; | |
368 base::DictionaryValue dict; | |
369 InvalidatorStorage::DeserializeMap(&dict, &map); | |
370 EXPECT_TRUE(map.empty()); | |
371 } | |
372 | |
373 TEST_F(InvalidatorStorageTest, DeserializeMapBasic) { | |
374 InvalidationStateMap map; | |
375 base::DictionaryValue dict; | |
376 | |
377 dict.SetString(base::IntToString(syncer::AUTOFILL), "10"); | |
378 dict.SetString(base::IntToString(syncer::BOOKMARKS), "15"); | |
379 | |
380 InvalidatorStorage::DeserializeMap(&dict, &map); | |
381 EXPECT_EQ(2U, map.size()); | |
382 EXPECT_EQ(10, map[kAutofillId_].version); | |
383 EXPECT_EQ(15, map[kBookmarksId_].version); | |
384 } | |
385 | |
386 // Test that the migration code for the legacy preference works as expected. | |
387 // Migration should happen on construction of InvalidatorStorage. | |
388 TEST_F(InvalidatorStorageTest, MigrateLegacyPreferences) { | |
389 base::DictionaryValue* legacy_dict = new DictionaryValue; | |
390 legacy_dict->SetString(base::IntToString(syncer::AUTOFILL), "10"); | |
391 legacy_dict->SetString(base::IntToString(syncer::BOOKMARKS), "32"); | |
392 legacy_dict->SetString(base::IntToString(syncer::PREFERENCES), "54"); | |
393 pref_service_.SetUserPref(prefs::kSyncMaxInvalidationVersions, legacy_dict); | |
394 InvalidatorStorage storage(&pref_service_); | |
395 | |
396 // Legacy pref should be cleared. | |
397 const base::DictionaryValue* dict = | |
398 pref_service_.GetDictionary(prefs::kSyncMaxInvalidationVersions); | |
399 EXPECT_TRUE(dict->empty()); | |
400 | |
401 // Validate the new pref is set correctly. | |
402 InvalidationStateMap map; | |
403 const base::ListValue* list = | |
404 pref_service_.GetList(prefs::kInvalidatorMaxInvalidationVersions); | |
405 InvalidatorStorage::DeserializeFromList(*list, &map); | |
406 | |
407 EXPECT_EQ(3U, map.size()); | |
408 EXPECT_EQ(10, map[kAutofillId_].version); | |
409 EXPECT_EQ(32, map[kBookmarksId_].version); | |
410 EXPECT_EQ(54, map[kPreferencesId_].version); | |
411 } | |
412 | |
413 TEST_F(InvalidatorStorageTest, SetGetNotifierClientId) { | 47 TEST_F(InvalidatorStorageTest, SetGetNotifierClientId) { |
414 InvalidatorStorage storage(&pref_service_); | 48 InvalidatorStorage storage(&pref_service_); |
415 const std::string client_id("fK6eDzAIuKqx9A4+93bljg=="); | 49 const std::string client_id("fK6eDzAIuKqx9A4+93bljg=="); |
416 | 50 |
417 storage.SetInvalidatorClientId(client_id); | 51 storage.SetInvalidatorClientId(client_id); |
418 EXPECT_EQ(client_id, storage.GetInvalidatorClientId()); | 52 EXPECT_EQ(client_id, storage.GetInvalidatorClientId()); |
419 } | 53 } |
420 | 54 |
421 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) { | 55 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) { |
422 InvalidatorStorage storage(&pref_service_); | 56 InvalidatorStorage storage(&pref_service_); |
423 const std::string mess("n\0tK\0\0l\344", 8); | 57 const std::string mess("n\0tK\0\0l\344", 8); |
424 ASSERT_FALSE(IsStringUTF8(mess)); | 58 ASSERT_FALSE(IsStringUTF8(mess)); |
425 | 59 |
426 storage.SetBootstrapData(mess); | 60 storage.SetBootstrapData(mess); |
427 EXPECT_EQ(mess, storage.GetBootstrapData()); | 61 EXPECT_EQ(mess, storage.GetBootstrapData()); |
428 } | 62 } |
429 | 63 |
430 // Test that we correctly generate ack handles, acknowledge them, and persist | 64 TEST_F(InvalidatorStorageTest, SaveGetInvalidations_Empty) { |
431 // them. | |
432 TEST_F(InvalidatorStorageTest, GenerateAckHandlesAndAcknowledge) { | |
433 InvalidatorStorage storage(&pref_service_); | 65 InvalidatorStorage storage(&pref_service_); |
434 syncer::ObjectIdSet ids; | 66 syncer::UnackedInvalidationsMap empty_map; |
435 InvalidationStateMap state_map; | 67 ASSERT_TRUE(empty_map.empty()); |
436 syncer::AckHandleMap ack_handle_map; | |
437 syncer::AckHandleMap::const_iterator it; | |
438 | 68 |
439 // Test that it works as expected if the key doesn't already exist in the map, | 69 storage.SetSavedInvalidations(empty_map); |
440 // e.g. the first invalidation received for the object ID was not for a | 70 syncer::UnackedInvalidationsMap restored_map = |
441 // specific version. | 71 storage.GetSavedInvalidations(); |
442 ids.insert(kAutofillId_); | 72 EXPECT_TRUE(restored_map.empty()); |
443 storage.GenerateAckHandles( | 73 } |
444 ids, base::MessageLoopProxy::current(), | |
445 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map)); | |
446 loop_.RunUntilIdle(); | |
447 EXPECT_EQ(1U, ack_handle_map.size()); | |
448 it = ack_handle_map.find(kAutofillId_); | |
449 // Android STL appears to be buggy and causes gtest's IsContainerTest<> to | |
450 // treat an iterator as a STL container so we use != instead of ASSERT_NE. | |
451 ASSERT_TRUE(ack_handle_map.end() != it); | |
452 EXPECT_TRUE(it->second.IsValid()); | |
453 state_map[kAutofillId_].expected = it->second; | |
454 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | |
455 | 74 |
456 storage.Acknowledge(kAutofillId_, it->second); | 75 TEST_F(InvalidatorStorageTest, SaveGetInvalidations) { |
457 state_map[kAutofillId_].current = it->second; | 76 InvalidatorStorage storage(&pref_service_); |
458 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | |
459 | 77 |
460 ids.clear(); | 78 ObjectId id1(10, "object1"); |
| 79 syncer::UnackedInvalidationSet storage1(id1); |
| 80 syncer::Invalidation unknown_version_inv = |
| 81 syncer::Invalidation::InitUnknownVersion(id1); |
| 82 syncer::Invalidation known_version_inv = |
| 83 syncer::Invalidation::Init(id1, 314, "payload"); |
| 84 storage1.Add(unknown_version_inv); |
| 85 storage1.Add(known_version_inv); |
461 | 86 |
462 // Test that it works as expected if the key already exists. | 87 ObjectId id2(10, "object2"); |
463 state_map[kBookmarksId_].version = 11; | 88 syncer::UnackedInvalidationSet storage2(id2); |
464 state_map[kBookmarksId_].payload = "hello"; | 89 syncer::Invalidation obj2_inv = |
465 storage.SetMaxVersionAndPayload(kBookmarksId_, 11, "hello"); | 90 syncer::Invalidation::Init(id2, 1234, "payl\0ad\xff"); |
466 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | 91 storage2.Add(obj2_inv); |
467 ids.insert(kBookmarksId_); | |
468 storage.GenerateAckHandles( | |
469 ids, base::MessageLoopProxy::current(), | |
470 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map)); | |
471 loop_.RunUntilIdle(); | |
472 EXPECT_EQ(1U, ack_handle_map.size()); | |
473 it = ack_handle_map.find(kBookmarksId_); | |
474 ASSERT_TRUE(ack_handle_map.end() != it); | |
475 EXPECT_TRUE(it->second.IsValid()); | |
476 state_map[kBookmarksId_].expected = it->second; | |
477 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | |
478 | 92 |
479 storage.Acknowledge(kBookmarksId_, it->second); | 93 syncer::UnackedInvalidationsMap map; |
480 state_map[kBookmarksId_].current = it->second; | 94 map.insert(std::make_pair(storage1.object_id(), storage1)); |
481 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | 95 map.insert(std::make_pair(storage2.object_id(), storage2)); |
482 | 96 |
483 // Finally, test that the ack handles are updated if we're asked to generate | 97 storage.SetSavedInvalidations(map); |
484 // another ack handle for the same object ID. | 98 syncer::UnackedInvalidationsMap restored_map = |
485 state_map[kBookmarksId_].version = 12; | 99 storage.GetSavedInvalidations(); |
486 state_map[kBookmarksId_].payload = "world"; | |
487 storage.SetMaxVersionAndPayload(kBookmarksId_, 12, "world"); | |
488 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | |
489 ids.insert(kBookmarksId_); | |
490 storage.GenerateAckHandles( | |
491 ids, base::MessageLoopProxy::current(), | |
492 base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map)); | |
493 loop_.RunUntilIdle(); | |
494 EXPECT_EQ(1U, ack_handle_map.size()); | |
495 it = ack_handle_map.find(kBookmarksId_); | |
496 ASSERT_TRUE(ack_handle_map.end() != it); | |
497 EXPECT_TRUE(it->second.IsValid()); | |
498 state_map[kBookmarksId_].expected = it->second; | |
499 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | |
500 | 100 |
501 storage.Acknowledge(kBookmarksId_, it->second); | 101 EXPECT_THAT(map, syncer::test_util::Eq(restored_map)); |
502 state_map[kBookmarksId_].current = it->second; | |
503 EXPECT_EQ(state_map, storage.GetAllInvalidationStates()); | |
504 } | 102 } |
505 | 103 |
506 } // namespace invalidation | 104 } // namespace invalidation |
OLD | NEW |