| Index: sync/internal_api/sync_manager_impl_unittest.cc
|
| diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc
|
| index 41b2e2df4b812fe06aa8eac08a32809131e66088..8bab47a49488b875fcbbc8690b4fc5bc766639c8 100644
|
| --- a/sync/internal_api/sync_manager_impl_unittest.cc
|
| +++ b/sync/internal_api/sync_manager_impl_unittest.cc
|
| @@ -69,7 +69,7 @@
|
| #include "sync/test/fake_encryptor.h"
|
| #include "sync/util/cryptographer.h"
|
| #include "sync/util/extensions_activity.h"
|
| -#include "sync/util/test_unrecoverable_error_handler.h"
|
| +#include "sync/util/mock_unrecoverable_error_handler.h"
|
| #include "sync/util/time.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -836,7 +836,8 @@ class SyncManagerTest : public testing::Test,
|
| };
|
|
|
| SyncManagerTest()
|
| - : sync_manager_("Test sync manager") {
|
| + : sync_manager_("Test sync manager"),
|
| + mock_unrecoverable_error_handler_(NULL) {
|
| switches_.encryption_method =
|
| InternalComponentsFactory::ENCRYPTION_KEYSTORE;
|
| }
|
| @@ -886,7 +887,8 @@ class SyncManagerTest : public testing::Test,
|
| args.invalidator_client_id = "fake_invalidator_client_id";
|
| args.internal_components_factory.reset(GetFactory());
|
| args.encryptor = &encryptor_;
|
| - args.unrecoverable_error_handler.reset(new TestUnrecoverableErrorHandler);
|
| + mock_unrecoverable_error_handler_ = new MockUnrecoverableErrorHandler();
|
| + args.unrecoverable_error_handler.reset(mock_unrecoverable_error_handler_);
|
| args.cancelation_signal = &cancelation_signal_;
|
| sync_manager_.Init(&args);
|
|
|
| @@ -1080,6 +1082,12 @@ class SyncManagerTest : public testing::Test,
|
| sync_manager_.GetEncryptionHandler()->GetPassphraseType());
|
| }
|
|
|
| + bool HasUnrecoverableError() {
|
| + if (mock_unrecoverable_error_handler_)
|
| + return mock_unrecoverable_error_handler_->invocation_count() > 0;
|
| + return false;
|
| + }
|
| +
|
| private:
|
| // Needed by |sync_manager_|.
|
| base::MessageLoop message_loop_;
|
| @@ -1099,6 +1107,9 @@ class SyncManagerTest : public testing::Test,
|
| StrictMock<SyncEncryptionHandlerObserverMock> encryption_observer_;
|
| InternalComponentsFactory::Switches switches_;
|
| InternalComponentsFactory::StorageOption storage_used_;
|
| +
|
| + // Not owned (ownership is passed to the SyncManager).
|
| + MockUnrecoverableErrorHandler* mock_unrecoverable_error_handler_;
|
| };
|
|
|
| TEST_F(SyncManagerTest, GetAllNodesForTypeTest) {
|
| @@ -2058,6 +2069,93 @@ TEST_F(SyncManagerTest, UpdatePasswordReencryptEverything) {
|
| EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, client_tag));
|
| }
|
|
|
| +// Test that attempting to start up with corrupted password data triggers
|
| +// an unrecoverable error (rather than crashing).
|
| +TEST_F(SyncManagerTest, ReencryptEverythingWithUnrecoverableErrorPasswords) {
|
| + const char kClientTag[] = "client_tag";
|
| +
|
| + EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION));
|
| + sync_pb::EntitySpecifics entity_specifics;
|
| + {
|
| + // Create a synced bookmark with undecryptable data.
|
| + ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
|
| +
|
| + Cryptographer other_cryptographer(&encryptor_);
|
| + KeyParams fake_params = {"localhost", "dummy", "fake_key"};
|
| + other_cryptographer.AddKey(fake_params);
|
| + sync_pb::PasswordSpecificsData data;
|
| + data.set_password_value("secret");
|
| + other_cryptographer.Encrypt(
|
| + data,
|
| + entity_specifics.mutable_password()->mutable_encrypted());
|
| +
|
| + // Set up the real cryptographer with a different key.
|
| + KeyParams real_params = {"localhost", "username", "real_key"};
|
| + trans.GetCryptographer()->AddKey(real_params);
|
| + }
|
| + MakeServerNode(sync_manager_.GetUserShare(), PASSWORDS, kClientTag,
|
| + syncable::GenerateSyncableHash(PASSWORDS,
|
| + kClientTag),
|
| + entity_specifics);
|
| + EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, kClientTag));
|
| +
|
| + // Force a re-encrypt everything. Should trigger an unrecoverable error due
|
| + // to being unable to decrypt the data that was previously applied.
|
| + testing::Mock::VerifyAndClearExpectations(&encryption_observer_);
|
| + EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
|
| + EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
|
| + EXPECT_CALL(encryption_observer_, OnEncryptedTypesChanged(_, false));
|
| + EXPECT_FALSE(HasUnrecoverableError());
|
| + sync_manager_.GetEncryptionHandler()->Init();
|
| + PumpLoop();
|
| + EXPECT_TRUE(HasUnrecoverableError());
|
| +}
|
| +
|
| +// Test that attempting to start up with corrupted bookmark data triggers
|
| +// an unrecoverable error (rather than crashing).
|
| +TEST_F(SyncManagerTest, ReencryptEverythingWithUnrecoverableErrorBookmarks) {
|
| + const char kClientTag[] = "client_tag";
|
| + EXPECT_CALL(encryption_observer_,
|
| + OnEncryptedTypesChanged(
|
| + HasModelTypes(EncryptableUserTypes()), true));
|
| + EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, FULL_ENCRYPTION));
|
| + sync_pb::EntitySpecifics entity_specifics;
|
| + {
|
| + // Create a synced bookmark with undecryptable data.
|
| + ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
|
| +
|
| + Cryptographer other_cryptographer(&encryptor_);
|
| + KeyParams fake_params = {"localhost", "dummy", "fake_key"};
|
| + other_cryptographer.AddKey(fake_params);
|
| + sync_pb::EntitySpecifics bm_specifics;
|
| + bm_specifics.mutable_bookmark()->set_title("title");
|
| + bm_specifics.mutable_bookmark()->set_url("url");
|
| + sync_pb::EncryptedData encrypted;
|
| + other_cryptographer.Encrypt(bm_specifics, &encrypted);
|
| + entity_specifics.mutable_encrypted()->CopyFrom(encrypted);
|
| +
|
| + // Set up the real cryptographer with a different key.
|
| + KeyParams real_params = {"localhost", "username", "real_key"};
|
| + trans.GetCryptographer()->AddKey(real_params);
|
| + }
|
| + MakeServerNode(sync_manager_.GetUserShare(), BOOKMARKS, kClientTag,
|
| + syncable::GenerateSyncableHash(BOOKMARKS,
|
| + kClientTag),
|
| + entity_specifics);
|
| + EXPECT_FALSE(ResetUnsyncedEntry(BOOKMARKS, kClientTag));
|
| +
|
| + // Force a re-encrypt everything. Should trigger an unrecoverable error due
|
| + // to being unable to decrypt the data that was previously applied.
|
| + testing::Mock::VerifyAndClearExpectations(&encryption_observer_);
|
| + EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
|
| + EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
|
| + EXPECT_CALL(encryption_observer_, OnEncryptedTypesChanged(_, true));
|
| + EXPECT_FALSE(HasUnrecoverableError());
|
| + sync_manager_.GetEncryptionHandler()->Init();
|
| + PumpLoop();
|
| + EXPECT_TRUE(HasUnrecoverableError());
|
| +}
|
| +
|
| // Verify SetTitle(..) doesn't unnecessarily set IS_UNSYNCED for bookmarks
|
| // when we write the same data, but does set it when we write new data.
|
| TEST_F(SyncManagerTest, SetBookmarkTitle) {
|
|
|