Index: components/sync/model_impl/model_type_store_impl_unittest.cc |
diff --git a/components/sync/model_impl/model_type_store_impl_unittest.cc b/components/sync/model_impl/model_type_store_impl_unittest.cc |
index 6d3202ad038aad12b122b93764e8bdbca2b66da2..15ac6a9ae6b6c2e82164e5a27d88168889cf6ca4 100644 |
--- a/components/sync/model_impl/model_type_store_impl_unittest.cc |
+++ b/components/sync/model_impl/model_type_store_impl_unittest.cc |
@@ -9,11 +9,29 @@ |
#include "base/bind.h" |
#include "base/message_loop/message_loop.h" |
#include "base/run_loop.h" |
+#include "components/sync/protocol/entity_metadata.pb.h" |
+#include "components/sync/protocol/model_type_state.pb.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
namespace syncer { |
+namespace { |
+ |
+sync_pb::ModelTypeState CreateModelTypeState(const std::string& value) { |
+ sync_pb::ModelTypeState state; |
+ state.set_encryption_key_name(value); |
+ return state; |
+} |
+ |
+sync_pb::EntityMetadata CreateEntityMetadata(const std::string& value) { |
+ sync_pb::EntityMetadata metadata; |
+ metadata.set_client_tag_hash(value); |
+ return metadata; |
+} |
+ |
+} // namespace |
+ |
class ModelTypeStoreImplTest : public testing::Test { |
public: |
void TearDown() override { |
@@ -50,8 +68,7 @@ class ModelTypeStoreImplTest : public testing::Test { |
static void WriteData(ModelTypeStore* store, |
const std::string& key, |
const std::string& data) { |
- std::unique_ptr<ModelTypeStore::WriteBatch> write_batch = |
- store->CreateWriteBatch(); |
+ auto write_batch = store->CreateWriteBatch(); |
store->WriteData(write_batch.get(), key, data); |
ModelTypeStore::Result result; |
store->CommitWriteBatch(std::move(write_batch), |
@@ -62,10 +79,10 @@ class ModelTypeStoreImplTest : public testing::Test { |
static void WriteMetadata(ModelTypeStore* store, |
const std::string& key, |
- const std::string& metadata) { |
- std::unique_ptr<ModelTypeStore::WriteBatch> write_batch = |
- store->CreateWriteBatch(); |
- store->WriteMetadata(write_batch.get(), key, metadata); |
+ const sync_pb::EntityMetadata& metadata) { |
+ auto write_batch = store->CreateWriteBatch(); |
+ write_batch->GetMetadataChangeList()->UpdateMetadata(key, metadata); |
+ |
ModelTypeStore::Result result; |
store->CommitWriteBatch(std::move(write_batch), |
base::Bind(&CaptureResult, &result)); |
@@ -73,11 +90,11 @@ class ModelTypeStoreImplTest : public testing::Test { |
ASSERT_EQ(ModelTypeStore::Result::SUCCESS, result); |
} |
- static void WriteGlobalMetadata(ModelTypeStore* store, |
- const std::string& metadata) { |
- std::unique_ptr<ModelTypeStore::WriteBatch> write_batch = |
- store->CreateWriteBatch(); |
- store->WriteGlobalMetadata(write_batch.get(), metadata); |
+ static void WriteModelTypeState(ModelTypeStore* store, |
+ const sync_pb::ModelTypeState& state) { |
+ auto write_batch = store->CreateWriteBatch(); |
+ write_batch->GetMetadataChangeList()->UpdateModelTypeState(state); |
+ |
ModelTypeStore::Result result; |
store->CommitWriteBatch(std::move(write_batch), |
base::Bind(&CaptureResult, &result)); |
@@ -87,25 +104,25 @@ class ModelTypeStoreImplTest : public testing::Test { |
void WriteTestData() { |
WriteData(store(), "id1", "data1"); |
- WriteMetadata(store(), "id1", "metadata1"); |
+ WriteMetadata(store(), "id1", CreateEntityMetadata("metadata1")); |
WriteData(store(), "id2", "data2"); |
- WriteGlobalMetadata(store(), "global_metadata"); |
+ WriteModelTypeState(store(), CreateModelTypeState("type_state")); |
} |
static void ReadStoreContents( |
ModelTypeStore* store, |
std::unique_ptr<ModelTypeStore::RecordList>* data_records, |
- std::unique_ptr<ModelTypeStore::RecordList>* metadata_records, |
- std::string* global_metadata) { |
+ std::unique_ptr<MetadataBatch>* metadata_batch) { |
ModelTypeStore::Result result; |
store->ReadAllData( |
- base::Bind(&CaptureResultWithRecords, &result, data_records)); |
+ base::Bind(&CaptureResultAndRecords, &result, data_records)); |
PumpLoop(); |
ASSERT_EQ(ModelTypeStore::Result::SUCCESS, result); |
- store->ReadAllMetadata(base::Bind(&CaptureResutRecordsAndString, &result, |
- metadata_records, global_metadata)); |
+ SyncError sync_error; |
+ store->ReadAllMetadata(base::Bind(&CaptureSyncErrorAndMetadataBatch, |
+ &sync_error, metadata_batch)); |
PumpLoop(); |
- ASSERT_EQ(ModelTypeStore::Result::SUCCESS, result); |
+ ASSERT_FALSE(sync_error.IsSet()); |
} |
// Following functions capture parameters passed to callbacks into variables |
@@ -116,7 +133,7 @@ class ModelTypeStoreImplTest : public testing::Test { |
*dst = result; |
} |
- static void CaptureResultWithRecords( |
+ static void CaptureResultAndRecords( |
ModelTypeStore::Result* dst_result, |
std::unique_ptr<ModelTypeStore::RecordList>* dst_records, |
ModelTypeStore::Result result, |
@@ -125,19 +142,16 @@ class ModelTypeStoreImplTest : public testing::Test { |
*dst_records = std::move(records); |
} |
- static void CaptureResutRecordsAndString( |
- ModelTypeStore::Result* dst_result, |
- std::unique_ptr<ModelTypeStore::RecordList>* dst_records, |
- std::string* dst_value, |
- ModelTypeStore::Result result, |
- std::unique_ptr<ModelTypeStore::RecordList> records, |
- const std::string& value) { |
- *dst_result = result; |
- *dst_records = std::move(records); |
- *dst_value = value; |
+ static void CaptureSyncErrorAndMetadataBatch( |
+ SyncError* dst_sync_error, |
+ std::unique_ptr<MetadataBatch>* dst_batch, |
+ SyncError sync_error, |
+ std::unique_ptr<MetadataBatch> batch) { |
+ *dst_sync_error = sync_error; |
+ *dst_batch = std::move(batch); |
} |
- static void CaptureResutRecordsAndIdList( |
+ static void CaptureResultRecordsAndIdList( |
ModelTypeStore::Result* dst_result, |
std::unique_ptr<ModelTypeStore::RecordList>* dst_records, |
std::unique_ptr<ModelTypeStore::IdList>* dst_id_list, |
@@ -149,6 +163,22 @@ class ModelTypeStoreImplTest : public testing::Test { |
*dst_id_list = std::move(missing_id_list); |
} |
+ void VerifyMetadata( |
+ std::unique_ptr<MetadataBatch> batch, |
+ const sync_pb::ModelTypeState& state, |
+ std::map<std::string, sync_pb::EntityMetadata> expected_metadata) { |
+ EXPECT_EQ(state.SerializeAsString(), |
+ batch->GetModelTypeState().SerializeAsString()); |
+ EntityMetadataMap actual_metadata = batch->TakeAllMetadata(); |
+ for (const auto& kv : expected_metadata) { |
+ auto it = actual_metadata.find(kv.first); |
+ ASSERT_TRUE(it != actual_metadata.end()); |
+ EXPECT_EQ(kv.second.SerializeAsString(), it->second.SerializeAsString()); |
+ actual_metadata.erase(it); |
+ } |
+ EXPECT_EQ(0U, actual_metadata.size()); |
+ } |
+ |
private: |
base::MessageLoop message_loop_; |
std::unique_ptr<ModelTypeStore> store_; |
@@ -175,13 +205,11 @@ TEST_F(ModelTypeStoreImplTest, ReadEmptyStore) { |
CreateStore(); |
std::unique_ptr<ModelTypeStore::RecordList> data_records; |
- std::unique_ptr<ModelTypeStore::RecordList> metadata_records; |
- std::string global_metadata; |
- ReadStoreContents(store(), &data_records, &metadata_records, |
- &global_metadata); |
+ std::unique_ptr<MetadataBatch> metadata_batch; |
+ ReadStoreContents(store(), &data_records, &metadata_batch); |
ASSERT_TRUE(data_records->empty()); |
- ASSERT_TRUE(metadata_records->empty()); |
- ASSERT_TRUE(global_metadata.empty()); |
+ VerifyMetadata(std::move(metadata_batch), sync_pb::ModelTypeState(), |
+ std::map<std::string, sync_pb::EntityMetadata>()); |
} |
// Test that records that are written to store later can be read from it. |
@@ -190,43 +218,86 @@ TEST_F(ModelTypeStoreImplTest, WriteThenRead) { |
WriteTestData(); |
std::unique_ptr<ModelTypeStore::RecordList> data_records; |
- std::unique_ptr<ModelTypeStore::RecordList> metadata_records; |
- std::string global_metadata; |
- ReadStoreContents(store(), &data_records, &metadata_records, |
- &global_metadata); |
+ std::unique_ptr<MetadataBatch> metadata_batch; |
+ ReadStoreContents(store(), &data_records, &metadata_batch); |
ASSERT_THAT(*data_records, |
testing::UnorderedElementsAre(RecordMatches("id1", "data1"), |
RecordMatches("id2", "data2"))); |
- ASSERT_THAT(*metadata_records, |
- testing::ElementsAre(RecordMatches("id1", "metadata1"))); |
- ASSERT_EQ("global_metadata", global_metadata); |
+ VerifyMetadata(std::move(metadata_batch), CreateModelTypeState("type_state"), |
+ {{"id1", CreateEntityMetadata("metadata1")}}); |
} |
-// Test that if global metadata is not set then ReadAllMetadata still succeeds |
+// Test that if ModelTypeState is not set then ReadAllMetadata still succeeds |
// and returns entry metadata records. |
-TEST_F(ModelTypeStoreImplTest, MissingGlobalMetadata) { |
+TEST_F(ModelTypeStoreImplTest, MissingModelTypeState) { |
CreateStore(); |
WriteTestData(); |
ModelTypeStore::Result result; |
- std::unique_ptr<ModelTypeStore::WriteBatch> write_batch = |
- store()->CreateWriteBatch(); |
+ auto write_batch = store()->CreateWriteBatch(); |
store()->DeleteGlobalMetadata(write_batch.get()); |
store()->CommitWriteBatch(std::move(write_batch), |
base::Bind(&CaptureResult, &result)); |
PumpLoop(); |
ASSERT_EQ(ModelTypeStore::Result::SUCCESS, result); |
- std::unique_ptr<ModelTypeStore::RecordList> records; |
- std::string global_metadata; |
- store()->ReadAllMetadata(base::Bind(&CaptureResutRecordsAndString, &result, |
- &records, &global_metadata)); |
+ SyncError error; |
+ std::unique_ptr<MetadataBatch> metadata_batch; |
+ store()->ReadAllMetadata( |
+ base::Bind(&CaptureSyncErrorAndMetadataBatch, &error, &metadata_batch)); |
+ PumpLoop(); |
+ ASSERT_FALSE(error.IsSet()); |
+ VerifyMetadata(std::move(metadata_batch), sync_pb::ModelTypeState(), |
+ {{"id1", CreateEntityMetadata("metadata1")}}); |
+} |
+ |
+// Tests that unparseable metadata results in an error being set. |
+TEST_F(ModelTypeStoreImplTest, CorruptModelTypeState) { |
+ CreateStore(); |
+ WriteTestData(); |
+ |
+ // Write a ModelTypeState that can't be parsed. |
+ ModelTypeStore::Result result; |
+ auto write_batch = store()->CreateWriteBatch(); |
+ store()->WriteGlobalMetadata(write_batch.get(), "unparseable"); |
+ store()->CommitWriteBatch(std::move(write_batch), |
+ base::Bind(&CaptureResult, &result)); |
PumpLoop(); |
ASSERT_EQ(ModelTypeStore::Result::SUCCESS, result); |
- ASSERT_THAT(*records, |
- testing::UnorderedElementsAre(RecordMatches("id1", "metadata1"))); |
- ASSERT_EQ(std::string(), global_metadata); |
+ |
+ SyncError error; |
+ std::unique_ptr<MetadataBatch> metadata_batch; |
+ store()->ReadAllMetadata( |
+ base::Bind(&CaptureSyncErrorAndMetadataBatch, &error, &metadata_batch)); |
+ PumpLoop(); |
+ ASSERT_TRUE(error.IsSet()); |
+ VerifyMetadata(std::move(metadata_batch), sync_pb::ModelTypeState(), |
+ std::map<std::string, sync_pb::EntityMetadata>()); |
+} |
+ |
+// Tests that unparseable metadata results in an error being set. |
+TEST_F(ModelTypeStoreImplTest, CorruptEntityMetadata) { |
+ CreateStore(); |
+ WriteTestData(); |
+ |
+ // Write an EntityMetadata that can't be parsed. |
+ ModelTypeStore::Result result; |
+ auto write_batch = store()->CreateWriteBatch(); |
+ store()->WriteMetadata(write_batch.get(), "id", "unparseable"); |
+ store()->CommitWriteBatch(std::move(write_batch), |
+ base::Bind(&CaptureResult, &result)); |
+ PumpLoop(); |
+ ASSERT_EQ(ModelTypeStore::Result::SUCCESS, result); |
+ |
+ SyncError error; |
+ std::unique_ptr<MetadataBatch> metadata_batch; |
+ store()->ReadAllMetadata( |
+ base::Bind(&CaptureSyncErrorAndMetadataBatch, &error, &metadata_batch)); |
+ PumpLoop(); |
+ ASSERT_TRUE(error.IsSet()); |
+ VerifyMetadata(std::move(metadata_batch), sync_pb::ModelTypeState(), |
+ std::map<std::string, sync_pb::EntityMetadata>()); |
} |
// Test that when reading data records by id, if one of the ids is missing |
@@ -244,7 +315,7 @@ TEST_F(ModelTypeStoreImplTest, ReadMissingDataRecords) { |
std::unique_ptr<ModelTypeStore::RecordList> records; |
std::unique_ptr<ModelTypeStore::IdList> missing_id_list; |
- store()->ReadData(id_list, base::Bind(&CaptureResutRecordsAndIdList, &result, |
+ store()->ReadData(id_list, base::Bind(&CaptureResultRecordsAndIdList, &result, |
&records, &missing_id_list)); |
PumpLoop(); |
ASSERT_EQ(ModelTypeStore::Result::SUCCESS, result); |
@@ -261,35 +332,33 @@ TEST_F(ModelTypeStoreImplTest, TwoStoresWithSharedBackend) { |
CreateStoreCaptureReference(AUTOFILL, &store_1); |
CreateStoreCaptureReference(BOOKMARKS, &store_2); |
+ const sync_pb::EntityMetadata metadata1 = CreateEntityMetadata("metadata1"); |
+ const sync_pb::EntityMetadata metadata2 = CreateEntityMetadata("metadata2"); |
+ const sync_pb::ModelTypeState state1 = CreateModelTypeState("state1"); |
+ const sync_pb::ModelTypeState state2 = CreateModelTypeState("state2"); |
+ |
WriteData(store_1.get(), "key", "data1"); |
- WriteMetadata(store_1.get(), "key", "metadata1"); |
- WriteGlobalMetadata(store_1.get(), "global1"); |
+ WriteMetadata(store_1.get(), "key", metadata1); |
+ WriteModelTypeState(store_1.get(), state1); |
WriteData(store_2.get(), "key", "data2"); |
- WriteMetadata(store_2.get(), "key", "metadata2"); |
- WriteGlobalMetadata(store_2.get(), "global2"); |
+ WriteMetadata(store_2.get(), "key", metadata2); |
+ WriteModelTypeState(store_2.get(), state2); |
std::unique_ptr<ModelTypeStore::RecordList> data_records; |
- std::unique_ptr<ModelTypeStore::RecordList> metadata_records; |
- std::string global_metadata; |
+ std::unique_ptr<MetadataBatch> metadata_batch; |
- ReadStoreContents(store_1.get(), &data_records, &metadata_records, |
- &global_metadata); |
+ ReadStoreContents(store_1.get(), &data_records, &metadata_batch); |
EXPECT_THAT(*data_records, |
testing::ElementsAre(RecordMatches("key", "data1"))); |
- EXPECT_THAT(*metadata_records, |
- testing::ElementsAre(RecordMatches("key", "metadata1"))); |
- EXPECT_EQ("global1", global_metadata); |
+ VerifyMetadata(std::move(metadata_batch), state1, {{"key", metadata1}}); |
- ReadStoreContents(store_2.get(), &data_records, &metadata_records, |
- &global_metadata); |
+ ReadStoreContents(store_2.get(), &data_records, &metadata_batch); |
EXPECT_THAT(*data_records, |
testing::ElementsAre(RecordMatches("key", "data2"))); |
- EXPECT_THAT(*metadata_records, |
- testing::ElementsAre(RecordMatches("key", "metadata2"))); |
- EXPECT_EQ("global2", global_metadata); |
+ VerifyMetadata(std::move(metadata_batch), state2, {{"key", metadata2}}); |
} |
} // namespace syncer |