Chromium Code Reviews| Index: components/sync/core_impl/sync_manager_impl_unittest.cc |
| diff --git a/components/sync/core_impl/sync_manager_impl_unittest.cc b/components/sync/core_impl/sync_manager_impl_unittest.cc |
| index 5ff5a15fa9e4ccc39336916fc3d738076eb32599..e6b1ffbabd053579fc35426781b52191bd39c600 100644 |
| --- a/components/sync/core_impl/sync_manager_impl_unittest.cc |
| +++ b/components/sync/core_impl/sync_manager_impl_unittest.cc |
| @@ -20,6 +20,7 @@ |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/format_macros.h" |
| #include "base/location.h" |
| +#include "base/metrics/field_trial.h" |
| #include "base/run_loop.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/stringprintf.h" |
| @@ -39,6 +40,7 @@ |
| #include "components/sync/core/http_post_provider_interface.h" |
| #include "components/sync/core/read_node.h" |
| #include "components/sync/core/read_transaction.h" |
| +#include "components/sync/core/sync_features.h" |
| #include "components/sync/core/test/test_entry_factory.h" |
| #include "components/sync/core/test/test_internal_components_factory.h" |
| #include "components/sync/core/test/test_user_share.h" |
| @@ -510,10 +512,14 @@ TEST_F(SyncApiTest, TestDeleteBehavior) { |
| TEST_F(SyncApiTest, WriteAndReadPassword) { |
| KeyParams params = {"localhost", "username", "passphrase"}; |
| + base::FeatureList::ClearInstanceForTesting(); |
| + EXPECT_FALSE(base::FeatureList::IsEnabled(kFillPasswordMetadata)); |
| + |
| { |
| ReadTransaction trans(FROM_HERE, user_share()); |
| trans.GetCryptographer()->AddKey(params); |
| } |
| + |
| { |
| WriteTransaction trans(FROM_HERE, user_share()); |
| ReadNode root_node(&trans); |
| @@ -536,13 +542,59 @@ TEST_F(SyncApiTest, WriteAndReadPassword) { |
| const sync_pb::PasswordSpecificsData& data = |
| password_node.GetPasswordSpecifics(); |
| EXPECT_EQ(kPasswordValue, data.password_value()); |
| - // Check that nothing has appeared in the unencrypted field. |
| + // Check that when feature is disabled nothing appears in the unencrypted |
| + // field. |
| EXPECT_FALSE(password_node.GetEntitySpecifics() |
| .password() |
| .has_unencrypted_metadata()); |
| } |
| } |
| +TEST_F(SyncApiTest, WritePasswordAndCheckMetadata) { |
| + KeyParams params = {"localhost", "username", "passphrase"}; |
| + { |
| + ReadTransaction trans(FROM_HERE, user_share()); |
| + trans.GetCryptographer()->AddKey(params); |
| + } |
| + |
| + base::FeatureList::ClearInstanceForTesting(); |
| + base::FieldTrialList field_trial_list(nullptr); |
| + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| + feature_list->InitializeFromCommandLine(kFillPasswordMetadata.name, |
| + std::string()); |
| + base::FeatureList::SetInstance(std::move(feature_list)); |
| + |
| + EXPECT_TRUE(base::FeatureList::IsEnabled(kFillPasswordMetadata)); |
| + { |
| + WriteTransaction trans(FROM_HERE, user_share()); |
| + ReadNode root_node(&trans); |
| + root_node.InitByRootLookup(); |
| + |
| + WriteNode password_node(&trans); |
| + WriteNode::InitUniqueByCreationResult result = |
| + password_node.InitUniqueByCreation(PASSWORDS, root_node, kClientTag); |
| + EXPECT_EQ(WriteNode::INIT_SUCCESS, result); |
| + sync_pb::PasswordSpecificsData data; |
| + data.set_password_value(kPasswordValue); |
| + data.set_signon_realm(kUrl); |
| + password_node.SetPasswordSpecifics(data); |
| + } |
| + { |
| + ReadTransaction trans(FROM_HERE, user_share()); |
| + |
| + ReadNode password_node(&trans); |
| + EXPECT_EQ(BaseNode::INIT_OK, |
| + password_node.InitByClientTagLookup(PASSWORDS, kClientTag)); |
| + const sync_pb::PasswordSpecificsData& data = |
| + password_node.GetPasswordSpecifics(); |
| + EXPECT_EQ(kPasswordValue, data.password_value()); |
| + EXPECT_EQ(kUrl, password_node.GetEntitySpecifics() |
| + .password() |
| + .unencrypted_metadata() |
| + .url()); |
| + } |
| +} |
| + |
| TEST_F(SyncApiTest, WriteEncryptedTitle) { |
| KeyParams params = {"localhost", "username", "passphrase"}; |
| { |
| @@ -2055,6 +2107,12 @@ TEST_F(SyncManagerTest, UpdatePasswordSetPasswordSpecifics) { |
| TEST_F(SyncManagerTest, UpdatePasswordNewPassphrase) { |
| EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); |
| sync_pb::EntitySpecifics entity_specifics; |
| + base::FeatureList::ClearInstanceForTesting(); |
| + base::FieldTrialList field_trial_list(nullptr); |
| + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| + feature_list->InitializeFromCommandLine(kFillPasswordMetadata.name, |
| + std::string()); |
| + base::FeatureList::SetInstance(std::move(feature_list)); |
| { |
| ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| Cryptographer* cryptographer = trans.GetCryptographer(); |
| @@ -2094,12 +2152,44 @@ TEST_F(SyncManagerTest, UpdatePasswordNewPassphrase) { |
| .has_unencrypted_metadata()); |
| } |
| EXPECT_TRUE(ResetUnsyncedEntry(PASSWORDS, kClientTag)); |
| + // Check that writing new password doesn't set the metadata. |
|
Nicolas Zea
2016/10/04 20:58:11
nit: newline above
melandory
2016/10/18 08:35:20
Done.
|
| + const std::string tag = "newpassentity"; |
| + { |
| + WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| + ReadNode root_node(&trans); |
| + root_node.InitByRootLookup(); |
| + |
| + WriteNode password_node(&trans); |
| + WriteNode::InitUniqueByCreationResult result = |
| + password_node.InitUniqueByCreation(PASSWORDS, root_node, tag); |
| + EXPECT_EQ(WriteNode::INIT_SUCCESS, result); |
| + sync_pb::PasswordSpecificsData data; |
| + data.set_password_value(kPasswordValue); |
| + data.set_signon_realm(kUrl); |
| + password_node.SetPasswordSpecifics(data); |
| + } |
| + { |
| + ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| + Cryptographer* cryptographer = trans.GetCryptographer(); |
| + EXPECT_TRUE(cryptographer->is_ready()); |
| + ReadNode password_node(&trans); |
| + EXPECT_EQ(BaseNode::INIT_OK, |
| + password_node.InitByClientTagLookup(PASSWORDS, tag)); |
| + const sync_pb::PasswordSpecificsData& data = |
| + password_node.GetPasswordSpecifics(); |
| + EXPECT_EQ(kPasswordValue, data.password_value()); |
| + EXPECT_FALSE(password_node.GetEntitySpecifics() |
| + .password() |
| + .has_unencrypted_metadata()); |
| + } |
| } |
| // Passwords have their own handling for encryption. Verify it does not result |
| // in unnecessary writes via ReencryptEverything. |
| TEST_F(SyncManagerTest, UpdatePasswordReencryptEverything) { |
| - std::string client_tag = "title"; |
| + base::FeatureList::ClearInstanceForTesting(); |
| + EXPECT_FALSE(base::FeatureList::IsEnabled(kFillPasswordMetadata)); |
| + |
| EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); |
| sync_pb::EntitySpecifics entity_specifics; |
| { |
| @@ -2110,11 +2200,11 @@ TEST_F(SyncManagerTest, UpdatePasswordReencryptEverything) { |
| cryptographer->Encrypt( |
| data, entity_specifics.mutable_password()->mutable_encrypted()); |
| } |
| - MakeServerNode(sync_manager_.GetUserShare(), PASSWORDS, client_tag, |
| - syncable::GenerateSyncableHash(PASSWORDS, client_tag), |
| + MakeServerNode(sync_manager_.GetUserShare(), PASSWORDS, kClientTag, |
| + syncable::GenerateSyncableHash(PASSWORDS, kClientTag), |
| entity_specifics); |
| // New node shouldn't start off unsynced. |
| - EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, client_tag)); |
| + EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, kClientTag)); |
| // Force a re-encrypt everything. Should not set is_unsynced. |
| testing::Mock::VerifyAndClearExpectations(&encryption_observer_); |
| @@ -2123,7 +2213,101 @@ TEST_F(SyncManagerTest, UpdatePasswordReencryptEverything) { |
| EXPECT_CALL(encryption_observer_, OnEncryptedTypesChanged(_, false)); |
| sync_manager_.GetEncryptionHandler()->Init(); |
| PumpLoop(); |
| - EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, client_tag)); |
| + EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, kClientTag)); |
| +} |
| + |
| +// Metadata filling can happen during ReencryptEverything, check that data is |
| +// written when it's applicable, namely that password specifics entity is marked |
| +// unsynced, when data was written to the unencrypted metadata field. |
| +TEST_F(SyncManagerTest, UpdatePasswordReencryptEverythingFillMetadata) { |
| + base::FeatureList::ClearInstanceForTesting(); |
| + base::FieldTrialList field_trial_list(nullptr); |
| + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| + feature_list->InitializeFromCommandLine(kFillPasswordMetadata.name, |
| + std::string()); |
| + base::FeatureList::SetInstance(std::move(feature_list)); |
| + EXPECT_TRUE(base::FeatureList::IsEnabled(kFillPasswordMetadata)); |
| + |
| + EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); |
| + sync_pb::EntitySpecifics entity_specifics; |
| + { |
| + ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| + Cryptographer* cryptographer = trans.GetCryptographer(); |
| + sync_pb::PasswordSpecificsData data; |
| + data.set_password_value("secret"); |
| + data.set_signon_realm(kUrl); |
| + cryptographer->Encrypt( |
| + data, entity_specifics.mutable_password()->mutable_encrypted()); |
| + } |
| + MakeServerNode(sync_manager_.GetUserShare(), PASSWORDS, kClientTag, |
| + syncable::GenerateSyncableHash(PASSWORDS, kClientTag), |
| + entity_specifics); |
| + // New node shouldn't start off unsynced. |
| + EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, kClientTag)); |
| + |
| + // Force a re-encrypt everything. Should set is_unsynced. |
| + testing::Mock::VerifyAndClearExpectations(&encryption_observer_); |
| + EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); |
| + EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); |
| + EXPECT_CALL(encryption_observer_, OnEncryptedTypesChanged(_, false)); |
| + sync_manager_.GetEncryptionHandler()->Init(); |
| + PumpLoop(); |
| + // Check that unencrypted metadata field was set. |
| + { |
| + ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| + Cryptographer* cryptographer = trans.GetCryptographer(); |
| + EXPECT_TRUE(cryptographer->is_ready()); |
| + ReadNode password_node(&trans); |
| + EXPECT_EQ(BaseNode::INIT_OK, |
| + password_node.InitByClientTagLookup(PASSWORDS, kClientTag)); |
| + EXPECT_EQ(kUrl, password_node.GetEntitySpecifics() |
| + .password() |
| + .unencrypted_metadata() |
| + .url()); |
| + } |
| + |
| + EXPECT_TRUE(ResetUnsyncedEntry(PASSWORDS, kClientTag)); |
| +} |
| + |
| +// Check that when the data in PasswordSpecifics hasn't changed during |
| +// ReEncryption, entity is not marked as unsynced. |
| +TEST_F(SyncManagerTest, |
| + UpdatePasswordReencryptEverythingDontMarkUnsyncWhenNotNeeded) { |
| + base::FeatureList::ClearInstanceForTesting(); |
| + base::FieldTrialList field_trial_list(nullptr); |
| + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| + feature_list->InitializeFromCommandLine(kFillPasswordMetadata.name, |
| + std::string()); |
| + base::FeatureList::SetInstance(std::move(feature_list)); |
| + EXPECT_TRUE(base::FeatureList::IsEnabled(kFillPasswordMetadata)); |
| + |
| + EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); |
| + sync_pb::EntitySpecifics entity_specifics; |
| + { |
| + ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); |
| + Cryptographer* cryptographer = trans.GetCryptographer(); |
| + sync_pb::PasswordSpecificsData data; |
| + data.set_password_value("secret"); |
| + data.set_signon_realm(kUrl); |
| + cryptographer->Encrypt( |
| + data, entity_specifics.mutable_password()->mutable_encrypted()); |
| + } |
| + entity_specifics.mutable_password()->mutable_unencrypted_metadata()->set_url( |
| + kUrl); |
| + MakeServerNode(sync_manager_.GetUserShare(), PASSWORDS, kClientTag, |
| + syncable::GenerateSyncableHash(PASSWORDS, kClientTag), |
| + entity_specifics); |
| + // New node shouldn't start off unsynced. |
| + EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, kClientTag)); |
| + |
| + // Force a re-encrypt everything. Should not set is_unsynced. |
| + testing::Mock::VerifyAndClearExpectations(&encryption_observer_); |
| + EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); |
| + EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); |
| + EXPECT_CALL(encryption_observer_, OnEncryptedTypesChanged(_, false)); |
| + sync_manager_.GetEncryptionHandler()->Init(); |
| + PumpLoop(); |
| + EXPECT_FALSE(ResetUnsyncedEntry(PASSWORDS, kClientTag)); |
| } |
| // Test that attempting to start up with corrupted password data triggers |