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