Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: chrome/browser/sync/engine/syncer_unittest.cc

Issue 8917031: [Sync] Add nigori node conflict resolution. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase + pass trans/cryptographer directly through Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Syncer unit tests. Unfortunately a lot of these tests 5 // Syncer unit tests. Unfortunately a lot of these tests
6 // are outdated and need to be reworked and updated. 6 // are outdated and need to be reworked and updated.
7 7
8 #include <algorithm> 8 #include <algorithm>
9 #include <limits> 9 #include <limits>
10 #include <list> 10 #include <list>
(...skipping 14 matching lines...) Expand all
25 #include "chrome/browser/sync/engine/model_safe_worker.h" 25 #include "chrome/browser/sync/engine/model_safe_worker.h"
26 #include "chrome/browser/sync/engine/net/server_connection_manager.h" 26 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
27 #include "chrome/browser/sync/engine/process_updates_command.h" 27 #include "chrome/browser/sync/engine/process_updates_command.h"
28 #include "chrome/browser/sync/engine/nigori_util.h" 28 #include "chrome/browser/sync/engine/nigori_util.h"
29 #include "chrome/browser/sync/engine/syncer.h" 29 #include "chrome/browser/sync/engine/syncer.h"
30 #include "chrome/browser/sync/engine/syncer_proto_util.h" 30 #include "chrome/browser/sync/engine/syncer_proto_util.h"
31 #include "chrome/browser/sync/engine/syncer_util.h" 31 #include "chrome/browser/sync/engine/syncer_util.h"
32 #include "chrome/browser/sync/engine/syncproto.h" 32 #include "chrome/browser/sync/engine/syncproto.h"
33 #include "chrome/browser/sync/protocol/sync.pb.h" 33 #include "chrome/browser/sync/protocol/sync.pb.h"
34 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" 34 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
35 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
35 #include "chrome/browser/sync/sessions/sync_session_context.h" 36 #include "chrome/browser/sync/sessions/sync_session_context.h"
36 #include "chrome/browser/sync/syncable/directory_manager.h" 37 #include "chrome/browser/sync/syncable/directory_manager.h"
37 #include "chrome/browser/sync/syncable/model_type.h" 38 #include "chrome/browser/sync/syncable/model_type.h"
38 #include "chrome/browser/sync/syncable/syncable.h" 39 #include "chrome/browser/sync/syncable/syncable.h"
39 #include "chrome/browser/sync/test/engine/fake_model_worker.h" 40 #include "chrome/browser/sync/test/engine/fake_model_worker.h"
40 #include "chrome/browser/sync/test/engine/mock_connection_manager.h" 41 #include "chrome/browser/sync/test/engine/mock_connection_manager.h"
41 #include "chrome/browser/sync/test/engine/test_directory_setter_upper.h" 42 #include "chrome/browser/sync/test/engine/test_directory_setter_upper.h"
42 #include "chrome/browser/sync/test/engine/test_id_factory.h" 43 #include "chrome/browser/sync/test/engine/test_id_factory.h"
43 #include "chrome/browser/sync/test/engine/test_syncable_utils.h" 44 #include "chrome/browser/sync/test/engine/test_syncable_utils.h"
45 #include "chrome/browser/sync/util/cryptographer.h"
44 #include "chrome/browser/sync/util/time.h" 46 #include "chrome/browser/sync/util/time.h"
45 #include "testing/gtest/include/gtest/gtest.h" 47 #include "testing/gtest/include/gtest/gtest.h"
46 48
47 using base::TimeDelta; 49 using base::TimeDelta;
48 50
49 using std::map; 51 using std::map;
50 using std::multimap; 52 using std::multimap;
51 using std::set; 53 using std::set;
52 using std::string; 54 using std::string;
53 55
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 should_loop = SyncShareAsDelegate(); 191 should_loop = SyncShareAsDelegate();
190 } while (should_loop); 192 } while (should_loop);
191 } 193 }
192 194
193 virtual void SetUp() { 195 virtual void SetUp() {
194 syncdb_.SetUp(); 196 syncdb_.SetUp();
195 197
196 mock_server_.reset( 198 mock_server_.reset(
197 new MockConnectionManager(syncdb_.manager(), syncdb_.name())); 199 new MockConnectionManager(syncdb_.manager(), syncdb_.name()));
198 EnableDatatype(syncable::BOOKMARKS); 200 EnableDatatype(syncable::BOOKMARKS);
201 EnableDatatype(syncable::NIGORI);
199 worker_ = new FakeModelWorker(GROUP_PASSIVE); 202 worker_ = new FakeModelWorker(GROUP_PASSIVE);
200 std::vector<SyncEngineEventListener*> listeners; 203 std::vector<SyncEngineEventListener*> listeners;
201 listeners.push_back(this); 204 listeners.push_back(this);
202 context_.reset(new SyncSessionContext(mock_server_.get(), 205 context_.reset(new SyncSessionContext(mock_server_.get(),
203 syncdb_.manager(), this, listeners, NULL)); 206 syncdb_.manager(), this, listeners, NULL));
204 context_->set_account_name(syncdb_.name()); 207 context_->set_account_name(syncdb_.name());
205 ASSERT_FALSE(context_->resolver()); 208 ASSERT_FALSE(context_->resolver());
206 syncer_ = new Syncer(); 209 syncer_ = new Syncer();
207 session_.reset(MakeSession()); 210 session_.reset(MakeSession());
208 211
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 ASSERT_TRUE(entryC.good()); 740 ASSERT_TRUE(entryC.good());
738 EXPECT_FALSE(entryC.Get(IS_UNSYNCED)); 741 EXPECT_FALSE(entryC.Get(IS_UNSYNCED));
739 EXPECT_FALSE(entryC.Get(IS_UNAPPLIED_UPDATE)); 742 EXPECT_FALSE(entryC.Get(IS_UNAPPLIED_UPDATE));
740 Entry entryD(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(4)); 743 Entry entryD(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(4));
741 ASSERT_TRUE(entryD.good()); 744 ASSERT_TRUE(entryD.good());
742 EXPECT_FALSE(entryD.Get(IS_UNSYNCED)); 745 EXPECT_FALSE(entryD.Get(IS_UNSYNCED));
743 EXPECT_FALSE(entryD.Get(IS_UNAPPLIED_UPDATE)); 746 EXPECT_FALSE(entryD.Get(IS_UNAPPLIED_UPDATE));
744 } 747 }
745 } 748 }
746 749
750 TEST_F(SyncerTest, NigoriConflicts) {
751 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
752 ASSERT_TRUE(dir.good());
753 KeyParams local_key_params = {"localhost", "dummy", "blargle"};
754 KeyParams other_key_params = {"localhost", "dummy", "foobar"};
755 browser_sync::Cryptographer other_cryptographer;
756 other_cryptographer.AddKey(other_key_params);
757 syncable::ModelTypeSet encrypted_types(syncable::PASSWORDS, syncable::NIGORI);
758 sync_pb::EntitySpecifics initial_nigori_specifics;
759 initial_nigori_specifics.MutableExtension(sync_pb::nigori);
760 mock_server_->SetNigori(1, 10, 10, initial_nigori_specifics);
761
762 // Data for testing encryption/decryption.
763 sync_pb::EntitySpecifics other_encrypted_specifics;
764 other_encrypted_specifics.MutableExtension(sync_pb::bookmark)->
765 set_title("title");
766 other_cryptographer.Encrypt(
767 other_encrypted_specifics,
768 other_encrypted_specifics.mutable_encrypted());
769 sync_pb::EntitySpecifics our_encrypted_specifics;
770 our_encrypted_specifics.MutableExtension(sync_pb::bookmark)->
771 set_title("title2");
772
773 // Receive the initial nigori node.
774 SyncShareAsDelegate();
775 encrypted_types = syncable::ModelTypeSet::All();
776 {
777 // Local changes with different passphrase, different types, and sync_tabs.
778 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
779 sync_pb::EntitySpecifics specifics;
780 sync_pb::NigoriSpecifics* nigori =
781 specifics.MutableExtension(sync_pb::nigori);
782 syncdb_.manager()->GetCryptographer(&wtrans)->AddKey(local_key_params);
783 syncdb_.manager()->GetCryptographer(&wtrans)->Encrypt(
784 our_encrypted_specifics,
785 our_encrypted_specifics.mutable_encrypted());
786 syncdb_.manager()->GetCryptographer(&wtrans)->GetKeys(
787 nigori->mutable_encrypted());
788 syncdb_.manager()->GetCryptographer(&wtrans)->
789 UpdateNigoriFromEncryptedTypes(nigori);
790 nigori->set_sync_tabs(true);
791 syncdb_.manager()->GetCryptographer(&wtrans)->set_encrypt_everything();
792 MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG,
793 syncable::ModelTypeToRootTag(syncable::NIGORI));
794 ASSERT_TRUE(nigori_entry.good());
795 nigori_entry.Put(SPECIFICS, specifics);
796 nigori_entry.Put(IS_UNSYNCED, true);
797 EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)->
798 has_pending_keys());
799 EXPECT_TRUE(encrypted_types.Equals(
800 syncdb_.manager()->GetCryptographer(&wtrans)->GetEncryptedTypes()));
801 }
802 {
803 sync_pb::EntitySpecifics specifics;
804 sync_pb::NigoriSpecifics* nigori =
805 specifics.MutableExtension(sync_pb::nigori);
806 other_cryptographer.GetKeys(nigori->mutable_encrypted());
807 nigori->set_encrypt_bookmarks(true);
808 nigori->set_encrypt_preferences(true);
809 nigori->set_encrypt_everything(false);
810 mock_server_->SetNigori(1, 20, 20, specifics);
811 }
812
813 // Will result in downloading the server nigori, which puts the local nigori
814 // in a state of conflict. This is resolved by merging the local and server
815 // data (with priority given to the server's encryption keys if they are
816 // undecryptable), which we then commit. The cryptographer should have pending
817 // keys and merge the set of encrypted types.
818 SyncShareAsDelegate(); // Resolve conflict in this cycle.
819 SyncShareAsDelegate(); // Commit local change in this cycle.
820 {
821 // Ensure the nigori data merged (encrypted types, sync_tabs).
822 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
823 MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG,
824 syncable::ModelTypeToRootTag(syncable::NIGORI));
825 ASSERT_TRUE(nigori_entry.good());
826 EXPECT_FALSE(nigori_entry.Get(IS_UNAPPLIED_UPDATE));
827 EXPECT_FALSE(nigori_entry.Get(IS_UNSYNCED));
828 sync_pb::EntitySpecifics specifics = nigori_entry.Get(SPECIFICS);
829 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
830 has_pending_keys());
831 EXPECT_TRUE(encrypted_types.Equals(
832 syncdb_.manager()->GetCryptographer(&wtrans)->GetEncryptedTypes()));
833 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
834 encrypt_everything());
835 EXPECT_TRUE(specifics.GetExtension(sync_pb::nigori).sync_tabs());
836 // Supply the pending keys. Afterwards, we should be able to decrypt both
837 // our own encrypted data and data encrypted by the other cryptographer,
838 // but the key provided by the other cryptographer should be the default.
839 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
840 DecryptPendingKeys(other_key_params));
841 EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)->
842 has_pending_keys());
843 sync_pb::NigoriSpecifics* nigori =
844 specifics.MutableExtension(sync_pb::nigori);
845 syncdb_.manager()->GetCryptographer(&wtrans)->GetKeys(
846 nigori->mutable_encrypted());
847 syncdb_.manager()->GetCryptographer(&wtrans)->
848 UpdateNigoriFromEncryptedTypes(nigori);
849 // Normally this would be written as part of SetPassphrase, but we do it
850 // manually for the test.
851 nigori_entry.Put(SPECIFICS, specifics);
852 nigori_entry.Put(IS_UNSYNCED, true);
853 }
854
855 SyncShareAsDelegate();
856 {
857 // Ensure everything is committed and stable now. The cryptographer
858 // should be able to decrypt both sets of keys, sync_tabs should be true,
859 // and the encrypted types should have been unioned.
860 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
861 MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG,
862 syncable::ModelTypeToRootTag(syncable::NIGORI));
863 ASSERT_TRUE(nigori_entry.good());
864 EXPECT_FALSE(nigori_entry.Get(IS_UNAPPLIED_UPDATE));
865 EXPECT_FALSE(nigori_entry.Get(IS_UNSYNCED));
866 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->CanDecrypt(
867 our_encrypted_specifics.encrypted()));
868 EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)->
869 CanDecryptUsingDefaultKey(our_encrypted_specifics.encrypted()));
870 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->CanDecrypt(
871 other_encrypted_specifics.encrypted()));
872 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
873 CanDecryptUsingDefaultKey(other_encrypted_specifics.encrypted()));
874 EXPECT_TRUE(nigori_entry.Get(SPECIFICS).GetExtension(sync_pb::nigori)
875 .sync_tabs());
876 }
877 }
878
879
747 // TODO(chron): More corner case unit tests around validation. 880 // TODO(chron): More corner case unit tests around validation.
748 TEST_F(SyncerTest, TestCommitMetahandleIterator) { 881 TEST_F(SyncerTest, TestCommitMetahandleIterator) {
749 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 882 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
750 ASSERT_TRUE(dir.good()); 883 ASSERT_TRUE(dir.good());
751 StatusController* status = session_->mutable_status_controller(); 884 StatusController* status = session_->mutable_status_controller();
752 const vector<int64>& unsynced(status->unsynced_handles()); 885 const vector<int64>& unsynced(status->unsynced_handles());
753 886
754 { 887 {
755 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir); 888 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
756 ScopedSetSessionWriteTransaction set_trans(session_.get(), &wtrans); 889 ScopedSetSessionWriteTransaction set_trans(session_.get(), &wtrans);
(...skipping 3792 matching lines...) Expand 10 before | Expand all | Expand 10 after
4549 Add(low_id_); 4682 Add(low_id_);
4550 Add(high_id_); 4683 Add(high_id_);
4551 SyncShareAsDelegate(); 4684 SyncShareAsDelegate();
4552 ExpectLocalOrderIsByServerId(); 4685 ExpectLocalOrderIsByServerId();
4553 } 4686 }
4554 4687
4555 const SyncerTest::CommitOrderingTest 4688 const SyncerTest::CommitOrderingTest
4556 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()}; 4689 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()};
4557 4690
4558 } // namespace browser_sync 4691 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/resolve_conflicts_command.cc ('k') | chrome/browser/sync/engine/syncer_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698