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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sync/invalidations/invalidator_storage_unittest.cc
diff --git a/chrome/browser/sync/invalidations/invalidator_storage_unittest.cc b/chrome/browser/sync/invalidations/invalidator_storage_unittest.cc
index 850c574052c31f500237126e1024977f67722f11..8beb9a50276b33e71b8742a3046697b6eca789e7 100644
--- a/chrome/browser/sync/invalidations/invalidator_storage_unittest.cc
+++ b/chrome/browser/sync/invalidations/invalidator_storage_unittest.cc
@@ -5,11 +5,14 @@
#include "chrome/browser/sync/invalidations/invalidator_storage.h"
+#include "base/bind.h"
#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_pref_service.h"
+#include "sync/internal_api/public/base/invalidation_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -22,9 +25,17 @@ namespace {
const char kSourceKey[] = "source";
const char kNameKey[] = "name";
const char kMaxVersionKey[] = "max-version";
+const char kPayloadKey[] = "payload";
+const char kCurrentAckHandleKey[] = "current-ack";
+const char kExpectedAckHandleKey[] = "expected-ack";
const int kChromeSyncSourceId = 1004;
+void GenerateAckHandlesTestHelper(syncer::AckHandleMap* output,
+ const syncer::AckHandleMap& input) {
+ *output = input;
+}
+
} // namespace
class InvalidatorStorageTest : public testing::Test {
@@ -43,33 +54,35 @@ class InvalidatorStorageTest : public testing::Test {
const invalidation::ObjectId kAppNotificationsId_;
const invalidation::ObjectId kAutofillId_;
- private:
MessageLoop loop_;
};
-// Set max versions for various keys and verify that they are written and read
-// back correctly.
-TEST_F(InvalidatorStorageTest, MaxInvalidationVersions) {
+// Set invalidation states for various keys and verify that they are written and
+// read back correctly.
+TEST_F(InvalidatorStorageTest, SetMaxVersionAndPayload) {
InvalidatorStorage storage(&pref_service_);
- InvalidationStateMap expected_max_versions;
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ InvalidationStateMap expected_states;
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
- expected_max_versions[kBookmarksId_].version = 2;
- storage.SetMaxVersion(kBookmarksId_, 2);
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ expected_states[kBookmarksId_].version = 2;
+ expected_states[kBookmarksId_].payload = "hello";
+ storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "hello");
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
- expected_max_versions[kPreferencesId_].version = 5;
- storage.SetMaxVersion(kPreferencesId_, 5);
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ expected_states[kPreferencesId_].version = 5;
+ storage.SetMaxVersionAndPayload(kPreferencesId_, 5, std::string());
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
- expected_max_versions[kAppNotificationsId_].version = 3;
- storage.SetMaxVersion(kAppNotificationsId_, 3);
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ expected_states[kAppNotificationsId_].version = 3;
+ expected_states[kAppNotificationsId_].payload = "world";
+ storage.SetMaxVersionAndPayload(kAppNotificationsId_, 3, "world");
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
- expected_max_versions[kAppNotificationsId_].version = 4;
- storage.SetMaxVersion(kAppNotificationsId_, 4);
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ expected_states[kAppNotificationsId_].version = 4;
+ expected_states[kAppNotificationsId_].payload = "again";
+ storage.SetMaxVersionAndPayload(kAppNotificationsId_, 4, "again");
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
}
// Forgetting an entry should cause that entry to be deleted.
@@ -77,18 +90,20 @@ TEST_F(InvalidatorStorageTest, Forget) {
InvalidatorStorage storage(&pref_service_);
EXPECT_TRUE(storage.GetAllInvalidationStates().empty());
- InvalidationStateMap expected_max_versions;
- expected_max_versions[kBookmarksId_].version = 2;
- expected_max_versions[kPreferencesId_].version = 5;
- storage.SetMaxVersion(kBookmarksId_, 2);
- storage.SetMaxVersion(kPreferencesId_, 5);
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ InvalidationStateMap expected_states;
+ expected_states[kBookmarksId_].version = 2;
+ expected_states[kBookmarksId_].payload = "a";
+ expected_states[kPreferencesId_].version = 5;
+ expected_states[kPreferencesId_].payload = "b";
+ storage.SetMaxVersionAndPayload(kBookmarksId_, 2, "a");
+ storage.SetMaxVersionAndPayload(kPreferencesId_, 5, "b");
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
- expected_max_versions.erase(kPreferencesId_);
+ expected_states.erase(kPreferencesId_);
syncer::ObjectIdSet to_forget;
to_forget.insert(kPreferencesId_);
storage.Forget(to_forget);
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
}
// Clearing the storage should erase all version map entries and the bootstrap
@@ -101,10 +116,10 @@ TEST_F(InvalidatorStorageTest, Clear) {
storage.SetBootstrapData("test");
EXPECT_EQ("test", storage.GetBootstrapData());
{
- InvalidationStateMap expected_max_versions;
- expected_max_versions[kAppNotificationsId_].version = 3;
- storage.SetMaxVersion(kAppNotificationsId_, 3);
- EXPECT_EQ(expected_max_versions, storage.GetAllInvalidationStates());
+ InvalidationStateMap expected_states;
+ expected_states[kAppNotificationsId_].version = 3;
+ storage.SetMaxVersionAndPayload(kAppNotificationsId_, 3, std::string());
+ EXPECT_EQ(expected_states, storage.GetAllInvalidationStates());
}
storage.Clear();
@@ -227,28 +242,82 @@ TEST_F(InvalidatorStorageTest, DeserializeFromEmptyList) {
EXPECT_TRUE(map.empty());
}
-// Tests that deserializing a well-formed value results in the expected version
+// Tests that deserializing a well-formed value results in the expected state
// map.
TEST_F(InvalidatorStorageTest, DeserializeFromListBasic) {
InvalidationStateMap map;
base::ListValue list;
DictionaryValue* value;
+ syncer::AckHandle ack_handle_1 = syncer::AckHandle::CreateUnique();
+ syncer::AckHandle ack_handle_2 = syncer::AckHandle::CreateUnique();
+
+ value = new DictionaryValue();
+ value->SetString(kSourceKey,
+ base::IntToString(kAppNotificationsId_.source()));
+ value->SetString(kNameKey, kAppNotificationsId_.name());
+ value->SetString(kMaxVersionKey, "20");
+ value->SetString(kPayloadKey, "testing");
+ value->Set(kCurrentAckHandleKey, ack_handle_1.ToValue().release());
+ value->Set(kExpectedAckHandleKey, ack_handle_2.ToValue().release());
+ list.Append(value);
+
+ InvalidatorStorage::DeserializeFromList(list, &map);
+ EXPECT_EQ(1U, map.size());
+ EXPECT_EQ(20, map[kAppNotificationsId_].version);
+ EXPECT_EQ("testing", map[kAppNotificationsId_].payload);
+ EXPECT_THAT(map[kAppNotificationsId_].current, Eq(ack_handle_1));
+ EXPECT_THAT(map[kAppNotificationsId_].expected, Eq(ack_handle_2));
+}
+
+// Tests that deserializing well-formed values when optional parameters are
+// omitted works.
+TEST_F(InvalidatorStorageTest, DeserializeFromListMissingOptionalValues) {
+ InvalidationStateMap map;
+ base::ListValue list;
+ DictionaryValue* value;
+ syncer::AckHandle ack_handle = syncer::AckHandle::CreateUnique();
+ // Payload missing because of an upgrade from a previous browser version that
+ // didn't set the field.
value = new DictionaryValue();
value->SetString(kSourceKey, base::IntToString(kAutofillId_.source()));
value->SetString(kNameKey, kAutofillId_.name());
value->SetString(kMaxVersionKey, "10");
list.Append(value);
+ // A crash between SetMaxVersion() and a callback from GenerateAckHandles()
+ // could result in this state.
value = new DictionaryValue();
value->SetString(kSourceKey, base::IntToString(kBookmarksId_.source()));
value->SetString(kNameKey, kBookmarksId_.name());
value->SetString(kMaxVersionKey, "15");
+ value->SetString(kPayloadKey, "hello");
+ list.Append(value);
+ // Never acknowledged, so current ack handle is unset.
+ value = new DictionaryValue();
+ value->SetString(kSourceKey, base::IntToString(kPreferencesId_.source()));
+ value->SetString(kNameKey, kPreferencesId_.name());
+ value->SetString(kMaxVersionKey, "20");
+ value->SetString(kPayloadKey, "world");
+ value->Set(kExpectedAckHandleKey, ack_handle.ToValue().release());
list.Append(value);
InvalidatorStorage::DeserializeFromList(list, &map);
- EXPECT_EQ(2U, map.size());
+ EXPECT_EQ(3U, map.size());
+
EXPECT_EQ(10, map[kAutofillId_].version);
+ EXPECT_EQ("", map[kAutofillId_].payload);
+ EXPECT_FALSE(map[kAutofillId_].current.IsValid());
+ EXPECT_FALSE(map[kAutofillId_].expected.IsValid());
+
EXPECT_EQ(15, map[kBookmarksId_].version);
+ EXPECT_EQ("hello", map[kBookmarksId_].payload);
+ EXPECT_FALSE(map[kBookmarksId_].current.IsValid());
+ EXPECT_FALSE(map[kBookmarksId_].expected.IsValid());
+
+ EXPECT_EQ(20, map[kPreferencesId_].version);
+ EXPECT_EQ("world", map[kPreferencesId_].payload);
+ EXPECT_FALSE(map[kPreferencesId_].current.IsValid());
+ EXPECT_THAT(map[kPreferencesId_].expected, Eq(ack_handle));
}
// Tests for legacy deserialization code.
@@ -340,4 +409,80 @@ TEST_F(InvalidatorStorageTest, SetGetBootstrapData) {
EXPECT_EQ(mess, storage.GetBootstrapData());
}
+// Test that we correctly generate ack handles, acknowledge them, and persist
+// them.
+TEST_F(InvalidatorStorageTest, GenerateAckHandlesAndAcknowledge) {
+ InvalidatorStorage storage(&pref_service_);
+ syncer::ObjectIdSet ids;
+ InvalidationStateMap state_map;
+ syncer::AckHandleMap ack_handle_map;
+ syncer::AckHandleMap::const_iterator it;
+
+ // Test that it works as expected if the key doesn't already exist in the map,
+ // e.g. the first invalidation received for the object ID was not for a
+ // specific version.
+ ids.insert(kAutofillId_);
+ storage.GenerateAckHandles(
+ ids, base::MessageLoopProxy::current(),
+ base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
+ loop_.RunUntilIdle();
+ EXPECT_EQ(1U, ack_handle_map.size());
+ it = ack_handle_map.find(kAutofillId_);
+ // Android STL appears to be buggy and causes gtest's IsContainerTest<> to
+ // treat an iterator as a STL container so we use != instead of ASSERT_NE.
+ ASSERT_TRUE(ack_handle_map.end() != it);
+ EXPECT_TRUE(it->second.IsValid());
+ state_map[kAutofillId_].expected = it->second;
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+
+ storage.Acknowledge(kAutofillId_, it->second);
+ state_map[kAutofillId_].current = it->second;
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+
+ ids.clear();
+
+ // Test that it works as expected if the key already exists.
+ state_map[kBookmarksId_].version = 11;
+ state_map[kBookmarksId_].payload = "hello";
+ storage.SetMaxVersionAndPayload(kBookmarksId_, 11, "hello");
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+ ids.insert(kBookmarksId_);
+ storage.GenerateAckHandles(
+ ids, base::MessageLoopProxy::current(),
+ base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
+ loop_.RunUntilIdle();
+ EXPECT_EQ(1U, ack_handle_map.size());
+ it = ack_handle_map.find(kBookmarksId_);
+ ASSERT_TRUE(ack_handle_map.end() != it);
+ EXPECT_TRUE(it->second.IsValid());
+ state_map[kBookmarksId_].expected = it->second;
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+
+ storage.Acknowledge(kBookmarksId_, it->second);
+ state_map[kBookmarksId_].current = it->second;
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+
+ // Finally, test that the ack handles are updated if we're asked to generate
+ // another ack handle for the same object ID.
+ state_map[kBookmarksId_].version = 12;
+ state_map[kBookmarksId_].payload = "world";
+ storage.SetMaxVersionAndPayload(kBookmarksId_, 12, "world");
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+ ids.insert(kBookmarksId_);
+ storage.GenerateAckHandles(
+ ids, base::MessageLoopProxy::current(),
+ base::Bind(&GenerateAckHandlesTestHelper, &ack_handle_map));
+ loop_.RunUntilIdle();
+ EXPECT_EQ(1U, ack_handle_map.size());
+ it = ack_handle_map.find(kBookmarksId_);
+ ASSERT_TRUE(ack_handle_map.end() != it);
+ EXPECT_TRUE(it->second.IsValid());
+ state_map[kBookmarksId_].expected = it->second;
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+
+ storage.Acknowledge(kBookmarksId_, it->second);
+ state_map[kBookmarksId_].current = it->second;
+ EXPECT_EQ(state_map, storage.GetAllInvalidationStates());
+}
+
} // namespace browser_sync
« 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