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

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: Re-add some lines lost in the split 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 15 matching lines...) Expand all
26 #include "chrome/browser/sync/engine/model_safe_worker.h" 26 #include "chrome/browser/sync/engine/model_safe_worker.h"
27 #include "chrome/browser/sync/engine/net/server_connection_manager.h" 27 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
28 #include "chrome/browser/sync/engine/process_updates_command.h" 28 #include "chrome/browser/sync/engine/process_updates_command.h"
29 #include "chrome/browser/sync/engine/nigori_util.h" 29 #include "chrome/browser/sync/engine/nigori_util.h"
30 #include "chrome/browser/sync/engine/syncer.h" 30 #include "chrome/browser/sync/engine/syncer.h"
31 #include "chrome/browser/sync/engine/syncer_proto_util.h" 31 #include "chrome/browser/sync/engine/syncer_proto_util.h"
32 #include "chrome/browser/sync/engine/syncer_util.h" 32 #include "chrome/browser/sync/engine/syncer_util.h"
33 #include "chrome/browser/sync/engine/syncproto.h" 33 #include "chrome/browser/sync/engine/syncproto.h"
34 #include "chrome/browser/sync/protocol/sync.pb.h" 34 #include "chrome/browser/sync/protocol/sync.pb.h"
35 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" 35 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
36 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
36 #include "chrome/browser/sync/sessions/sync_session_context.h" 37 #include "chrome/browser/sync/sessions/sync_session_context.h"
37 #include "chrome/browser/sync/syncable/directory_manager.h" 38 #include "chrome/browser/sync/syncable/directory_manager.h"
38 #include "chrome/browser/sync/syncable/model_type.h" 39 #include "chrome/browser/sync/syncable/model_type.h"
39 #include "chrome/browser/sync/syncable/syncable.h" 40 #include "chrome/browser/sync/syncable/syncable.h"
40 #include "chrome/browser/sync/test/engine/fake_model_worker.h" 41 #include "chrome/browser/sync/test/engine/fake_model_worker.h"
41 #include "chrome/browser/sync/test/engine/mock_connection_manager.h" 42 #include "chrome/browser/sync/test/engine/mock_connection_manager.h"
42 #include "chrome/browser/sync/test/engine/test_directory_setter_upper.h" 43 #include "chrome/browser/sync/test/engine/test_directory_setter_upper.h"
43 #include "chrome/browser/sync/test/engine/test_id_factory.h" 44 #include "chrome/browser/sync/test/engine/test_id_factory.h"
44 #include "chrome/browser/sync/test/engine/test_syncable_utils.h" 45 #include "chrome/browser/sync/test/engine/test_syncable_utils.h"
46 #include "chrome/browser/sync/util/cryptographer.h"
45 #include "chrome/browser/sync/util/time.h" 47 #include "chrome/browser/sync/util/time.h"
46 #include "testing/gtest/include/gtest/gtest.h" 48 #include "testing/gtest/include/gtest/gtest.h"
47 49
48 using base::TimeDelta; 50 using base::TimeDelta;
49 51
50 using std::map; 52 using std::map;
51 using std::multimap; 53 using std::multimap;
52 using std::set; 54 using std::set;
53 using std::string; 55 using std::string;
54 56
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 should_loop = SyncShareAsDelegate(); 192 should_loop = SyncShareAsDelegate();
191 } while (should_loop); 193 } while (should_loop);
192 } 194 }
193 195
194 virtual void SetUp() { 196 virtual void SetUp() {
195 syncdb_.SetUp(); 197 syncdb_.SetUp();
196 198
197 mock_server_.reset( 199 mock_server_.reset(
198 new MockConnectionManager(syncdb_.manager(), syncdb_.name())); 200 new MockConnectionManager(syncdb_.manager(), syncdb_.name()));
199 EnableDatatype(syncable::BOOKMARKS); 201 EnableDatatype(syncable::BOOKMARKS);
202 EnableDatatype(syncable::NIGORI);
200 worker_ = new FakeModelWorker(GROUP_PASSIVE); 203 worker_ = new FakeModelWorker(GROUP_PASSIVE);
201 std::vector<SyncEngineEventListener*> listeners; 204 std::vector<SyncEngineEventListener*> listeners;
202 listeners.push_back(this); 205 listeners.push_back(this);
203 context_.reset(new SyncSessionContext(mock_server_.get(), 206 context_.reset(new SyncSessionContext(mock_server_.get(),
204 syncdb_.manager(), this, listeners, NULL)); 207 syncdb_.manager(), this, listeners, NULL));
205 context_->set_account_name(syncdb_.name()); 208 context_->set_account_name(syncdb_.name());
206 ASSERT_FALSE(context_->resolver()); 209 ASSERT_FALSE(context_->resolver());
207 syncer_ = new Syncer(); 210 syncer_ = new Syncer();
208 session_.reset(MakeSession()); 211 session_.reset(MakeSession());
209 212
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 ASSERT_TRUE(entryC.good()); 741 ASSERT_TRUE(entryC.good());
739 EXPECT_FALSE(entryC.Get(IS_UNSYNCED)); 742 EXPECT_FALSE(entryC.Get(IS_UNSYNCED));
740 EXPECT_FALSE(entryC.Get(IS_UNAPPLIED_UPDATE)); 743 EXPECT_FALSE(entryC.Get(IS_UNAPPLIED_UPDATE));
741 Entry entryD(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(4)); 744 Entry entryD(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(4));
742 ASSERT_TRUE(entryD.good()); 745 ASSERT_TRUE(entryD.good());
743 EXPECT_FALSE(entryD.Get(IS_UNSYNCED)); 746 EXPECT_FALSE(entryD.Get(IS_UNSYNCED));
744 EXPECT_FALSE(entryD.Get(IS_UNAPPLIED_UPDATE)); 747 EXPECT_FALSE(entryD.Get(IS_UNAPPLIED_UPDATE));
745 } 748 }
746 } 749 }
747 750
751 TEST_F(SyncerTest, NigoriConflicts) {
752 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
753 ASSERT_TRUE(dir.good());
754 KeyParams local_key_params = {"localhost", "dummy", "blargle"};
755 KeyParams other_key_params = {"localhost", "dummy", "foobar"};
756 browser_sync::Cryptographer other_cryptographer;
757 other_cryptographer.AddKey(other_key_params);
758 syncable::ModelTypeSet encrypted_types(syncable::PASSWORDS, syncable::NIGORI);
759 sync_pb::EntitySpecifics initial_nigori_specifics;
760 initial_nigori_specifics.MutableExtension(sync_pb::nigori);
761 mock_server_->SetNigori(1, 10, 10, initial_nigori_specifics);
762
763 // Data for testing encryption/decryption.
764 sync_pb::EntitySpecifics other_encrypted_specifics;
765 other_encrypted_specifics.MutableExtension(sync_pb::bookmark)->
766 set_title("title");
767 other_cryptographer.Encrypt(
768 other_encrypted_specifics,
769 other_encrypted_specifics.mutable_encrypted());
770 sync_pb::EntitySpecifics our_encrypted_specifics;
771 our_encrypted_specifics.MutableExtension(sync_pb::bookmark)->
772 set_title("title2");
773
774 // Receive the initial nigori node.
775 SyncShareAsDelegate();
776 encrypted_types = syncable::ModelTypeSet::All();
777 {
778 // Local changes with different passphrase and different types.
779 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
780 sync_pb::EntitySpecifics specifics;
781 sync_pb::NigoriSpecifics* nigori =
782 specifics.MutableExtension(sync_pb::nigori);
783 syncdb_.manager()->GetCryptographer(&wtrans)->AddKey(local_key_params);
784 syncdb_.manager()->GetCryptographer(&wtrans)->Encrypt(
785 our_encrypted_specifics,
786 our_encrypted_specifics.mutable_encrypted());
787 syncdb_.manager()->GetCryptographer(&wtrans)->GetKeys(
788 nigori->mutable_encrypted());
789 syncdb_.manager()->GetCryptographer(&wtrans)->
790 UpdateNigoriFromEncryptedTypes(nigori);
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 set of encrypted types merged.
822 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
823 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
824 has_pending_keys());
825 EXPECT_TRUE(encrypted_types.Equals(
826 syncdb_.manager()->GetCryptographer(&wtrans)->GetEncryptedTypes()));
827 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
828 encrypt_everything());
829 // Supply the pending keys. Afterwards, we should be able to decrypt both
830 // our own encrypted data and data encrypted by the other cryptographer,
831 // but the key provided by the other cryptographer should be the default.
832 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
833 DecryptPendingKeys(other_key_params));
834 EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)->
835 has_pending_keys());
836 sync_pb::EntitySpecifics specifics;
837 sync_pb::NigoriSpecifics* nigori =
838 specifics.MutableExtension(sync_pb::nigori);
839 syncdb_.manager()->GetCryptographer(&wtrans)->GetKeys(
840 nigori->mutable_encrypted());
841 syncdb_.manager()->GetCryptographer(&wtrans)->
842 UpdateNigoriFromEncryptedTypes(nigori);
843 MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG,
844 syncable::ModelTypeToRootTag(syncable::NIGORI));
845 ASSERT_TRUE(nigori_entry.good());
846 EXPECT_FALSE(nigori_entry.Get(IS_UNAPPLIED_UPDATE));
847 EXPECT_FALSE(nigori_entry.Get(IS_UNSYNCED));
848 // Normally this would be written as part of SetPassphrase, but we do it
849 // manually for the test.
850 nigori_entry.Put(SPECIFICS, specifics);
851 nigori_entry.Put(IS_UNSYNCED, true);
852 }
853
854 SyncShareAsDelegate();
855 {
856 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
857 MutableEntry nigori_entry(&wtrans, GET_BY_SERVER_TAG,
858 syncable::ModelTypeToRootTag(syncable::NIGORI));
859 ASSERT_TRUE(nigori_entry.good());
860 EXPECT_FALSE(nigori_entry.Get(IS_UNAPPLIED_UPDATE));
861 EXPECT_FALSE(nigori_entry.Get(IS_UNSYNCED));
862 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->CanDecrypt(
863 our_encrypted_specifics.encrypted()));
864 EXPECT_FALSE(syncdb_.manager()->GetCryptographer(&wtrans)->
865 CanDecryptUsingDefaultKey(our_encrypted_specifics.encrypted()));
866 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->CanDecrypt(
867 other_encrypted_specifics.encrypted()));
868 EXPECT_TRUE(syncdb_.manager()->GetCryptographer(&wtrans)->
869 CanDecryptUsingDefaultKey(other_encrypted_specifics.encrypted()));
870 }
871 }
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.
872
873
748 // TODO(chron): More corner case unit tests around validation. 874 // TODO(chron): More corner case unit tests around validation.
749 TEST_F(SyncerTest, TestCommitMetahandleIterator) { 875 TEST_F(SyncerTest, TestCommitMetahandleIterator) {
750 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 876 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
751 ASSERT_TRUE(dir.good()); 877 ASSERT_TRUE(dir.good());
752 StatusController* status = session_->mutable_status_controller(); 878 StatusController* status = session_->mutable_status_controller();
753 const vector<int64>& unsynced(status->unsynced_handles()); 879 const vector<int64>& unsynced(status->unsynced_handles());
754 880
755 { 881 {
756 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir); 882 WriteTransaction wtrans(FROM_HERE, UNITTEST, dir);
757 ScopedSetSessionWriteTransaction set_trans(session_.get(), &wtrans); 883 ScopedSetSessionWriteTransaction set_trans(session_.get(), &wtrans);
(...skipping 4593 matching lines...) Expand 10 before | Expand all | Expand 10 after
5351 Add(low_id_); 5477 Add(low_id_);
5352 Add(high_id_); 5478 Add(high_id_);
5353 SyncShareAsDelegate(); 5479 SyncShareAsDelegate();
5354 ExpectLocalOrderIsByServerId(); 5480 ExpectLocalOrderIsByServerId();
5355 } 5481 }
5356 5482
5357 const SyncerTest::CommitOrderingTest 5483 const SyncerTest::CommitOrderingTest
5358 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()}; 5484 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()};
5359 5485
5360 } // namespace browser_sync 5486 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698