Chromium Code Reviews| Index: chrome/browser/sync/engine/syncer_unittest.cc |
| diff --git a/chrome/browser/sync/engine/syncer_unittest.cc b/chrome/browser/sync/engine/syncer_unittest.cc |
| index 405bf452efdc1ff94420b1be0cd3be0b7d1a178b..48c759bf56cc8a6c83c46603b97b827490e4d552 100644 |
| --- a/chrome/browser/sync/engine/syncer_unittest.cc |
| +++ b/chrome/browser/sync/engine/syncer_unittest.cc |
| @@ -33,6 +33,7 @@ |
| #include "chrome/browser/sync/engine/syncproto.h" |
| #include "chrome/browser/sync/protocol/sync.pb.h" |
| #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" |
| +#include "chrome/browser/sync/protocol/nigori_specifics.pb.h" |
| #include "chrome/browser/sync/sessions/sync_session_context.h" |
| #include "chrome/browser/sync/syncable/directory_manager.h" |
| #include "chrome/browser/sync/syncable/model_type.h" |
| @@ -42,6 +43,7 @@ |
| #include "chrome/browser/sync/test/engine/test_directory_setter_upper.h" |
| #include "chrome/browser/sync/test/engine/test_id_factory.h" |
| #include "chrome/browser/sync/test/engine/test_syncable_utils.h" |
| +#include "chrome/browser/sync/util/cryptographer.h" |
| #include "chrome/browser/sync/util/time.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -197,6 +199,7 @@ class SyncerTest : public testing::Test, |
| mock_server_.reset( |
| new MockConnectionManager(syncdb_.manager(), syncdb_.name())); |
| EnableDatatype(syncable::BOOKMARKS); |
| + EnableDatatype(syncable::NIGORI); |
| worker_ = new FakeModelWorker(GROUP_PASSIVE); |
| std::vector<SyncEngineEventListener*> listeners; |
| listeners.push_back(this); |
| @@ -745,6 +748,129 @@ TEST_F(SyncerTest, GetCommitIdsFiltersUnreadyEntries) { |
| } |
| } |
| +TEST_F(SyncerTest, NigoriConflicts) { |
| + ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| + ASSERT_TRUE(dir.good()); |
| + KeyParams local_key_params = {"localhost", "dummy", "blargle"}; |
| + KeyParams other_key_params = {"localhost", "dummy", "foobar"}; |
| + browser_sync::Cryptographer other_cryptographer; |
| + other_cryptographer.AddKey(other_key_params); |
| + syncable::ModelTypeSet encrypted_types(syncable::PASSWORDS, syncable::NIGORI); |
| + sync_pb::EntitySpecifics initial_nigori_specifics; |
| + initial_nigori_specifics.MutableExtension(sync_pb::nigori); |
| + mock_server_->SetNigori(1, 10, 10, initial_nigori_specifics); |
| + |
| + // Data for testing encryption/decryption. |
| + sync_pb::EntitySpecifics other_encrypted_specifics; |
| + other_encrypted_specifics.MutableExtension(sync_pb::bookmark)-> |
| + set_title("title"); |
| + other_cryptographer.Encrypt( |
| + other_encrypted_specifics, |
| + other_encrypted_specifics.mutable_encrypted()); |
| + sync_pb::EntitySpecifics our_encrypted_specifics; |
| + our_encrypted_specifics.MutableExtension(sync_pb::bookmark)-> |
| + set_title("title2"); |
| + |
| + // Receive the initial nigori node. |
| + SyncShareAsDelegate(); |
| + encrypted_types = syncable::ModelTypeSet::All(); |
| + { |
| + // Local changes with different passphrase and different types. |
| + WriteTransaction wtrans(FROM_HERE, UNITTEST, dir); |
| + sync_pb::EntitySpecifics specifics; |
| + sync_pb::NigoriSpecifics* nigori = |
| + specifics.MutableExtension(sync_pb::nigori); |
| + syncdb_.manager()->GetCryptographer(&wtrans)->AddKey(local_key_params); |
| + syncdb_.manager()->GetCryptographer(&wtrans)->Encrypt( |
| + our_encrypted_specifics, |
| + our_encrypted_specifics.mutable_encrypted()); |
| + syncdb_.manager()->GetCryptographer(&wtrans)->GetKeys( |
| + nigori->mutable_encrypted()); |
| + syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + UpdateNigoriFromEncryptedTypes(nigori); |
| + syncdb_.manager()->GetCryptographer(&wtrans)->set_encrypt_everything(); |
| + MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG, |
| + syncable::ModelTypeToRootTag(syncable::NIGORI)); |
| + ASSERT_TRUE(nigori_entry.good()); |
| + nigori_entry.Put(SPECIFICS, specifics); |
| + nigori_entry.Put(IS_UNSYNCED, true); |
| + EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + has_pending_keys()); |
| + EXPECT_TRUE(encrypted_types.Equals( |
| + syncdb_.manager()->GetCryptographer(&wtrans)->GetEncryptedTypes())); |
| + } |
| + { |
| + sync_pb::EntitySpecifics specifics; |
| + sync_pb::NigoriSpecifics* nigori = |
| + specifics.MutableExtension(sync_pb::nigori); |
| + other_cryptographer.GetKeys(nigori->mutable_encrypted()); |
| + nigori->set_encrypt_bookmarks(true); |
| + nigori->set_encrypt_preferences(true); |
| + nigori->set_encrypt_everything(false); |
| + mock_server_->SetNigori(1, 20, 20, specifics); |
| + } |
| + |
| + // Will result in downloading the server nigori, which puts the local nigori |
| + // in a state of conflict. This is resolved by merging the local and server |
| + // data (with priority given to the server's encryption keys if they are |
| + // undecryptable), which we then commit. The cryptographer should have pending |
| + // keys and merge the set of encrypted types. |
| + SyncShareAsDelegate(); // Resolve conflict in this cycle. |
| + SyncShareAsDelegate(); // Commit local change in this cycle. |
| + { |
| + // Ensure set of encrypted types merged. |
| + WriteTransaction wtrans(FROM_HERE, UNITTEST, dir); |
| + EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + has_pending_keys()); |
| + EXPECT_TRUE(encrypted_types.Equals( |
| + syncdb_.manager()->GetCryptographer(&wtrans)->GetEncryptedTypes())); |
| + EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + encrypt_everything()); |
| + // Supply the pending keys. Afterwards, we should be able to decrypt both |
| + // our own encrypted data and data encrypted by the other cryptographer, |
| + // but the key provided by the other cryptographer should be the default. |
| + EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + DecryptPendingKeys(other_key_params)); |
| + EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + has_pending_keys()); |
| + sync_pb::EntitySpecifics specifics; |
| + sync_pb::NigoriSpecifics* nigori = |
| + specifics.MutableExtension(sync_pb::nigori); |
| + syncdb_.manager()->GetCryptographer(&wtrans)->GetKeys( |
| + nigori->mutable_encrypted()); |
| + syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + UpdateNigoriFromEncryptedTypes(nigori); |
| + MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG, |
| + syncable::ModelTypeToRootTag(syncable::NIGORI)); |
| + ASSERT_TRUE(nigori_entry.good()); |
| + EXPECT_FALSE(nigori_entry.Get(IS_UNAPPLIED_UPDATE)); |
| + EXPECT_FALSE(nigori_entry.Get(IS_UNSYNCED)); |
| + // Normally this would be written as part of SetPassphrase, but we do it |
| + // manually for the test. |
| + nigori_entry.Put(SPECIFICS, specifics); |
| + nigori_entry.Put(IS_UNSYNCED, true); |
| + } |
| + |
| + SyncShareAsDelegate(); |
| + { |
| + WriteTransaction wtrans(FROM_HERE, UNITTEST, dir); |
| + MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG, |
| + syncable::ModelTypeToRootTag(syncable::NIGORI)); |
| + ASSERT_TRUE(nigori_entry.good()); |
| + EXPECT_FALSE(nigori_entry.Get(IS_UNAPPLIED_UPDATE)); |
| + EXPECT_FALSE(nigori_entry.Get(IS_UNSYNCED)); |
| + EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->CanDecrypt( |
| + our_encrypted_specifics.encrypted())); |
| + EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + CanDecryptUsingDefaultKey(our_encrypted_specifics.encrypted())); |
| + EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->CanDecrypt( |
| + other_encrypted_specifics.encrypted())); |
| + EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)-> |
| + CanDecryptUsingDefaultKey(other_encrypted_specifics.encrypted())); |
| + } |
| +} |
|
tim (not reviewing)
2011/12/20 17:54:05
I don't see anything for sync_tabs here?
Nicolas Zea
2011/12/20 19:54:10
Done.
|
| + |
| + |
| // TODO(chron): More corner case unit tests around validation. |
| TEST_F(SyncerTest, TestCommitMetahandleIterator) { |
| ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |