Index: sync/syncable/syncable_unittest.cc |
diff --git a/sync/syncable/syncable_unittest.cc b/sync/syncable/syncable_unittest.cc |
deleted file mode 100644 |
index 95d15314fe9e58cd8dc1cfedb7cce7e8635d9280..0000000000000000000000000000000000000000 |
--- a/sync/syncable/syncable_unittest.cc |
+++ /dev/null |
@@ -1,679 +0,0 @@ |
-// Copyright 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include <stdint.h> |
- |
-#include <memory> |
-#include <string> |
- |
-#include "base/compiler_specific.h" |
-#include "base/files/file_path.h" |
-#include "base/files/file_util.h" |
-#include "base/files/scoped_temp_dir.h" |
-#include "base/location.h" |
-#include "base/logging.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/stl_util.h" |
-#include "base/synchronization/condition_variable.h" |
-#include "base/test/values_test_util.h" |
-#include "base/threading/platform_thread.h" |
-#include "base/values.h" |
-#include "build/build_config.h" |
-#include "sync/protocol/bookmark_specifics.pb.h" |
-#include "sync/syncable/directory_backing_store.h" |
-#include "sync/syncable/directory_change_delegate.h" |
-#include "sync/syncable/directory_unittest.h" |
-#include "sync/syncable/in_memory_directory_backing_store.h" |
-#include "sync/syncable/metahandle_set.h" |
-#include "sync/syncable/mutable_entry.h" |
-#include "sync/syncable/on_disk_directory_backing_store.h" |
-#include "sync/syncable/syncable_proto_util.h" |
-#include "sync/syncable/syncable_read_transaction.h" |
-#include "sync/syncable/syncable_util.h" |
-#include "sync/syncable/syncable_write_transaction.h" |
-#include "sync/test/engine/test_id_factory.h" |
-#include "sync/test/engine/test_syncable_utils.h" |
-#include "sync/test/fake_encryptor.h" |
-#include "sync/test/null_directory_change_delegate.h" |
-#include "sync/test/null_transaction_observer.h" |
-#include "sync/util/test_unrecoverable_error_handler.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace syncer { |
-namespace syncable { |
- |
-using base::ExpectDictBooleanValue; |
-using base::ExpectDictStringValue; |
- |
-// An OnDiskDirectoryBackingStore that can be set to always fail SaveChanges. |
-class TestBackingStore : public OnDiskDirectoryBackingStore { |
- public: |
- TestBackingStore(const std::string& dir_name, |
- const base::FilePath& backing_filepath); |
- |
- ~TestBackingStore() override; |
- |
- bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot) override; |
- |
- void StartFailingSaveChanges() { fail_save_changes_ = true; } |
- |
- private: |
- bool fail_save_changes_; |
-}; |
- |
-TestBackingStore::TestBackingStore(const std::string& dir_name, |
- const base::FilePath& backing_filepath) |
- : OnDiskDirectoryBackingStore(dir_name, backing_filepath), |
- fail_save_changes_(false) { |
-} |
- |
-TestBackingStore::~TestBackingStore() { } |
- |
-bool TestBackingStore::SaveChanges( |
- const Directory::SaveChangesSnapshot& snapshot) { |
- if (fail_save_changes_) { |
- return false; |
- } else { |
- return OnDiskDirectoryBackingStore::SaveChanges(snapshot); |
- } |
-} |
- |
-// A directory whose Save() function can be set to always fail. |
-class TestDirectory : public Directory { |
- public: |
- // A factory function used to work around some initialization order issues. |
- static TestDirectory* Create( |
- Encryptor* encryptor, |
- const WeakHandle<UnrecoverableErrorHandler>& handler, |
- const std::string& dir_name, |
- const base::FilePath& backing_filepath); |
- |
- ~TestDirectory() override; |
- |
- void StartFailingSaveChanges() { |
- backing_store_->StartFailingSaveChanges(); |
- } |
- |
- private: |
- TestDirectory(Encryptor* encryptor, |
- const WeakHandle<UnrecoverableErrorHandler>& handler, |
- TestBackingStore* backing_store); |
- |
- TestBackingStore* backing_store_; |
-}; |
- |
-TestDirectory* TestDirectory::Create( |
- Encryptor* encryptor, |
- const WeakHandle<UnrecoverableErrorHandler>& handler, |
- const std::string& dir_name, |
- const base::FilePath& backing_filepath) { |
- TestBackingStore* backing_store = |
- new TestBackingStore(dir_name, backing_filepath); |
- return new TestDirectory(encryptor, handler, backing_store); |
-} |
- |
-TestDirectory::TestDirectory( |
- Encryptor* encryptor, |
- const WeakHandle<UnrecoverableErrorHandler>& handler, |
- TestBackingStore* backing_store) |
- : Directory(backing_store, handler, base::Closure(), NULL, NULL), |
- backing_store_(backing_store) {} |
- |
-TestDirectory::~TestDirectory() { } |
- |
-// crbug.com/144422 |
-#if defined(OS_ANDROID) |
-#define MAYBE_FailInitialWrite DISABLED_FailInitialWrite |
-#else |
-#define MAYBE_FailInitialWrite FailInitialWrite |
-#endif |
-TEST(OnDiskSyncableDirectory, MAYBE_FailInitialWrite) { |
- base::MessageLoop message_loop; |
- FakeEncryptor encryptor; |
- TestUnrecoverableErrorHandler handler; |
- base::ScopedTempDir temp_dir; |
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
- base::FilePath file_path = temp_dir.path().Append( |
- FILE_PATH_LITERAL("Test.sqlite3")); |
- std::string name = "user@x.com"; |
- NullDirectoryChangeDelegate delegate; |
- |
- std::unique_ptr<TestDirectory> test_dir(TestDirectory::Create( |
- &encryptor, MakeWeakHandle(handler.GetWeakPtr()), name, file_path)); |
- |
- test_dir->StartFailingSaveChanges(); |
- ASSERT_EQ(FAILED_INITIAL_WRITE, test_dir->Open(name, &delegate, |
- NullTransactionObserver())); |
-} |
- |
-// A variant of SyncableDirectoryTest that uses a real sqlite database. |
-class OnDiskSyncableDirectoryTest : public SyncableDirectoryTest { |
- protected: |
- // SetUp() is called before each test case is run. |
- // The sqlite3 DB is deleted before each test is run. |
- void SetUp() override { |
- SyncableDirectoryTest::SetUp(); |
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
- file_path_ = temp_dir_.path().Append( |
- FILE_PATH_LITERAL("Test.sqlite3")); |
- base::DeleteFile(file_path_, false); |
- CreateDirectory(); |
- } |
- |
- void TearDown() override { |
- // This also closes file handles. |
- dir()->SaveChanges(); |
- dir().reset(); |
- base::DeleteFile(file_path_, false); |
- SyncableDirectoryTest::TearDown(); |
- } |
- |
- // Creates a new directory. Deletes the old directory, if it exists. |
- void CreateDirectory() { |
- test_directory_ = TestDirectory::Create( |
- encryptor(), |
- MakeWeakHandle(unrecoverable_error_handler()->GetWeakPtr()), |
- kDirectoryName, file_path_); |
- dir().reset(test_directory_); |
- ASSERT_TRUE(dir().get()); |
- ASSERT_EQ(OPENED, |
- dir()->Open(kDirectoryName, |
- directory_change_delegate(), |
- NullTransactionObserver())); |
- ASSERT_TRUE(dir()->good()); |
- } |
- |
- void SaveAndReloadDir() { |
- dir()->SaveChanges(); |
- CreateDirectory(); |
- } |
- |
- void StartFailingSaveChanges() { |
- test_directory_->StartFailingSaveChanges(); |
- } |
- |
- TestDirectory* test_directory_; // mirrors std::unique_ptr<Directory> dir_ |
- base::ScopedTempDir temp_dir_; |
- base::FilePath file_path_; |
-}; |
- |
-sync_pb::DataTypeContext BuildContext(ModelType type) { |
- sync_pb::DataTypeContext context; |
- context.set_context("context"); |
- context.set_data_type_id(GetSpecificsFieldNumberFromModelType(type)); |
- return context; |
-} |
- |
-TEST_F(OnDiskSyncableDirectoryTest, TestPurgeEntriesWithTypeIn) { |
- sync_pb::EntitySpecifics bookmark_specs; |
- sync_pb::EntitySpecifics autofill_specs; |
- sync_pb::EntitySpecifics preference_specs; |
- AddDefaultFieldValue(BOOKMARKS, &bookmark_specs); |
- AddDefaultFieldValue(PREFERENCES, &preference_specs); |
- AddDefaultFieldValue(AUTOFILL, &autofill_specs); |
- |
- ModelTypeSet types_to_purge(PREFERENCES, AUTOFILL); |
- |
- dir()->SetDownloadProgress(BOOKMARKS, BuildProgress(BOOKMARKS)); |
- dir()->SetDownloadProgress(PREFERENCES, BuildProgress(PREFERENCES)); |
- dir()->SetDownloadProgress(AUTOFILL, BuildProgress(AUTOFILL)); |
- |
- TestIdFactory id_factory; |
- // Create some items for each type. |
- { |
- WriteTransaction trans(FROM_HERE, UNITTEST, dir().get()); |
- |
- dir()->SetDataTypeContext(&trans, BOOKMARKS, BuildContext(BOOKMARKS)); |
- dir()->SetDataTypeContext(&trans, PREFERENCES, BuildContext(PREFERENCES)); |
- dir()->SetDataTypeContext(&trans, AUTOFILL, BuildContext(AUTOFILL)); |
- |
- // Make it look like these types have completed initial sync. |
- CreateTypeRoot(&trans, dir().get(), BOOKMARKS); |
- CreateTypeRoot(&trans, dir().get(), PREFERENCES); |
- CreateTypeRoot(&trans, dir().get(), AUTOFILL); |
- |
- // Add more nodes for this type. Technically, they should be placed under |
- // the proper type root nodes but the assertions in this test won't notice |
- // if their parent isn't quite right. |
- MutableEntry item1(&trans, CREATE, BOOKMARKS, trans.root_id(), "Item"); |
- ASSERT_TRUE(item1.good()); |
- item1.PutServerSpecifics(bookmark_specs); |
- item1.PutIsUnsynced(true); |
- |
- MutableEntry item2(&trans, CREATE_NEW_UPDATE_ITEM, |
- id_factory.NewServerId()); |
- ASSERT_TRUE(item2.good()); |
- item2.PutServerSpecifics(bookmark_specs); |
- item2.PutIsUnappliedUpdate(true); |
- |
- MutableEntry item3(&trans, CREATE, PREFERENCES, |
- trans.root_id(), "Item"); |
- ASSERT_TRUE(item3.good()); |
- item3.PutSpecifics(preference_specs); |
- item3.PutServerSpecifics(preference_specs); |
- item3.PutIsUnsynced(true); |
- |
- MutableEntry item4(&trans, CREATE_NEW_UPDATE_ITEM, |
- id_factory.NewServerId()); |
- ASSERT_TRUE(item4.good()); |
- item4.PutServerSpecifics(preference_specs); |
- item4.PutIsUnappliedUpdate(true); |
- |
- MutableEntry item5(&trans, CREATE, AUTOFILL, |
- trans.root_id(), "Item"); |
- ASSERT_TRUE(item5.good()); |
- item5.PutSpecifics(autofill_specs); |
- item5.PutServerSpecifics(autofill_specs); |
- item5.PutIsUnsynced(true); |
- |
- MutableEntry item6(&trans, CREATE_NEW_UPDATE_ITEM, |
- id_factory.NewServerId()); |
- ASSERT_TRUE(item6.good()); |
- item6.PutServerSpecifics(autofill_specs); |
- item6.PutIsUnappliedUpdate(true); |
- } |
- |
- dir()->SaveChanges(); |
- { |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- MetahandleSet all_set; |
- GetAllMetaHandles(&trans, &all_set); |
- ASSERT_EQ(10U, all_set.size()); |
- } |
- |
- dir()->PurgeEntriesWithTypeIn(types_to_purge, ModelTypeSet(), ModelTypeSet()); |
- |
- // We first query the in-memory data, and then reload the directory (without |
- // saving) to verify that disk does not still have the data. |
- CheckPurgeEntriesWithTypeInSucceeded(types_to_purge, true); |
- SaveAndReloadDir(); |
- CheckPurgeEntriesWithTypeInSucceeded(types_to_purge, false); |
-} |
- |
-TEST_F(OnDiskSyncableDirectoryTest, TestShareInfo) { |
- dir()->set_store_birthday("Jan 31st"); |
- const char* const bag_of_chips_array = "\0bag of chips"; |
- const std::string bag_of_chips_string = |
- std::string(bag_of_chips_array, sizeof(bag_of_chips_array)); |
- dir()->set_bag_of_chips(bag_of_chips_string); |
- { |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- EXPECT_EQ("Jan 31st", dir()->store_birthday()); |
- EXPECT_EQ(bag_of_chips_string, dir()->bag_of_chips()); |
- } |
- dir()->set_store_birthday("April 10th"); |
- const char* const bag_of_chips2_array = "\0bag of chips2"; |
- const std::string bag_of_chips2_string = |
- std::string(bag_of_chips2_array, sizeof(bag_of_chips2_array)); |
- dir()->set_bag_of_chips(bag_of_chips2_string); |
- dir()->SaveChanges(); |
- { |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- EXPECT_EQ("April 10th", dir()->store_birthday()); |
- EXPECT_EQ(bag_of_chips2_string, dir()->bag_of_chips()); |
- } |
- const char* const bag_of_chips3_array = "\0bag of chips3"; |
- const std::string bag_of_chips3_string = |
- std::string(bag_of_chips3_array, sizeof(bag_of_chips3_array)); |
- dir()->set_bag_of_chips(bag_of_chips3_string); |
- // Restore the directory from disk. Make sure that nothing's changed. |
- SaveAndReloadDir(); |
- { |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- EXPECT_EQ("April 10th", dir()->store_birthday()); |
- EXPECT_EQ(bag_of_chips3_string, dir()->bag_of_chips()); |
- } |
-} |
- |
-TEST_F(OnDiskSyncableDirectoryTest, |
- TestSimpleFieldsPreservedDuringSaveChanges) { |
- Id update_id = TestIdFactory::FromNumber(1); |
- Id create_id; |
- EntryKernel create_pre_save, update_pre_save; |
- EntryKernel create_post_save, update_post_save; |
- std::string create_name = "Create"; |
- |
- { |
- WriteTransaction trans(FROM_HERE, UNITTEST, dir().get()); |
- MutableEntry create( |
- &trans, CREATE, BOOKMARKS, trans.root_id(), create_name); |
- MutableEntry update(&trans, CREATE_NEW_UPDATE_ITEM, update_id); |
- create.PutIsUnsynced(true); |
- update.PutIsUnappliedUpdate(true); |
- sync_pb::EntitySpecifics specifics; |
- specifics.mutable_bookmark()->set_favicon("PNG"); |
- specifics.mutable_bookmark()->set_url("http://nowhere"); |
- create.PutSpecifics(specifics); |
- update.PutServerSpecifics(specifics); |
- create_pre_save = create.GetKernelCopy(); |
- update_pre_save = update.GetKernelCopy(); |
- create_id = create.GetId(); |
- } |
- |
- dir()->SaveChanges(); |
- dir().reset( |
- new Directory(new OnDiskDirectoryBackingStore(kDirectoryName, file_path_), |
- MakeWeakHandle(unrecoverable_error_handler()->GetWeakPtr()), |
- base::Closure(), NULL, NULL)); |
- |
- ASSERT_TRUE(dir().get()); |
- ASSERT_EQ(OPENED, |
- dir()->Open(kDirectoryName, |
- directory_change_delegate(), |
- NullTransactionObserver())); |
- ASSERT_TRUE(dir()->good()); |
- |
- { |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- Entry create(&trans, GET_BY_ID, create_id); |
- EXPECT_EQ(1, CountEntriesWithName(&trans, trans.root_id(), create_name)); |
- Entry update(&trans, GET_BY_ID, update_id); |
- create_post_save = create.GetKernelCopy(); |
- update_post_save = update.GetKernelCopy(); |
- } |
- int i = BEGIN_FIELDS; |
- for ( ; i < INT64_FIELDS_END ; ++i) { |
- EXPECT_EQ( |
- create_pre_save.ref((Int64Field)i) + (i == TRANSACTION_VERSION ? 1 : 0), |
- create_post_save.ref((Int64Field)i)) |
- << "int64_t field #" << i << " changed during save/load"; |
- EXPECT_EQ(update_pre_save.ref((Int64Field)i), |
- update_post_save.ref((Int64Field)i)) |
- << "int64_t field #" << i << " changed during save/load"; |
- } |
- for ( ; i < TIME_FIELDS_END ; ++i) { |
- EXPECT_EQ(create_pre_save.ref((TimeField)i), |
- create_post_save.ref((TimeField)i)) |
- << "time field #" << i << " changed during save/load"; |
- EXPECT_EQ(update_pre_save.ref((TimeField)i), |
- update_post_save.ref((TimeField)i)) |
- << "time field #" << i << " changed during save/load"; |
- } |
- for ( ; i < ID_FIELDS_END ; ++i) { |
- EXPECT_EQ(create_pre_save.ref((IdField)i), |
- create_post_save.ref((IdField)i)) |
- << "id field #" << i << " changed during save/load"; |
- EXPECT_EQ(update_pre_save.ref((IdField)i), |
- update_pre_save.ref((IdField)i)) |
- << "id field #" << i << " changed during save/load"; |
- } |
- for ( ; i < BIT_FIELDS_END ; ++i) { |
- EXPECT_EQ(create_pre_save.ref((BitField)i), |
- create_post_save.ref((BitField)i)) |
- << "Bit field #" << i << " changed during save/load"; |
- EXPECT_EQ(update_pre_save.ref((BitField)i), |
- update_post_save.ref((BitField)i)) |
- << "Bit field #" << i << " changed during save/load"; |
- } |
- for ( ; i < STRING_FIELDS_END ; ++i) { |
- EXPECT_EQ(create_pre_save.ref((StringField)i), |
- create_post_save.ref((StringField)i)) |
- << "String field #" << i << " changed during save/load"; |
- EXPECT_EQ(update_pre_save.ref((StringField)i), |
- update_post_save.ref((StringField)i)) |
- << "String field #" << i << " changed during save/load"; |
- } |
- for ( ; i < PROTO_FIELDS_END; ++i) { |
- EXPECT_EQ(create_pre_save.ref((ProtoField)i).SerializeAsString(), |
- create_post_save.ref((ProtoField)i).SerializeAsString()) |
- << "Blob field #" << i << " changed during save/load"; |
- EXPECT_EQ(update_pre_save.ref((ProtoField)i).SerializeAsString(), |
- update_post_save.ref((ProtoField)i).SerializeAsString()) |
- << "Blob field #" << i << " changed during save/load"; |
- } |
- for ( ; i < UNIQUE_POSITION_FIELDS_END; ++i) { |
- EXPECT_TRUE(create_pre_save.ref((UniquePositionField)i).Equals( |
- create_post_save.ref((UniquePositionField)i))) |
- << "Position field #" << i << " changed during save/load"; |
- EXPECT_TRUE(update_pre_save.ref((UniquePositionField)i).Equals( |
- update_post_save.ref((UniquePositionField)i))) |
- << "Position field #" << i << " changed during save/load"; |
- } |
-} |
- |
-TEST_F(OnDiskSyncableDirectoryTest, TestSaveChangesFailure) { |
- int64_t handle1 = 0; |
- // Set up an item using a regular, saveable directory. |
- { |
- WriteTransaction trans(FROM_HERE, UNITTEST, dir().get()); |
- |
- MutableEntry e1(&trans, CREATE, BOOKMARKS, trans.root_id(), "aguilera"); |
- ASSERT_TRUE(e1.good()); |
- EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); |
- handle1 = e1.GetMetahandle(); |
- e1.PutBaseVersion(1); |
- e1.PutIsDir(true); |
- e1.PutId(TestIdFactory::FromNumber(101)); |
- EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); |
- EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
- } |
- ASSERT_TRUE(dir()->SaveChanges()); |
- |
- // Make sure the item is no longer dirty after saving, |
- // and make a modification. |
- { |
- WriteTransaction trans(FROM_HERE, UNITTEST, dir().get()); |
- |
- MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); |
- ASSERT_TRUE(aguilera.good()); |
- EXPECT_FALSE(aguilera.GetKernelCopy().is_dirty()); |
- EXPECT_EQ(aguilera.GetNonUniqueName(), "aguilera"); |
- aguilera.PutNonUniqueName("overwritten"); |
- EXPECT_TRUE(aguilera.GetKernelCopy().is_dirty()); |
- EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
- } |
- ASSERT_TRUE(dir()->SaveChanges()); |
- |
- // Now do some operations when SaveChanges() will fail. |
- StartFailingSaveChanges(); |
- ASSERT_TRUE(dir()->good()); |
- |
- int64_t handle2 = 0; |
- { |
- WriteTransaction trans(FROM_HERE, UNITTEST, dir().get()); |
- |
- MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); |
- ASSERT_TRUE(aguilera.good()); |
- EXPECT_FALSE(aguilera.GetKernelCopy().is_dirty()); |
- EXPECT_EQ(aguilera.GetNonUniqueName(), "overwritten"); |
- EXPECT_FALSE(aguilera.GetKernelCopy().is_dirty()); |
- EXPECT_FALSE(IsInDirtyMetahandles(handle1)); |
- aguilera.PutNonUniqueName("christina"); |
- EXPECT_TRUE(aguilera.GetKernelCopy().is_dirty()); |
- EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
- |
- // New item. |
- MutableEntry kids_on_block( |
- &trans, CREATE, BOOKMARKS, trans.root_id(), "kids"); |
- ASSERT_TRUE(kids_on_block.good()); |
- handle2 = kids_on_block.GetMetahandle(); |
- kids_on_block.PutBaseVersion(1); |
- kids_on_block.PutIsDir(true); |
- kids_on_block.PutId(TestIdFactory::FromNumber(102)); |
- EXPECT_TRUE(kids_on_block.GetKernelCopy().is_dirty()); |
- EXPECT_TRUE(IsInDirtyMetahandles(handle2)); |
- } |
- |
- // We are using an unsaveable directory, so this can't succeed. However, |
- // the HandleSaveChangesFailure code path should have been triggered. |
- ASSERT_FALSE(dir()->SaveChanges()); |
- |
- // Make sure things were rolled back and the world is as it was before call. |
- { |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- Entry e1(&trans, GET_BY_HANDLE, handle1); |
- ASSERT_TRUE(e1.good()); |
- EntryKernel aguilera = e1.GetKernelCopy(); |
- Entry kids(&trans, GET_BY_HANDLE, handle2); |
- ASSERT_TRUE(kids.good()); |
- EXPECT_TRUE(kids.GetKernelCopy().is_dirty()); |
- EXPECT_TRUE(IsInDirtyMetahandles(handle2)); |
- EXPECT_TRUE(aguilera.is_dirty()); |
- EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
- } |
-} |
- |
-TEST_F(OnDiskSyncableDirectoryTest, TestSaveChangesFailureWithPurge) { |
- int64_t handle1 = 0; |
- // Set up an item and progress marker using a regular, saveable directory. |
- dir()->SetDownloadProgress(BOOKMARKS, BuildProgress(BOOKMARKS)); |
- { |
- WriteTransaction trans(FROM_HERE, UNITTEST, dir().get()); |
- |
- MutableEntry e1(&trans, CREATE, BOOKMARKS, trans.root_id(), "aguilera"); |
- ASSERT_TRUE(e1.good()); |
- EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); |
- handle1 = e1.GetMetahandle(); |
- e1.PutBaseVersion(1); |
- e1.PutIsDir(true); |
- e1.PutId(TestIdFactory::FromNumber(101)); |
- sync_pb::EntitySpecifics bookmark_specs; |
- AddDefaultFieldValue(BOOKMARKS, &bookmark_specs); |
- e1.PutSpecifics(bookmark_specs); |
- e1.PutServerSpecifics(bookmark_specs); |
- e1.PutId(TestIdFactory::FromNumber(101)); |
- EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); |
- EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
- } |
- ASSERT_TRUE(dir()->SaveChanges()); |
- |
- // Now do some operations while SaveChanges() is set to fail. |
- StartFailingSaveChanges(); |
- ASSERT_TRUE(dir()->good()); |
- |
- ModelTypeSet set(BOOKMARKS); |
- dir()->PurgeEntriesWithTypeIn(set, ModelTypeSet(), ModelTypeSet()); |
- EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); |
- ASSERT_FALSE(dir()->SaveChanges()); |
- EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); |
-} |
- |
-class SyncableDirectoryManagement : public testing::Test { |
- public: |
- void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } |
- |
- void TearDown() override {} |
- |
- protected: |
- base::MessageLoop message_loop_; |
- base::ScopedTempDir temp_dir_; |
- FakeEncryptor encryptor_; |
- TestUnrecoverableErrorHandler handler_; |
- NullDirectoryChangeDelegate delegate_; |
-}; |
- |
-TEST_F(SyncableDirectoryManagement, TestFileRelease) { |
- base::FilePath path = |
- temp_dir_.path().Append(Directory::kSyncDatabaseFilename); |
- |
- { |
- Directory dir(new OnDiskDirectoryBackingStore("ScopeTest", path), |
- MakeWeakHandle(handler_.GetWeakPtr()), base::Closure(), NULL, |
- NULL); |
- DirOpenResult result = |
- dir.Open("ScopeTest", &delegate_, NullTransactionObserver()); |
- ASSERT_EQ(result, OPENED); |
- } |
- |
- // Destroying the directory should have released the backing database file. |
- ASSERT_TRUE(base::DeleteFile(path, true)); |
-} |
- |
-class SyncableClientTagTest : public SyncableDirectoryTest { |
- public: |
- static const int kBaseVersion = 1; |
- const char* test_name_; |
- const char* test_tag_; |
- |
- SyncableClientTagTest() : test_name_("test_name"), test_tag_("dietcoke") {} |
- |
- bool CreateWithDefaultTag(Id id, bool deleted) { |
- WriteTransaction wtrans(FROM_HERE, UNITTEST, dir().get()); |
- MutableEntry me(&wtrans, CREATE, PREFERENCES, |
- wtrans.root_id(), test_name_); |
- CHECK(me.good()); |
- me.PutId(id); |
- if (id.ServerKnows()) { |
- me.PutBaseVersion(kBaseVersion); |
- } |
- me.PutIsUnsynced(true); |
- me.PutIsDel(deleted); |
- me.PutIsDir(false); |
- return me.PutUniqueClientTag(test_tag_); |
- } |
- |
- // Verify an entry exists with the default tag. |
- void VerifyTag(Id id, bool deleted) { |
- // Should still be present and valid in the client tag index. |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- Entry me(&trans, GET_BY_CLIENT_TAG, test_tag_); |
- CHECK(me.good()); |
- EXPECT_EQ(me.GetId(), id); |
- EXPECT_EQ(me.GetUniqueClientTag(), test_tag_); |
- EXPECT_EQ(me.GetIsDel(), deleted); |
- |
- // We only sync deleted items that the server knew about. |
- if (me.GetId().ServerKnows() || !me.GetIsDel()) { |
- EXPECT_EQ(me.GetIsUnsynced(), true); |
- } |
- } |
- |
- protected: |
- TestIdFactory factory_; |
-}; |
- |
-TEST_F(SyncableClientTagTest, TestClientTagClear) { |
- Id server_id = factory_.NewServerId(); |
- EXPECT_TRUE(CreateWithDefaultTag(server_id, false)); |
- { |
- WriteTransaction trans(FROM_HERE, UNITTEST, dir().get()); |
- MutableEntry me(&trans, GET_BY_CLIENT_TAG, test_tag_); |
- EXPECT_TRUE(me.good()); |
- me.PutUniqueClientTag(std::string()); |
- } |
- { |
- ReadTransaction trans(FROM_HERE, dir().get()); |
- Entry by_tag(&trans, GET_BY_CLIENT_TAG, test_tag_); |
- EXPECT_FALSE(by_tag.good()); |
- |
- Entry by_id(&trans, GET_BY_ID, server_id); |
- EXPECT_TRUE(by_id.good()); |
- EXPECT_TRUE(by_id.GetUniqueClientTag().empty()); |
- } |
-} |
- |
-TEST_F(SyncableClientTagTest, TestClientTagIndexServerId) { |
- Id server_id = factory_.NewServerId(); |
- EXPECT_TRUE(CreateWithDefaultTag(server_id, false)); |
- VerifyTag(server_id, false); |
-} |
- |
-TEST_F(SyncableClientTagTest, TestClientTagIndexClientId) { |
- Id client_id = factory_.NewLocalId(); |
- EXPECT_TRUE(CreateWithDefaultTag(client_id, false)); |
- VerifyTag(client_id, false); |
-} |
- |
-TEST_F(SyncableClientTagTest, TestDeletedClientTagIndexClientId) { |
- Id client_id = factory_.NewLocalId(); |
- EXPECT_TRUE(CreateWithDefaultTag(client_id, true)); |
- VerifyTag(client_id, true); |
-} |
- |
-TEST_F(SyncableClientTagTest, TestDeletedClientTagIndexServerId) { |
- Id server_id = factory_.NewServerId(); |
- EXPECT_TRUE(CreateWithDefaultTag(server_id, true)); |
- VerifyTag(server_id, true); |
-} |
- |
-TEST_F(SyncableClientTagTest, TestClientTagIndexDuplicateServer) { |
- EXPECT_TRUE(CreateWithDefaultTag(factory_.NewServerId(), true)); |
- EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), true)); |
- EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), false)); |
- EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), false)); |
- EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), true)); |
-} |
- |
-} // namespace syncable |
-} // namespace syncer |