OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |