| 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 // Unit tests for the SyncApi. Note that a lot of the underlying | 5 // Unit tests for the SyncApi. Note that a lot of the underlying |
| 6 // functionality is provided by the Syncable layer, which has its own | 6 // functionality is provided by the Syncable layer, which has its own |
| 7 // unit tests. We'll test SyncApi specific things in this harness. | 7 // unit tests. We'll test SyncApi specific things in this harness. |
| 8 | 8 |
| 9 #include <cstddef> | 9 #include <cstddef> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 using browser_sync::JsReplyHandler; | 66 using browser_sync::JsReplyHandler; |
| 67 using browser_sync::MockJsEventHandler; | 67 using browser_sync::MockJsEventHandler; |
| 68 using browser_sync::MockJsReplyHandler; | 68 using browser_sync::MockJsReplyHandler; |
| 69 using browser_sync::ModelSafeRoutingInfo; | 69 using browser_sync::ModelSafeRoutingInfo; |
| 70 using browser_sync::ModelSafeWorker; | 70 using browser_sync::ModelSafeWorker; |
| 71 using browser_sync::ModelSafeWorkerRegistrar; | 71 using browser_sync::ModelSafeWorkerRegistrar; |
| 72 using browser_sync::sessions::SyncSessionSnapshot; | 72 using browser_sync::sessions::SyncSessionSnapshot; |
| 73 using browser_sync::WeakHandle; | 73 using browser_sync::WeakHandle; |
| 74 using content::BrowserThread; | 74 using content::BrowserThread; |
| 75 using syncable::GetAllRealModelTypes; | 75 using syncable::GetAllRealModelTypes; |
| 76 using syncable::IS_DEL; |
| 77 using syncable::IS_UNSYNCED; |
| 76 using syncable::kEncryptedString; | 78 using syncable::kEncryptedString; |
| 77 using syncable::ModelType; | 79 using syncable::ModelType; |
| 78 using syncable::ModelTypeSet; | 80 using syncable::ModelTypeSet; |
| 81 using syncable::NON_UNIQUE_NAME; |
| 82 using syncable::SPECIFICS; |
| 79 using test::ExpectDictStringValue; | 83 using test::ExpectDictStringValue; |
| 80 using testing::_; | 84 using testing::_; |
| 81 using testing::AnyNumber; | 85 using testing::AnyNumber; |
| 82 using testing::AtLeast; | 86 using testing::AtLeast; |
| 83 using testing::InSequence; | 87 using testing::InSequence; |
| 84 using testing::Invoke; | 88 using testing::Invoke; |
| 85 using testing::SaveArg; | 89 using testing::SaveArg; |
| 86 using testing::StrictMock; | 90 using testing::StrictMock; |
| 87 | 91 |
| 88 namespace sync_api { | 92 namespace sync_api { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 entry.Put(syncable::SERVER_IS_DIR, true); | 176 entry.Put(syncable::SERVER_IS_DIR, true); |
| 173 entry.Put(syncable::IS_DIR, true); | 177 entry.Put(syncable::IS_DIR, true); |
| 174 entry.Put(syncable::SERVER_SPECIFICS, specifics); | 178 entry.Put(syncable::SERVER_SPECIFICS, specifics); |
| 175 entry.Put(syncable::UNIQUE_SERVER_TAG, type_tag); | 179 entry.Put(syncable::UNIQUE_SERVER_TAG, type_tag); |
| 176 entry.Put(syncable::NON_UNIQUE_NAME, type_tag); | 180 entry.Put(syncable::NON_UNIQUE_NAME, type_tag); |
| 177 entry.Put(syncable::IS_DEL, false); | 181 entry.Put(syncable::IS_DEL, false); |
| 178 entry.Put(syncable::SPECIFICS, specifics); | 182 entry.Put(syncable::SPECIFICS, specifics); |
| 179 return entry.Get(syncable::META_HANDLE); | 183 return entry.Get(syncable::META_HANDLE); |
| 180 } | 184 } |
| 181 | 185 |
| 186 // Simulates creating a "synced" node as a child of the root datatype node. |
| 187 int64 MakeServerNode(UserShare* share, ModelType model_type, |
| 188 const std::string& client_tag, |
| 189 const std::string& hashed_tag, |
| 190 const sync_pb::EntitySpecifics& specifics) { |
| 191 syncable::ScopedDirLookup dir(share->dir_manager.get(), share->name); |
| 192 EXPECT_TRUE(dir.good()); |
| 193 syncable::WriteTransaction trans(FROM_HERE, syncable::UNITTEST, dir); |
| 194 syncable::Entry root_entry(&trans, syncable::GET_BY_SERVER_TAG, |
| 195 syncable::ModelTypeToRootTag(model_type)); |
| 196 EXPECT_TRUE(root_entry.good()); |
| 197 syncable::Id root_id = root_entry.Get(syncable::ID); |
| 198 syncable::Id node_id = syncable::Id::CreateFromServerId(client_tag); |
| 199 syncable::MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM, |
| 200 node_id); |
| 201 EXPECT_TRUE(entry.good()); |
| 202 entry.Put(syncable::BASE_VERSION, 1); |
| 203 entry.Put(syncable::SERVER_VERSION, 1); |
| 204 entry.Put(syncable::IS_UNAPPLIED_UPDATE, false); |
| 205 entry.Put(syncable::SERVER_PARENT_ID, root_id); |
| 206 entry.Put(syncable::PARENT_ID, root_id); |
| 207 entry.Put(syncable::SERVER_IS_DIR, false); |
| 208 entry.Put(syncable::IS_DIR, false); |
| 209 entry.Put(syncable::SERVER_SPECIFICS, specifics); |
| 210 entry.Put(syncable::NON_UNIQUE_NAME, client_tag); |
| 211 entry.Put(syncable::UNIQUE_CLIENT_TAG, hashed_tag); |
| 212 entry.Put(syncable::IS_DEL, false); |
| 213 entry.Put(syncable::SPECIFICS, specifics); |
| 214 return entry.Get(syncable::META_HANDLE); |
| 215 } |
| 216 |
| 182 } // namespace | 217 } // namespace |
| 183 | 218 |
| 184 class SyncApiTest : public testing::Test { | 219 class SyncApiTest : public testing::Test { |
| 185 public: | 220 public: |
| 186 virtual void SetUp() { | 221 virtual void SetUp() { |
| 187 test_user_share_.SetUp(); | 222 test_user_share_.SetUp(); |
| 188 } | 223 } |
| 189 | 224 |
| 190 virtual void TearDown() { | 225 virtual void TearDown() { |
| 191 test_user_share_.TearDown(); | 226 test_user_share_.TearDown(); |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 MOCK_METHOD1(RemoveObserver, void(sync_notifier::SyncNotifierObserver*)); | 679 MOCK_METHOD1(RemoveObserver, void(sync_notifier::SyncNotifierObserver*)); |
| 645 MOCK_METHOD1(SetUniqueId, void(const std::string&)); | 680 MOCK_METHOD1(SetUniqueId, void(const std::string&)); |
| 646 MOCK_METHOD1(SetState, void(const std::string&)); | 681 MOCK_METHOD1(SetState, void(const std::string&)); |
| 647 MOCK_METHOD2(UpdateCredentials, | 682 MOCK_METHOD2(UpdateCredentials, |
| 648 void(const std::string&, const std::string&)); | 683 void(const std::string&, const std::string&)); |
| 649 MOCK_METHOD1(UpdateEnabledTypes, | 684 MOCK_METHOD1(UpdateEnabledTypes, |
| 650 void(const syncable::ModelTypeSet&)); | 685 void(const syncable::ModelTypeSet&)); |
| 651 MOCK_METHOD1(SendNotification, void(const syncable::ModelTypeSet&)); | 686 MOCK_METHOD1(SendNotification, void(const syncable::ModelTypeSet&)); |
| 652 }; | 687 }; |
| 653 | 688 |
| 689 } // namespace |
| 690 |
| 654 class SyncManagerTest : public testing::Test, | 691 class SyncManagerTest : public testing::Test, |
| 655 public ModelSafeWorkerRegistrar, | 692 public ModelSafeWorkerRegistrar, |
| 656 public SyncManager::ChangeDelegate { | 693 public SyncManager::ChangeDelegate { |
| 657 protected: | 694 protected: |
| 658 SyncManagerTest() | 695 SyncManagerTest() |
| 659 : ui_thread_(BrowserThread::UI, &ui_loop_), | 696 : ui_thread_(BrowserThread::UI, &ui_loop_), |
| 660 sync_notifier_mock_(NULL), | 697 sync_notifier_mock_(NULL), |
| 661 sync_manager_("Test sync manager"), | 698 sync_manager_("Test sync manager"), |
| 662 sync_notifier_observer_(NULL), | 699 sync_notifier_observer_(NULL), |
| 663 update_enabled_types_call_count_(0) {} | 700 update_enabled_types_call_count_(0) {} |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 } | 777 } |
| 741 | 778 |
| 742 virtual void OnChangesApplied( | 779 virtual void OnChangesApplied( |
| 743 syncable::ModelType model_type, | 780 syncable::ModelType model_type, |
| 744 const BaseTransaction* trans, | 781 const BaseTransaction* trans, |
| 745 const ImmutableChangeRecordList& changes) OVERRIDE {} | 782 const ImmutableChangeRecordList& changes) OVERRIDE {} |
| 746 | 783 |
| 747 virtual void OnChangesComplete(syncable::ModelType model_type) OVERRIDE {} | 784 virtual void OnChangesComplete(syncable::ModelType model_type) OVERRIDE {} |
| 748 | 785 |
| 749 // Helper methods. | 786 // Helper methods. |
| 750 bool SetUpEncryption(bool write_to_nigori) { | 787 bool SetUpEncryption(bool write_to_nigori, bool encrypt_everything) { |
| 751 // Mock the Mac Keychain service. The real Keychain can block on user input. | 788 // Mock the Mac Keychain service. The real Keychain can block on user input. |
| 752 #if defined(OS_MACOSX) | 789 #if defined(OS_MACOSX) |
| 753 Encryptor::UseMockKeychain(true); | 790 Encryptor::UseMockKeychain(true); |
| 754 #endif | 791 #endif |
| 755 | 792 |
| 756 UserShare* share = sync_manager_.GetUserShare(); | 793 UserShare* share = sync_manager_.GetUserShare(); |
| 757 { | 794 { |
| 758 syncable::ScopedDirLookup dir(share->dir_manager.get(), share->name); | 795 syncable::ScopedDirLookup dir(share->dir_manager.get(), share->name); |
| 759 if (!dir.good()) | 796 if (!dir.good()) |
| 760 return false; | 797 return false; |
| 761 dir->set_initial_sync_ended_for_type(syncable::NIGORI, true); | 798 dir->set_initial_sync_ended_for_type(syncable::NIGORI, true); |
| 762 } | 799 } |
| 763 | 800 |
| 764 // We need to create the nigori node as if it were an applied server update. | 801 // We need to create the nigori node as if it were an applied server update. |
| 765 int64 nigori_id = GetIdForDataType(syncable::NIGORI); | 802 int64 nigori_id = GetIdForDataType(syncable::NIGORI); |
| 766 if (nigori_id == kInvalidId) | 803 if (nigori_id == kInvalidId) |
| 767 return false; | 804 return false; |
| 768 | 805 |
| 769 // Set the nigori cryptographer information. | 806 // Set the nigori cryptographer information. |
| 770 WriteTransaction trans(FROM_HERE, share); | 807 WriteTransaction trans(FROM_HERE, share); |
| 771 Cryptographer* cryptographer = trans.GetCryptographer(); | 808 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 772 if (!cryptographer) | 809 if (!cryptographer) |
| 773 return false; | 810 return false; |
| 774 KeyParams params = {"localhost", "dummy", "foobar"}; | 811 KeyParams params = {"localhost", "dummy", "foobar"}; |
| 775 cryptographer->AddKey(params); | 812 cryptographer->AddKey(params); |
| 813 if (encrypt_everything) |
| 814 cryptographer->set_encrypt_everything(); |
| 776 if (write_to_nigori) { | 815 if (write_to_nigori) { |
| 777 sync_pb::NigoriSpecifics nigori; | 816 sync_pb::NigoriSpecifics nigori; |
| 778 cryptographer->GetKeys(nigori.mutable_encrypted()); | 817 cryptographer->GetKeys(nigori.mutable_encrypted()); |
| 818 cryptographer->UpdateNigoriFromEncryptedTypes(&nigori); |
| 779 WriteNode node(&trans); | 819 WriteNode node(&trans); |
| 780 EXPECT_TRUE(node.InitByIdLookup(nigori_id)); | 820 EXPECT_TRUE(node.InitByIdLookup(nigori_id)); |
| 781 node.SetNigoriSpecifics(nigori); | 821 node.SetNigoriSpecifics(nigori); |
| 782 } | 822 } |
| 783 return cryptographer->is_ready(); | 823 return cryptographer->is_ready(); |
| 784 } | 824 } |
| 785 | 825 |
| 786 int64 GetIdForDataType(ModelType type) { | 826 int64 GetIdForDataType(ModelType type) { |
| 787 if (type_roots_.count(type) == 0) | 827 if (type_roots_.count(type) == 0) |
| 788 return 0; | 828 return 0; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 name, args, reply_handler); | 864 name, args, reply_handler); |
| 825 PumpLoop(); | 865 PumpLoop(); |
| 826 } | 866 } |
| 827 | 867 |
| 828 void SetJsEventHandler(const WeakHandle<JsEventHandler>& event_handler) { | 868 void SetJsEventHandler(const WeakHandle<JsEventHandler>& event_handler) { |
| 829 js_backend_.Call(FROM_HERE, &JsBackend::SetJsEventHandler, | 869 js_backend_.Call(FROM_HERE, &JsBackend::SetJsEventHandler, |
| 830 event_handler); | 870 event_handler); |
| 831 PumpLoop(); | 871 PumpLoop(); |
| 832 } | 872 } |
| 833 | 873 |
| 874 // Looks up an entry by client tag and resets IS_UNSYNCED value to false. |
| 875 // Returns true if entry was previously unsynced, false if IS_UNSYNCED was |
| 876 // already false. |
| 877 bool ResetUnsyncedEntry(syncable::ModelType type, |
| 878 const std::string& client_tag) { |
| 879 UserShare* share = sync_manager_.GetUserShare(); |
| 880 syncable::ScopedDirLookup dir(share->dir_manager.get(), share->name); |
| 881 EXPECT_TRUE(dir.good()); |
| 882 syncable::WriteTransaction trans(FROM_HERE, syncable::UNITTEST, dir); |
| 883 const std::string hash = BaseNode::GenerateSyncableHash(type, client_tag); |
| 884 syncable::MutableEntry entry(&trans, syncable::GET_BY_CLIENT_TAG, |
| 885 hash); |
| 886 EXPECT_TRUE(entry.good()); |
| 887 if (!entry.Get(IS_UNSYNCED)) |
| 888 return false; |
| 889 else |
| 890 entry.Put(IS_UNSYNCED, false); |
| 891 return true; |
| 892 } |
| 893 |
| 834 private: | 894 private: |
| 835 // Needed by |ui_thread_|. | 895 // Needed by |ui_thread_|. |
| 836 MessageLoopForUI ui_loop_; | 896 MessageLoopForUI ui_loop_; |
| 837 // Needed by |sync_manager_|. | 897 // Needed by |sync_manager_|. |
| 838 content::TestBrowserThread ui_thread_; | 898 content::TestBrowserThread ui_thread_; |
| 839 // Needed by |sync_manager_|. | 899 // Needed by |sync_manager_|. |
| 840 ScopedTempDir temp_dir_; | 900 ScopedTempDir temp_dir_; |
| 841 // Sync Id's for the roots of the enabled datatypes. | 901 // Sync Id's for the roots of the enabled datatypes. |
| 842 std::map<ModelType, int64> type_roots_; | 902 std::map<ModelType, int64> type_roots_; |
| 843 StrictMock<SyncNotifierMock>* sync_notifier_mock_; | 903 StrictMock<SyncNotifierMock>* sync_notifier_mock_; |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 SetJsEventHandler(WeakHandle<JsEventHandler>()); | 1258 SetJsEventHandler(WeakHandle<JsEventHandler>()); |
| 1199 | 1259 |
| 1200 sync_manager_.TriggerOnIncomingNotificationForTest(empty_model_types); | 1260 sync_manager_.TriggerOnIncomingNotificationForTest(empty_model_types); |
| 1201 sync_manager_.TriggerOnIncomingNotificationForTest(model_types); | 1261 sync_manager_.TriggerOnIncomingNotificationForTest(model_types); |
| 1202 | 1262 |
| 1203 // Should trigger the replies. | 1263 // Should trigger the replies. |
| 1204 PumpLoop(); | 1264 PumpLoop(); |
| 1205 } | 1265 } |
| 1206 | 1266 |
| 1207 TEST_F(SyncManagerTest, RefreshEncryptionReady) { | 1267 TEST_F(SyncManagerTest, RefreshEncryptionReady) { |
| 1208 EXPECT_TRUE(SetUpEncryption(true)); | 1268 EXPECT_TRUE(SetUpEncryption(true, false)); |
| 1209 EXPECT_CALL(observer_, OnEncryptionComplete()); | 1269 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1210 sync_manager_.RefreshEncryption(); | 1270 sync_manager_.RefreshEncryption(); |
| 1211 syncable::ModelTypeSet encrypted_types = | 1271 syncable::ModelTypeSet encrypted_types = |
| 1212 sync_manager_.GetEncryptedDataTypesForTest(); | 1272 sync_manager_.GetEncryptedDataTypesForTest(); |
| 1213 EXPECT_EQ(1U, encrypted_types.count(syncable::PASSWORDS)); | 1273 EXPECT_EQ(1U, encrypted_types.count(syncable::PASSWORDS)); |
| 1214 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); | 1274 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); |
| 1215 { | 1275 { |
| 1216 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); | 1276 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1217 ReadNode node(&trans); | 1277 ReadNode node(&trans); |
| 1218 EXPECT_TRUE(node.InitByIdLookup(GetIdForDataType(syncable::NIGORI))); | 1278 EXPECT_TRUE(node.InitByIdLookup(GetIdForDataType(syncable::NIGORI))); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1229 // Don't set up encryption (no nigori node created). | 1289 // Don't set up encryption (no nigori node created). |
| 1230 sync_manager_.RefreshEncryption(); // Should fail. | 1290 sync_manager_.RefreshEncryption(); // Should fail. |
| 1231 syncable::ModelTypeSet encrypted_types = | 1291 syncable::ModelTypeSet encrypted_types = |
| 1232 sync_manager_.GetEncryptedDataTypesForTest(); | 1292 sync_manager_.GetEncryptedDataTypesForTest(); |
| 1233 EXPECT_EQ(1U, encrypted_types.count(syncable::PASSWORDS)); // Hardcoded. | 1293 EXPECT_EQ(1U, encrypted_types.count(syncable::PASSWORDS)); // Hardcoded. |
| 1234 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); | 1294 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); |
| 1235 } | 1295 } |
| 1236 | 1296 |
| 1237 // Attempt to refresh encryption when nigori is empty. | 1297 // Attempt to refresh encryption when nigori is empty. |
| 1238 TEST_F(SyncManagerTest, RefreshEncryptionEmptyNigori) { | 1298 TEST_F(SyncManagerTest, RefreshEncryptionEmptyNigori) { |
| 1239 EXPECT_TRUE(SetUpEncryption(false)); | 1299 EXPECT_TRUE(SetUpEncryption(false, false)); |
| 1240 EXPECT_CALL(observer_, OnEncryptionComplete()); | 1300 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1241 sync_manager_.RefreshEncryption(); // Should write to nigori. | 1301 sync_manager_.RefreshEncryption(); // Should write to nigori. |
| 1242 syncable::ModelTypeSet encrypted_types = | 1302 syncable::ModelTypeSet encrypted_types = |
| 1243 sync_manager_.GetEncryptedDataTypesForTest(); | 1303 sync_manager_.GetEncryptedDataTypesForTest(); |
| 1244 EXPECT_EQ(1U, encrypted_types.count(syncable::PASSWORDS)); // Hardcoded. | 1304 EXPECT_EQ(1U, encrypted_types.count(syncable::PASSWORDS)); // Hardcoded. |
| 1245 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); | 1305 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); |
| 1246 { | 1306 { |
| 1247 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); | 1307 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1248 ReadNode node(&trans); | 1308 ReadNode node(&trans); |
| 1249 EXPECT_TRUE(node.InitByIdLookup(GetIdForDataType(syncable::NIGORI))); | 1309 EXPECT_TRUE(node.InitByIdLookup(GetIdForDataType(syncable::NIGORI))); |
| 1250 sync_pb::NigoriSpecifics nigori = node.GetNigoriSpecifics(); | 1310 sync_pb::NigoriSpecifics nigori = node.GetNigoriSpecifics(); |
| 1251 EXPECT_TRUE(nigori.has_encrypted()); | 1311 EXPECT_TRUE(nigori.has_encrypted()); |
| 1252 Cryptographer* cryptographer = trans.GetCryptographer(); | 1312 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 1253 EXPECT_TRUE(cryptographer->is_ready()); | 1313 EXPECT_TRUE(cryptographer->is_ready()); |
| 1254 EXPECT_TRUE(cryptographer->CanDecrypt(nigori.encrypted())); | 1314 EXPECT_TRUE(cryptographer->CanDecrypt(nigori.encrypted())); |
| 1255 } | 1315 } |
| 1256 } | 1316 } |
| 1257 | 1317 |
| 1258 TEST_F(SyncManagerTest, EncryptDataTypesWithNoData) { | 1318 TEST_F(SyncManagerTest, EncryptDataTypesWithNoData) { |
| 1259 EXPECT_TRUE(SetUpEncryption(true)); | 1319 EXPECT_TRUE(SetUpEncryption(true, false)); |
| 1260 EXPECT_CALL(observer_, | 1320 EXPECT_CALL(observer_, |
| 1261 OnEncryptedTypesChanged(GetAllRealModelTypes(), true)); | 1321 OnEncryptedTypesChanged(GetAllRealModelTypes(), true)); |
| 1262 EXPECT_CALL(observer_, OnEncryptionComplete()); | 1322 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1263 sync_manager_.EnableEncryptEverything(); | 1323 sync_manager_.EnableEncryptEverything(); |
| 1264 EXPECT_TRUE(sync_manager_.EncryptEverythingEnabledForTest()); | 1324 EXPECT_TRUE(sync_manager_.EncryptEverythingEnabledForTest()); |
| 1265 } | 1325 } |
| 1266 | 1326 |
| 1267 TEST_F(SyncManagerTest, EncryptDataTypesWithData) { | 1327 TEST_F(SyncManagerTest, EncryptDataTypesWithData) { |
| 1268 size_t batch_size = 5; | 1328 size_t batch_size = 5; |
| 1269 EXPECT_TRUE(SetUpEncryption(true)); | 1329 EXPECT_TRUE(SetUpEncryption(true, false)); |
| 1270 | 1330 |
| 1271 // Create some unencrypted unsynced data. | 1331 // Create some unencrypted unsynced data. |
| 1272 int64 folder = MakeFolderWithParent(sync_manager_.GetUserShare(), | 1332 int64 folder = MakeFolderWithParent(sync_manager_.GetUserShare(), |
| 1273 syncable::BOOKMARKS, | 1333 syncable::BOOKMARKS, |
| 1274 GetIdForDataType(syncable::BOOKMARKS), | 1334 GetIdForDataType(syncable::BOOKMARKS), |
| 1275 NULL); | 1335 NULL); |
| 1276 // First batch_size nodes are children of folder. | 1336 // First batch_size nodes are children of folder. |
| 1277 size_t i; | 1337 size_t i; |
| 1278 for (i = 0; i < batch_size; ++i) { | 1338 for (i = 0; i < batch_size; ++i) { |
| 1279 MakeNodeWithParent(sync_manager_.GetUserShare(), syncable::BOOKMARKS, | 1339 MakeNodeWithParent(sync_manager_.GetUserShare(), syncable::BOOKMARKS, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 // Calling EncryptDataTypes with an empty encrypted types should not trigger | 1425 // Calling EncryptDataTypes with an empty encrypted types should not trigger |
| 1366 // a reencryption and should just notify immediately. | 1426 // a reencryption and should just notify immediately. |
| 1367 // TODO(zea): add logic to ensure nothing was written. | 1427 // TODO(zea): add logic to ensure nothing was written. |
| 1368 testing::Mock::VerifyAndClearExpectations(&observer_); | 1428 testing::Mock::VerifyAndClearExpectations(&observer_); |
| 1369 EXPECT_CALL(observer_, OnPassphraseAccepted(_)).Times(0); | 1429 EXPECT_CALL(observer_, OnPassphraseAccepted(_)).Times(0); |
| 1370 EXPECT_CALL(observer_, OnEncryptionComplete()); | 1430 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1371 sync_manager_.EnableEncryptEverything(); | 1431 sync_manager_.EnableEncryptEverything(); |
| 1372 } | 1432 } |
| 1373 | 1433 |
| 1374 TEST_F(SyncManagerTest, SetPassphraseWithPassword) { | 1434 TEST_F(SyncManagerTest, SetPassphraseWithPassword) { |
| 1375 EXPECT_TRUE(SetUpEncryption(true)); | 1435 EXPECT_TRUE(SetUpEncryption(true, false)); |
| 1376 { | 1436 { |
| 1377 WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); | 1437 WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1378 ReadNode root_node(&trans); | 1438 ReadNode root_node(&trans); |
| 1379 root_node.InitByRootLookup(); | 1439 root_node.InitByRootLookup(); |
| 1380 | 1440 |
| 1381 WriteNode password_node(&trans); | 1441 WriteNode password_node(&trans); |
| 1382 EXPECT_TRUE(password_node.InitUniqueByCreation(syncable::PASSWORDS, | 1442 EXPECT_TRUE(password_node.InitUniqueByCreation(syncable::PASSWORDS, |
| 1383 root_node, "foo")); | 1443 root_node, "foo")); |
| 1384 sync_pb::PasswordSpecificsData data; | 1444 sync_pb::PasswordSpecificsData data; |
| 1385 data.set_password_value("secret"); | 1445 data.set_password_value("secret"); |
| 1386 password_node.SetPasswordSpecifics(data); | 1446 password_node.SetPasswordSpecifics(data); |
| 1387 } | 1447 } |
| 1388 EXPECT_CALL(observer_, OnPassphraseAccepted(_)); | 1448 EXPECT_CALL(observer_, OnPassphraseAccepted(_)); |
| 1389 EXPECT_CALL(observer_, OnEncryptionComplete()); | 1449 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1390 sync_manager_.SetPassphrase("new_passphrase", true); | 1450 sync_manager_.SetPassphrase("new_passphrase", true); |
| 1391 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); | 1451 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); |
| 1392 { | 1452 { |
| 1393 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); | 1453 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1394 ReadNode password_node(&trans); | 1454 ReadNode password_node(&trans); |
| 1395 EXPECT_TRUE(password_node.InitByClientTagLookup(syncable::PASSWORDS, | 1455 EXPECT_TRUE(password_node.InitByClientTagLookup(syncable::PASSWORDS, |
| 1396 "foo")); | 1456 "foo")); |
| 1397 const sync_pb::PasswordSpecificsData& data = | 1457 const sync_pb::PasswordSpecificsData& data = |
| 1398 password_node.GetPasswordSpecifics(); | 1458 password_node.GetPasswordSpecifics(); |
| 1399 EXPECT_EQ("secret", data.password_value()); | 1459 EXPECT_EQ("secret", data.password_value()); |
| 1400 } | 1460 } |
| 1401 } | 1461 } |
| 1402 | 1462 |
| 1403 TEST_F(SyncManagerTest, SetPassphraseWithEmptyPasswordNode) { | 1463 TEST_F(SyncManagerTest, SetPassphraseWithEmptyPasswordNode) { |
| 1404 EXPECT_TRUE(SetUpEncryption(true)); | 1464 EXPECT_TRUE(SetUpEncryption(true, false)); |
| 1405 int64 node_id = 0; | 1465 int64 node_id = 0; |
| 1406 std::string tag = "foo"; | 1466 std::string tag = "foo"; |
| 1407 { | 1467 { |
| 1408 WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); | 1468 WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1409 ReadNode root_node(&trans); | 1469 ReadNode root_node(&trans); |
| 1410 root_node.InitByRootLookup(); | 1470 root_node.InitByRootLookup(); |
| 1411 | 1471 |
| 1412 WriteNode password_node(&trans); | 1472 WriteNode password_node(&trans); |
| 1413 EXPECT_TRUE(password_node.InitUniqueByCreation(syncable::PASSWORDS, | 1473 EXPECT_TRUE(password_node.InitUniqueByCreation(syncable::PASSWORDS, |
| 1414 root_node, tag)); | 1474 root_node, tag)); |
| 1415 node_id = password_node.GetId(); | 1475 node_id = password_node.GetId(); |
| 1416 } | 1476 } |
| 1417 EXPECT_CALL(observer_, OnPassphraseAccepted(_)); | 1477 EXPECT_CALL(observer_, OnPassphraseAccepted(_)); |
| 1418 EXPECT_CALL(observer_, OnEncryptionComplete()); | 1478 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1419 sync_manager_.SetPassphrase("new_passphrase", true); | 1479 sync_manager_.SetPassphrase("new_passphrase", true); |
| 1420 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); | 1480 EXPECT_FALSE(sync_manager_.EncryptEverythingEnabledForTest()); |
| 1421 { | 1481 { |
| 1422 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); | 1482 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1423 ReadNode password_node(&trans); | 1483 ReadNode password_node(&trans); |
| 1424 EXPECT_FALSE(password_node.InitByClientTagLookup(syncable::PASSWORDS, | 1484 EXPECT_FALSE(password_node.InitByClientTagLookup(syncable::PASSWORDS, |
| 1425 tag)); | 1485 tag)); |
| 1426 } | 1486 } |
| 1427 { | 1487 { |
| 1428 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); | 1488 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1429 ReadNode password_node(&trans); | 1489 ReadNode password_node(&trans); |
| 1430 EXPECT_FALSE(password_node.InitByIdLookup(node_id)); | 1490 EXPECT_FALSE(password_node.InitByIdLookup(node_id)); |
| 1431 } | 1491 } |
| 1432 } | 1492 } |
| 1433 | 1493 |
| 1434 } // namespace | |
| 1435 | |
| 1436 // Friended by WriteNode, so can't be in an anonymouse namespace. | 1494 // Friended by WriteNode, so can't be in an anonymouse namespace. |
| 1437 TEST_F(SyncManagerTest, EncryptBookmarksWithLegacyData) { | 1495 TEST_F(SyncManagerTest, EncryptBookmarksWithLegacyData) { |
| 1438 EXPECT_TRUE(SetUpEncryption(true)); | 1496 EXPECT_TRUE(SetUpEncryption(true, false)); |
| 1439 std::string title; | 1497 std::string title; |
| 1440 SyncAPINameToServerName("Google", &title); | 1498 SyncAPINameToServerName("Google", &title); |
| 1441 std::string url = "http://www.google.com"; | 1499 std::string url = "http://www.google.com"; |
| 1442 std::string raw_title2 = ".."; // An invalid cosmo title. | 1500 std::string raw_title2 = ".."; // An invalid cosmo title. |
| 1443 std::string title2; | 1501 std::string title2; |
| 1444 SyncAPINameToServerName(raw_title2, &title2); | 1502 SyncAPINameToServerName(raw_title2, &title2); |
| 1445 std::string url2 = "http://www.bla.com"; | 1503 std::string url2 = "http://www.bla.com"; |
| 1446 | 1504 |
| 1447 // Create a bookmark using the legacy format. | 1505 // Create a bookmark using the legacy format. |
| 1448 int64 node_id1 = MakeNode(sync_manager_.GetUserShare(), | 1506 int64 node_id1 = MakeNode(sync_manager_.GetUserShare(), |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1530 EXPECT_TRUE(node2.InitByIdLookup(node_id2)); | 1588 EXPECT_TRUE(node2.InitByIdLookup(node_id2)); |
| 1531 EXPECT_EQ(syncable::BOOKMARKS, node2.GetModelType()); | 1589 EXPECT_EQ(syncable::BOOKMARKS, node2.GetModelType()); |
| 1532 // We should de-canonicalize the title in GetTitle(), but the title in the | 1590 // We should de-canonicalize the title in GetTitle(), but the title in the |
| 1533 // specifics should be stored in the server legal form. | 1591 // specifics should be stored in the server legal form. |
| 1534 EXPECT_EQ(raw_title2, node2.GetTitle()); | 1592 EXPECT_EQ(raw_title2, node2.GetTitle()); |
| 1535 EXPECT_EQ(title2, node2.GetBookmarkSpecifics().title()); | 1593 EXPECT_EQ(title2, node2.GetBookmarkSpecifics().title()); |
| 1536 EXPECT_EQ(url2, node2.GetBookmarkSpecifics().url()); | 1594 EXPECT_EQ(url2, node2.GetBookmarkSpecifics().url()); |
| 1537 } | 1595 } |
| 1538 } | 1596 } |
| 1539 | 1597 |
| 1598 // Verifies WriteNode::UpdateEntryWithEncryption does not make unnecessary |
| 1599 // changes. |
| 1600 TEST_F(SyncManagerTest, UpdateEntryWithEncryption) { |
| 1601 std::string client_tag = "title"; |
| 1602 sync_pb::EntitySpecifics entity_specifics; |
| 1603 entity_specifics.MutableExtension(sync_pb::bookmark)->set_url("url"); |
| 1604 entity_specifics.MutableExtension(sync_pb::bookmark)->set_title("title"); |
| 1605 MakeServerNode(sync_manager_.GetUserShare(), syncable::BOOKMARKS, client_tag, |
| 1606 BaseNode::GenerateSyncableHash(syncable::BOOKMARKS, |
| 1607 client_tag), |
| 1608 entity_specifics); |
| 1609 // New node shouldn't start off unsynced. |
| 1610 EXPECT_FALSE(ResetUnsyncedEntry(syncable::BOOKMARKS, client_tag)); |
| 1611 // Manually change to the same data. Should not set is_unsynced. |
| 1612 { |
| 1613 WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1614 WriteNode node(&trans); |
| 1615 EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS, client_tag)); |
| 1616 node.SetEntitySpecifics(entity_specifics); |
| 1617 } |
| 1618 EXPECT_FALSE(ResetUnsyncedEntry(syncable::BOOKMARKS, client_tag)); |
| 1619 // Encrypt the datatatype, should set is_unsynced. |
| 1620 EXPECT_CALL(observer_, |
| 1621 OnEncryptedTypesChanged(GetAllRealModelTypes(), true)); |
| 1622 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1623 EXPECT_TRUE(SetUpEncryption(true, true)); |
| 1624 sync_manager_.RefreshEncryption(); |
| 1625 { |
| 1626 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1627 ReadNode node(&trans); |
| 1628 EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS, client_tag)); |
| 1629 const syncable::Entry* node_entry = node.GetEntry(); |
| 1630 const sync_pb::EntitySpecifics& specifics = node_entry->Get(SPECIFICS); |
| 1631 EXPECT_TRUE(specifics.has_encrypted()); |
| 1632 EXPECT_EQ(kEncryptedString, node_entry->Get(NON_UNIQUE_NAME)); |
| 1633 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 1634 EXPECT_TRUE(cryptographer->is_ready()); |
| 1635 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
| 1636 specifics.encrypted())); |
| 1637 } |
| 1638 EXPECT_TRUE(ResetUnsyncedEntry(syncable::BOOKMARKS, client_tag)); |
| 1639 // Set a new passphrase. Should set is_unsynced. |
| 1640 testing::Mock::VerifyAndClearExpectations(&observer_); |
| 1641 EXPECT_CALL(observer_, OnPassphraseAccepted(_)); |
| 1642 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1643 sync_manager_.SetPassphrase("new_passphrase", true); |
| 1644 { |
| 1645 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1646 ReadNode node(&trans); |
| 1647 EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS, client_tag)); |
| 1648 const syncable::Entry* node_entry = node.GetEntry(); |
| 1649 const sync_pb::EntitySpecifics& specifics = node_entry->Get(SPECIFICS); |
| 1650 EXPECT_TRUE(specifics.has_encrypted()); |
| 1651 EXPECT_EQ(kEncryptedString, node_entry->Get(NON_UNIQUE_NAME)); |
| 1652 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 1653 EXPECT_TRUE(cryptographer->is_ready()); |
| 1654 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
| 1655 specifics.encrypted())); |
| 1656 } |
| 1657 EXPECT_TRUE(ResetUnsyncedEntry(syncable::BOOKMARKS, client_tag)); |
| 1658 // Force a re-encrypt everything. Should not set is_unsynced. |
| 1659 testing::Mock::VerifyAndClearExpectations(&observer_); |
| 1660 EXPECT_CALL(observer_, OnEncryptionComplete()); |
| 1661 sync_manager_.RefreshEncryption(); |
| 1662 { |
| 1663 ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1664 ReadNode node(&trans); |
| 1665 EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS, client_tag)); |
| 1666 const syncable::Entry* node_entry = node.GetEntry(); |
| 1667 const sync_pb::EntitySpecifics& specifics = node_entry->Get(SPECIFICS); |
| 1668 EXPECT_TRUE(specifics.has_encrypted()); |
| 1669 EXPECT_EQ(kEncryptedString, node_entry->Get(NON_UNIQUE_NAME)); |
| 1670 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 1671 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
| 1672 specifics.encrypted())); |
| 1673 } |
| 1674 EXPECT_FALSE(ResetUnsyncedEntry(syncable::BOOKMARKS, client_tag)); |
| 1675 // Manually change to the same data. Should not set is_unsynced. |
| 1676 { |
| 1677 WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1678 WriteNode node(&trans); |
| 1679 EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS, client_tag)); |
| 1680 node.SetEntitySpecifics(entity_specifics); |
| 1681 const syncable::Entry* node_entry = node.GetEntry(); |
| 1682 const sync_pb::EntitySpecifics& specifics = node_entry->Get(SPECIFICS); |
| 1683 EXPECT_TRUE(specifics.has_encrypted()); |
| 1684 EXPECT_FALSE(node_entry->Get(IS_UNSYNCED)); |
| 1685 EXPECT_EQ(kEncryptedString, node_entry->Get(NON_UNIQUE_NAME)); |
| 1686 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 1687 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
| 1688 specifics.encrypted())); |
| 1689 } |
| 1690 EXPECT_FALSE(ResetUnsyncedEntry(syncable::BOOKMARKS, client_tag)); |
| 1691 // Manually change to different data. Should set is_unsynced. |
| 1692 { |
| 1693 entity_specifics.MutableExtension(sync_pb::bookmark)->set_url("url2"); |
| 1694 entity_specifics.MutableExtension(sync_pb::bookmark)->set_title("title2"); |
| 1695 WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| 1696 WriteNode node(&trans); |
| 1697 EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS, client_tag)); |
| 1698 node.SetEntitySpecifics(entity_specifics); |
| 1699 const syncable::Entry* node_entry = node.GetEntry(); |
| 1700 const sync_pb::EntitySpecifics& specifics = node_entry->Get(SPECIFICS); |
| 1701 EXPECT_TRUE(specifics.has_encrypted()); |
| 1702 EXPECT_TRUE(node_entry->Get(IS_UNSYNCED)); |
| 1703 EXPECT_EQ(kEncryptedString, node_entry->Get(NON_UNIQUE_NAME)); |
| 1704 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 1705 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
| 1706 specifics.encrypted())); |
| 1707 } |
| 1708 } |
| 1709 |
| 1540 } // namespace browser_sync | 1710 } // namespace browser_sync |
| OLD | NEW |