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