Index: sync/engine/apply_control_data_updates_unittest.cc |
diff --git a/sync/engine/apply_control_data_updates_unittest.cc b/sync/engine/apply_control_data_updates_unittest.cc |
deleted file mode 100644 |
index 39acb214e55320f74e3596e6fd9ae0c5b3e6e3ed..0000000000000000000000000000000000000000 |
--- a/sync/engine/apply_control_data_updates_unittest.cc |
+++ /dev/null |
@@ -1,974 +0,0 @@ |
-// Copyright 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "sync/engine/apply_control_data_updates.h" |
- |
-#include <stddef.h> |
-#include <stdint.h> |
- |
-#include <memory> |
-#include <string> |
- |
-#include "base/format_macros.h" |
-#include "base/location.h" |
-#include "base/macros.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/strings/stringprintf.h" |
-#include "sync/engine/syncer.h" |
-#include "sync/engine/syncer_util.h" |
-#include "sync/internal_api/public/test/test_entry_factory.h" |
-#include "sync/protocol/nigori_specifics.pb.h" |
-#include "sync/syncable/directory.h" |
-#include "sync/syncable/mutable_entry.h" |
-#include "sync/syncable/nigori_util.h" |
-#include "sync/syncable/syncable_read_transaction.h" |
-#include "sync/syncable/syncable_util.h" |
-#include "sync/syncable/syncable_write_transaction.h" |
-#include "sync/test/engine/fake_model_worker.h" |
-#include "sync/test/engine/test_directory_setter_upper.h" |
-#include "sync/test/engine/test_id_factory.h" |
-#include "sync/test/fake_sync_encryption_handler.h" |
-#include "sync/util/cryptographer.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace syncer { |
- |
-using syncable::MutableEntry; |
-using syncable::UNITTEST; |
-using syncable::Id; |
- |
-class ApplyControlDataUpdatesTest : public ::testing::Test { |
- public: |
- protected: |
- ApplyControlDataUpdatesTest() {} |
- ~ApplyControlDataUpdatesTest() override {} |
- |
- void SetUp() override { |
- dir_maker_.SetUp(); |
- entry_factory_.reset(new TestEntryFactory(directory())); |
- } |
- |
- void TearDown() override { dir_maker_.TearDown(); } |
- |
- syncable::Directory* directory() { |
- return dir_maker_.directory(); |
- } |
- |
- TestIdFactory id_factory_; |
- std::unique_ptr<TestEntryFactory> entry_factory_; |
- |
- private: |
- base::MessageLoop loop_; // Needed for directory init. |
- TestDirectorySetterUpper dir_maker_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ApplyControlDataUpdatesTest); |
-}; |
- |
-// Verify that applying a nigori node sets initial sync ended properly, |
-// updates the set of encrypted types, and updates the cryptographer. |
-TEST_F(ApplyControlDataUpdatesTest, NigoriUpdate) { |
- // Storing the cryptographer separately is bad, but for this test we |
- // know it's safe. |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types; |
- encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes()); |
- |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
- |
- // Nigori node updates should update the Cryptographer. |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- KeyParams params = {"localhost", "dummy", "foobar"}; |
- other_cryptographer.AddKey(params); |
- |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(nigori->mutable_encryption_keybag()); |
- nigori->set_encrypt_everything(true); |
- entry_factory_->CreateUnappliedNewItem( |
- ModelTypeToRootTag(NIGORI), specifics, true); |
- EXPECT_FALSE(cryptographer->has_pending_keys()); |
- |
- ApplyControlDataUpdates(directory()); |
- |
- EXPECT_FALSE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->has_pending_keys()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
-} |
- |
-// Create some local unsynced and unencrypted data. Apply a nigori update that |
-// turns on encryption for the unsynced data. Ensure we properly encrypt the |
-// data as part of the nigori update. Apply another nigori update with no |
-// changes. Ensure we ignore already-encrypted unsynced data and that nothing |
-// breaks. |
-TEST_F(ApplyControlDataUpdatesTest, EncryptUnsyncedChanges) { |
- // Storing the cryptographer separately is bad, but for this test we |
- // know it's safe. |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types; |
- encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- |
- // With default encrypted_types, this should be true. |
- EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
- |
- Syncer::UnsyncedMetaHandles handles; |
- GetUnsyncedEntries(&trans, &handles); |
- EXPECT_TRUE(handles.empty()); |
- } |
- |
- // Create unsynced bookmarks without encryption. |
- // First item is a folder |
- Id folder_id = id_factory_.NewLocalId(); |
- entry_factory_->CreateUnsyncedItem(folder_id, id_factory_.root(), "folder", |
- true, BOOKMARKS, NULL); |
- // Next five items are children of the folder |
- size_t i; |
- size_t batch_s = 5; |
- for (i = 0; i < batch_s; ++i) { |
- entry_factory_->CreateUnsyncedItem(id_factory_.NewLocalId(), folder_id, |
- base::StringPrintf("Item %" PRIuS "", i), |
- false, BOOKMARKS, NULL); |
- } |
- // Next five items are children of the root. |
- for (; i < 2*batch_s; ++i) { |
- entry_factory_->CreateUnsyncedItem( |
- id_factory_.NewLocalId(), id_factory_.root(), |
- base::StringPrintf("Item %" PRIuS "", i), false, |
- BOOKMARKS, NULL); |
- } |
- |
- KeyParams params = {"localhost", "dummy", "foobar"}; |
- cryptographer->AddKey(params); |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
- cryptographer->GetKeys(nigori->mutable_encryption_keybag()); |
- nigori->set_encrypt_everything(true); |
- encrypted_types.Put(BOOKMARKS); |
- entry_factory_->CreateUnappliedNewItem( |
- ModelTypeToRootTag(NIGORI), specifics, true); |
- EXPECT_FALSE(cryptographer->has_pending_keys()); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- { |
- // Ensure we have unsynced nodes that aren't properly encrypted. |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
- |
- Syncer::UnsyncedMetaHandles handles; |
- GetUnsyncedEntries(&trans, &handles); |
- EXPECT_EQ(2*batch_s+1, handles.size()); |
- } |
- |
- ApplyControlDataUpdates(directory()); |
- |
- EXPECT_FALSE(cryptographer->has_pending_keys()); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- |
- // If ProcessUnsyncedChangesForEncryption worked, all our unsynced changes |
- // should be encrypted now. |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
- |
- Syncer::UnsyncedMetaHandles handles; |
- GetUnsyncedEntries(&trans, &handles); |
- EXPECT_EQ(2*batch_s+1, handles.size()); |
- } |
- |
- // Simulate another nigori update that doesn't change anything. |
- { |
- syncable::WriteTransaction trans(FROM_HERE, UNITTEST, directory()); |
- MutableEntry entry(&trans, syncable::GET_TYPE_ROOT, NIGORI); |
- ASSERT_TRUE(entry.good()); |
- entry.PutServerVersion(entry_factory_->GetNextRevision()); |
- entry.PutIsUnappliedUpdate(true); |
- } |
- |
- ApplyControlDataUpdates(directory()); |
- |
- EXPECT_FALSE(cryptographer->has_pending_keys()); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- |
- // All our changes should still be encrypted. |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
- |
- Syncer::UnsyncedMetaHandles handles; |
- GetUnsyncedEntries(&trans, &handles); |
- EXPECT_EQ(2*batch_s+1, handles.size()); |
- } |
-} |
- |
-// Create some local unsynced and unencrypted changes. Receive a new nigori |
-// node enabling their encryption but also introducing pending keys. Ensure |
-// we apply the update properly without encrypting the unsynced changes or |
-// breaking. |
-TEST_F(ApplyControlDataUpdatesTest, CannotEncryptUnsyncedChanges) { |
- // Storing the cryptographer separately is bad, but for this test we |
- // know it's safe. |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types; |
- encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- |
- // With default encrypted_types, this should be true. |
- EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
- |
- Syncer::UnsyncedMetaHandles handles; |
- GetUnsyncedEntries(&trans, &handles); |
- EXPECT_TRUE(handles.empty()); |
- } |
- |
- // Create unsynced bookmarks without encryption. |
- // First item is a folder |
- Id folder_id = id_factory_.NewLocalId(); |
- entry_factory_->CreateUnsyncedItem( |
- folder_id, id_factory_.root(), "folder", true, |
- BOOKMARKS, NULL); |
- // Next five items are children of the folder |
- size_t i; |
- size_t batch_s = 5; |
- for (i = 0; i < batch_s; ++i) { |
- entry_factory_->CreateUnsyncedItem(id_factory_.NewLocalId(), folder_id, |
- base::StringPrintf("Item %" PRIuS "", i), |
- false, BOOKMARKS, NULL); |
- } |
- // Next five items are children of the root. |
- for (; i < 2*batch_s; ++i) { |
- entry_factory_->CreateUnsyncedItem( |
- id_factory_.NewLocalId(), id_factory_.root(), |
- base::StringPrintf("Item %" PRIuS "", i), false, |
- BOOKMARKS, NULL); |
- } |
- |
- // We encrypt with new keys, triggering the local cryptographer to be unready |
- // and unable to decrypt data (once updated). |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- KeyParams params = {"localhost", "dummy", "foobar"}; |
- other_cryptographer.AddKey(params); |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(nigori->mutable_encryption_keybag()); |
- nigori->set_encrypt_everything(true); |
- encrypted_types.Put(BOOKMARKS); |
- entry_factory_->CreateUnappliedNewItem( |
- ModelTypeToRootTag(NIGORI), specifics, true); |
- EXPECT_FALSE(cryptographer->has_pending_keys()); |
- |
- { |
- // Ensure we have unsynced nodes that aren't properly encrypted. |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
- Syncer::UnsyncedMetaHandles handles; |
- GetUnsyncedEntries(&trans, &handles); |
- EXPECT_EQ(2*batch_s+1, handles.size()); |
- } |
- |
- ApplyControlDataUpdates(directory()); |
- |
- EXPECT_FALSE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->has_pending_keys()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- |
- // Since we have pending keys, we would have failed to encrypt, but the |
- // cryptographer should be updated. |
- EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- EXPECT_FALSE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->has_pending_keys()); |
- |
- Syncer::UnsyncedMetaHandles handles; |
- GetUnsyncedEntries(&trans, &handles); |
- EXPECT_EQ(2*batch_s+1, handles.size()); |
- } |
-} |
- |
-// Verify we handle a nigori node conflict by merging encryption keys and |
-// types, but preserve the custom passphrase state of the server. |
-// Initial sync ended should be set. |
-TEST_F(ApplyControlDataUpdatesTest, |
- NigoriConflictPendingKeysServerEncryptEverythingCustom) { |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); |
- KeyParams other_params = {"localhost", "dummy", "foobar"}; |
- KeyParams local_params = {"localhost", "dummy", "local"}; |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans), |
- encrypted_types); |
- } |
- |
- // Set up a temporary cryptographer to generate new keys with. |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- other_cryptographer.AddKey(other_params); |
- |
- // Create server specifics with pending keys, new encrypted types, |
- // and a custom passphrase (unmigrated). |
- sync_pb::EntitySpecifics server_specifics; |
- sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag()); |
- server_nigori->set_encrypt_everything(true); |
- server_nigori->set_keybag_is_frozen(true); |
- int64_t nigori_handle = entry_factory_->CreateUnappliedNewItem( |
- kNigoriTag, server_specifics, true); |
- |
- // Initialize the local cryptographer with the local keys. |
- cryptographer->AddKey(local_params); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- // Set up a local nigori with the local encryption keys and default encrypted |
- // types. |
- sync_pb::EntitySpecifics local_specifics; |
- sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori(); |
- cryptographer->GetKeys(local_nigori->mutable_encryption_keybag()); |
- local_nigori->set_encrypt_everything(false); |
- local_nigori->set_keybag_is_frozen(true); |
- ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem( |
- nigori_handle, local_specifics)); |
- // Apply the update locally so that UpdateFromEncryptedTypes knows what state |
- // to use. |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- directory()->GetNigoriHandler()->ApplyNigoriUpdate( |
- *local_nigori, |
- &trans); |
- } |
- |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- ApplyControlDataUpdates(directory()); |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- |
- EXPECT_FALSE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->is_initialized()); |
- EXPECT_TRUE(cryptographer->has_pending_keys()); |
- EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().keybag_is_frozen()); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encrypt_everything()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
-} |
- |
-// Verify we handle a nigori node conflict by merging encryption keys and |
-// types, but preserve the custom passphrase state of the server. |
-// Initial sync ended should be set. |
-TEST_F(ApplyControlDataUpdatesTest, |
- NigoriConflictPendingKeysLocalEncryptEverythingCustom) { |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); |
- KeyParams other_params = {"localhost", "dummy", "foobar"}; |
- KeyParams local_params = {"localhost", "dummy", "local"}; |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
- |
- // Set up a temporary cryptographer to generate new keys with. |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- other_cryptographer.AddKey(other_params); |
- |
- // Create server specifics with pending keys, new encrypted types, |
- // and a custom passphrase (unmigrated). |
- sync_pb::EntitySpecifics server_specifics; |
- sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag()); |
- server_nigori->set_encrypt_everything(false); |
- server_nigori->set_keybag_is_frozen(false); |
- int64_t nigori_handle = entry_factory_->CreateUnappliedNewItem( |
- kNigoriTag, server_specifics, true); |
- |
- // Initialize the local cryptographer with the local keys. |
- cryptographer->AddKey(local_params); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- // Set up a local nigori with the local encryption keys and default encrypted |
- // types. |
- sync_pb::EntitySpecifics local_specifics; |
- sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori(); |
- cryptographer->GetKeys(local_nigori->mutable_encryption_keybag()); |
- local_nigori->set_encrypt_everything(true); |
- local_nigori->set_keybag_is_frozen(true); |
- ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem( |
- nigori_handle, local_specifics)); |
- // Apply the update locally so that UpdateFromEncryptedTypes knows what state |
- // to use. |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- directory()->GetNigoriHandler()->ApplyNigoriUpdate( |
- *local_nigori, |
- &trans); |
- } |
- |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- ApplyControlDataUpdates(directory()); |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- |
- EXPECT_FALSE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->is_initialized()); |
- EXPECT_TRUE(cryptographer->has_pending_keys()); |
- EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_FALSE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().keybag_is_frozen()); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encrypt_everything()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
-} |
- |
-// If the conflicting nigori has a subset of the local keys, the conflict |
-// resolution should preserve the full local keys. Initial sync ended should be |
-// set. |
-TEST_F(ApplyControlDataUpdatesTest, |
- NigoriConflictOldKeys) { |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); |
- KeyParams old_params = {"localhost", "dummy", "old"}; |
- KeyParams new_params = {"localhost", "dummy", "new"}; |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
- |
- // Set up the cryptographer with old keys |
- cryptographer->AddKey(old_params); |
- |
- // Create server specifics with old keys and new encrypted types. |
- sync_pb::EntitySpecifics server_specifics; |
- sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori(); |
- cryptographer->GetKeys(server_nigori->mutable_encryption_keybag()); |
- server_nigori->set_encrypt_everything(true); |
- int64_t nigori_handle = entry_factory_->CreateUnappliedNewItem( |
- kNigoriTag, server_specifics, true); |
- |
- // Add the new keys to the cryptogrpaher |
- cryptographer->AddKey(new_params); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- // Set up a local nigori with the superset of keys. |
- sync_pb::EntitySpecifics local_specifics; |
- sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori(); |
- cryptographer->GetKeys(local_nigori->mutable_encryption_keybag()); |
- local_nigori->set_encrypt_everything(false); |
- ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem( |
- nigori_handle, local_specifics)); |
- // Apply the update locally so that UpdateFromEncryptedTypes knows what state |
- // to use. |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- directory()->GetNigoriHandler()->ApplyNigoriUpdate( |
- *local_nigori, |
- &trans); |
- } |
- |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- ApplyControlDataUpdates(directory()); |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- |
- EXPECT_TRUE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_FALSE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().keybag_is_frozen()); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encrypt_everything()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
-} |
- |
-// If both nigoris are migrated, but we also set a custom passphrase locally, |
-// the local nigori should be preserved. |
-TEST_F(ApplyControlDataUpdatesTest, |
- NigoriConflictBothMigratedLocalCustom) { |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); |
- KeyParams old_params = {"localhost", "dummy", "old"}; |
- KeyParams new_params = {"localhost", "dummy", "new"}; |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
- |
- // Set up the cryptographer with new keys |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- other_cryptographer.AddKey(old_params); |
- |
- // Create server specifics with a migrated keystore passphrase type. |
- sync_pb::EntitySpecifics server_specifics; |
- sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag()); |
- server_nigori->set_encrypt_everything(false); |
- server_nigori->set_keybag_is_frozen(true); |
- server_nigori->set_passphrase_type( |
- sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); |
- server_nigori->mutable_keystore_decryptor_token(); |
- int64_t nigori_handle = entry_factory_->CreateUnappliedNewItem( |
- kNigoriTag, server_specifics, true); |
- |
- // Add the new keys to the cryptographer. |
- cryptographer->AddKey(old_params); |
- cryptographer->AddKey(new_params); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- // Set up a local nigori with a migrated custom passphrase type |
- sync_pb::EntitySpecifics local_specifics; |
- sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori(); |
- cryptographer->GetKeys(local_nigori->mutable_encryption_keybag()); |
- local_nigori->set_encrypt_everything(true); |
- local_nigori->set_keybag_is_frozen(true); |
- local_nigori->set_passphrase_type( |
- sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE); |
- ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem( |
- nigori_handle, local_specifics)); |
- // Apply the update locally so that UpdateFromEncryptedTypes knows what state |
- // to use. |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- directory()->GetNigoriHandler()->ApplyNigoriUpdate( |
- *local_nigori, |
- &trans); |
- } |
- |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- ApplyControlDataUpdates(directory()); |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- |
- EXPECT_TRUE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().keybag_is_frozen()); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encrypt_everything()); |
- EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE, |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().passphrase_type()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
-} |
- |
-// If both nigoris are migrated, but a custom passphrase with a new key was |
-// set remotely, the remote nigori should be preserved. |
-TEST_F(ApplyControlDataUpdatesTest, |
- NigoriConflictBothMigratedServerCustom) { |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); |
- KeyParams old_params = {"localhost", "dummy", "old"}; |
- KeyParams new_params = {"localhost", "dummy", "new"}; |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
- |
- // Set up the cryptographer with both new keys and old keys. |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- other_cryptographer.AddKey(old_params); |
- other_cryptographer.AddKey(new_params); |
- |
- // Create server specifics with a migrated custom passphrase type. |
- sync_pb::EntitySpecifics server_specifics; |
- sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag()); |
- server_nigori->set_encrypt_everything(true); |
- server_nigori->set_keybag_is_frozen(true); |
- server_nigori->set_passphrase_type( |
- sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE); |
- int64_t nigori_handle = entry_factory_->CreateUnappliedNewItem( |
- kNigoriTag, server_specifics, true); |
- |
- // Add the old keys to the cryptographer. |
- cryptographer->AddKey(old_params); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- // Set up a local nigori with a migrated keystore passphrase type |
- sync_pb::EntitySpecifics local_specifics; |
- sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori(); |
- cryptographer->GetKeys(local_nigori->mutable_encryption_keybag()); |
- local_nigori->set_encrypt_everything(false); |
- local_nigori->set_keybag_is_frozen(true); |
- local_nigori->set_passphrase_type( |
- sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); |
- server_nigori->mutable_keystore_decryptor_token(); |
- ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem( |
- nigori_handle, local_specifics)); |
- // Apply the update locally so that UpdateFromEncryptedTypes knows what state |
- // to use. |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- directory()->GetNigoriHandler()->ApplyNigoriUpdate( |
- *local_nigori, |
- &trans); |
- } |
- |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- ApplyControlDataUpdates(directory()); |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- |
- EXPECT_TRUE(cryptographer->is_initialized()); |
- EXPECT_TRUE(cryptographer->has_pending_keys()); |
- EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().keybag_is_frozen()); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encrypt_everything()); |
- EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE, |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().passphrase_type()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
-} |
- |
-// If the local nigori is migrated but the server is not, preserve the local |
-// nigori. |
-TEST_F(ApplyControlDataUpdatesTest, |
- NigoriConflictLocalMigrated) { |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); |
- KeyParams old_params = {"localhost", "dummy", "old"}; |
- KeyParams new_params = {"localhost", "dummy", "new"}; |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
- |
- // Set up the cryptographer with both new keys and old keys. |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- other_cryptographer.AddKey(old_params); |
- |
- // Create server specifics with an unmigrated implicit passphrase type. |
- sync_pb::EntitySpecifics server_specifics; |
- sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag()); |
- server_nigori->set_encrypt_everything(true); |
- server_nigori->set_keybag_is_frozen(false); |
- int64_t nigori_handle = entry_factory_->CreateUnappliedNewItem( |
- kNigoriTag, server_specifics, true); |
- |
- // Add the old keys to the cryptographer. |
- cryptographer->AddKey(old_params); |
- cryptographer->AddKey(new_params); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- // Set up a local nigori with a migrated custom passphrase type |
- sync_pb::EntitySpecifics local_specifics; |
- sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori(); |
- cryptographer->GetKeys(local_nigori->mutable_encryption_keybag()); |
- local_nigori->set_encrypt_everything(true); |
- local_nigori->set_keybag_is_frozen(true); |
- local_nigori->set_passphrase_type( |
- sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE); |
- ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem( |
- nigori_handle, local_specifics)); |
- // Apply the update locally so that UpdateFromEncryptedTypes knows what state |
- // to use. |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- directory()->GetNigoriHandler()->ApplyNigoriUpdate( |
- *local_nigori, |
- &trans); |
- } |
- |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- ApplyControlDataUpdates(directory()); |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- |
- EXPECT_TRUE(cryptographer->is_ready()); |
- EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().keybag_is_frozen()); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encrypt_everything()); |
- EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE, |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().passphrase_type()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- EXPECT_EQ(ModelTypeSet::All(), |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
-} |
- |
-// If the server nigori is migrated but the local is not, preserve the server |
-// nigori. |
-TEST_F(ApplyControlDataUpdatesTest, |
- NigoriConflictServerMigrated) { |
- Cryptographer* cryptographer; |
- ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); |
- KeyParams old_params = {"localhost", "dummy", "old"}; |
- KeyParams new_params = {"localhost", "dummy", "new"}; |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- EXPECT_EQ(encrypted_types, |
- directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); |
- } |
- |
- // Set up the cryptographer with both new keys and old keys. |
- Cryptographer other_cryptographer(cryptographer->encryptor()); |
- other_cryptographer.AddKey(old_params); |
- |
- // Create server specifics with an migrated keystore passphrase type. |
- sync_pb::EntitySpecifics server_specifics; |
- sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori(); |
- other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag()); |
- server_nigori->set_encrypt_everything(false); |
- server_nigori->set_keybag_is_frozen(true); |
- server_nigori->set_passphrase_type( |
- sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); |
- server_nigori->mutable_keystore_decryptor_token(); |
- int64_t nigori_handle = entry_factory_->CreateUnappliedNewItem( |
- kNigoriTag, server_specifics, true); |
- |
- // Add the old keys to the cryptographer. |
- cryptographer->AddKey(old_params); |
- cryptographer->AddKey(new_params); |
- EXPECT_TRUE(cryptographer->is_ready()); |
- |
- // Set up a local nigori with a migrated custom passphrase type |
- sync_pb::EntitySpecifics local_specifics; |
- sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori(); |
- cryptographer->GetKeys(local_nigori->mutable_encryption_keybag()); |
- local_nigori->set_encrypt_everything(false); |
- local_nigori->set_keybag_is_frozen(false); |
- ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem( |
- nigori_handle, local_specifics)); |
- // Apply the update locally so that UpdateFromEncryptedTypes knows what state |
- // to use. |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- directory()->GetNigoriHandler()->ApplyNigoriUpdate( |
- *local_nigori, |
- &trans); |
- } |
- |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- ApplyControlDataUpdates(directory()); |
- EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); |
- |
- EXPECT_TRUE(cryptographer->is_ready()); |
- // Note: we didn't overwrite the encryption keybag with the local keys. The |
- // sync encryption handler will do that when it detects that the new |
- // keybag is out of date (and update the keystore bootstrap if necessary). |
- EXPECT_FALSE(cryptographer->CanDecryptUsingDefaultKey( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_TRUE(cryptographer->CanDecrypt( |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().encryption_keybag())); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().keybag_is_frozen()); |
- EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().has_keystore_decryptor_token()); |
- EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE, |
- entry_factory_->GetLocalSpecificsForItem(nigori_handle). |
- nigori().passphrase_type()); |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- } |
-} |
- |
-// Check that we can apply a simple control datatype node successfully. |
-TEST_F(ApplyControlDataUpdatesTest, ControlApply) { |
- std::string experiment_id = "experiment"; |
- sync_pb::EntitySpecifics specifics; |
- specifics.mutable_experiments()->mutable_keystore_encryption()-> |
- set_enabled(true); |
- int64_t experiment_handle = |
- entry_factory_->CreateUnappliedNewItem(experiment_id, specifics, false); |
- ApplyControlDataUpdates(directory()); |
- |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(experiment_handle)); |
- EXPECT_TRUE( |
- entry_factory_->GetLocalSpecificsForItem(experiment_handle). |
- experiments().keystore_encryption().enabled()); |
-} |
- |
-// Verify that we apply top level folders before their children. |
-TEST_F(ApplyControlDataUpdatesTest, ControlApplyParentBeforeChild) { |
- std::string parent_id = "parent"; |
- std::string experiment_id = "experiment"; |
- sync_pb::EntitySpecifics specifics; |
- specifics.mutable_experiments()->mutable_keystore_encryption()-> |
- set_enabled(true); |
- int64_t experiment_handle = entry_factory_->CreateUnappliedNewItemWithParent( |
- experiment_id, specifics, parent_id); |
- int64_t parent_handle = |
- entry_factory_->CreateUnappliedNewItem(parent_id, specifics, true); |
- ApplyControlDataUpdates(directory()); |
- |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(parent_handle)); |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(experiment_handle)); |
- EXPECT_TRUE( |
- entry_factory_->GetLocalSpecificsForItem(experiment_handle). |
- experiments().keystore_encryption().enabled()); |
-} |
- |
-// Verify that we handle control datatype conflicts by preserving the server |
-// data. |
-TEST_F(ApplyControlDataUpdatesTest, ControlConflict) { |
- std::string experiment_id = "experiment"; |
- sync_pb::EntitySpecifics local_specifics, server_specifics; |
- server_specifics.mutable_experiments()->mutable_keystore_encryption()-> |
- set_enabled(true); |
- local_specifics.mutable_experiments()->mutable_keystore_encryption()-> |
- set_enabled(false); |
- int64_t experiment_handle = |
- entry_factory_->CreateSyncedItem(experiment_id, EXPERIMENTS, false); |
- entry_factory_->SetServerSpecificsForItem(experiment_handle, |
- server_specifics); |
- entry_factory_->SetLocalSpecificsForItem(experiment_handle, |
- local_specifics); |
- ApplyControlDataUpdates(directory()); |
- |
- EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(experiment_handle)); |
- EXPECT_TRUE( |
- entry_factory_->GetLocalSpecificsForItem(experiment_handle). |
- experiments().keystore_encryption().enabled()); |
-} |
- |
-// Check that applying a EXPERIMENTS update marks the datatype as downloaded. |
-TEST_F(ApplyControlDataUpdatesTest, ExperimentsApplyMarksDownloadCompleted) { |
- EXPECT_FALSE(directory()->InitialSyncEndedForType(EXPERIMENTS)); |
- |
- // Create root node for EXPERIMENTS datatype |
- { |
- syncable::WriteTransaction trans(FROM_HERE, UNITTEST, directory()); |
- syncable::ModelNeutralMutableEntry entry( |
- &trans, syncable::CREATE_NEW_TYPE_ROOT, EXPERIMENTS); |
- ASSERT_TRUE(entry.good()); |
- entry.PutServerIsDir(true); |
- entry.PutUniqueServerTag(ModelTypeToRootTag(EXPERIMENTS)); |
- } |
- |
- // Initial sync isn't marked as ended for EXPERIMENTS even though the |
- // root folder exists. |
- EXPECT_FALSE(directory()->InitialSyncEndedForType(EXPERIMENTS)); |
- |
- std::string experiment_id = "experiment"; |
- sync_pb::EntitySpecifics specifics; |
- specifics.mutable_experiments()->mutable_keystore_encryption()->set_enabled( |
- true); |
- entry_factory_->CreateUnappliedNewItem(experiment_id, specifics, false); |
- |
- ApplyControlDataUpdates(directory()); |
- |
- // After applying the updates EXPERIMENTS should be marked as having its |
- // initial sync completed. |
- EXPECT_TRUE(directory()->InitialSyncEndedForType(EXPERIMENTS)); |
- // Verify that there is no side effect on another control type. |
- EXPECT_FALSE(directory()->InitialSyncEndedForType(NIGORI)); |
-} |
- |
-// Check that applying a NIGORI update marks the datatype as downloaded. |
-TEST_F(ApplyControlDataUpdatesTest, NigoriApplyMarksDownloadCompleted) { |
- EXPECT_FALSE(directory()->InitialSyncEndedForType(NIGORI)); |
- |
- Cryptographer* cryptographer; |
- |
- { |
- syncable::ReadTransaction trans(FROM_HERE, directory()); |
- cryptographer = directory()->GetCryptographer(&trans); |
- } |
- |
- KeyParams params = {"localhost", "dummy", "foobar"}; |
- cryptographer->AddKey(params); |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
- cryptographer->GetKeys(nigori->mutable_encryption_keybag()); |
- nigori->set_encrypt_everything(true); |
- |
- entry_factory_->CreateUnappliedNewItem(ModelTypeToRootTag(NIGORI), specifics, |
- true); |
- |
- ApplyControlDataUpdates(directory()); |
- |
- // After applying the updates NIGORI should be marked as having its |
- // initial sync completed. |
- EXPECT_TRUE(directory()->InitialSyncEndedForType(NIGORI)); |
- // Verify that there is no side effect on another control type. |
- EXPECT_FALSE(directory()->InitialSyncEndedForType(EXPERIMENTS)); |
-} |
- |
-} // namespace syncer |