| 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
|
|
|