backend_migrator_unittest.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/sync/driver/backend_migrator.h"
  5. #include <memory>
  6. #include "base/run_loop.h"
  7. #include "base/test/mock_callback.h"
  8. #include "base/test/task_environment.h"
  9. #include "components/sync/base/model_type_test_util.h"
  10. #include "components/sync/driver/data_type_manager_mock.h"
  11. #include "testing/gmock/include/gmock/gmock.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. using ::testing::_;
  14. using ::testing::Eq;
  15. using ::testing::Mock;
  16. using ::testing::NiceMock;
  17. using ::testing::Return;
  18. namespace syncer {
  19. class SyncBackendMigratorTest : public testing::Test {
  20. public:
  21. SyncBackendMigratorTest() = default;
  22. ~SyncBackendMigratorTest() override = default;
  23. void SetUp() override {
  24. Mock::VerifyAndClear(manager());
  25. preferred_types_.Put(BOOKMARKS);
  26. preferred_types_.Put(PREFERENCES);
  27. preferred_types_.Put(AUTOFILL);
  28. migrator_ = std::make_unique<BackendMigrator>(
  29. "Profile0", manager(), reconfigure_callback()->Get(),
  30. migration_done_callback()->Get());
  31. SetUnsyncedTypes(ModelTypeSet());
  32. }
  33. void TearDown() override { migrator_.reset(); }
  34. // Marks all types in |unsynced_types| as unsynced and all other
  35. // types as synced.
  36. void SetUnsyncedTypes(ModelTypeSet unsynced_types) {
  37. ON_CALL(manager_, GetPurgedDataTypes())
  38. .WillByDefault(Return(unsynced_types));
  39. }
  40. void SendConfigureDone(DataTypeManager::ConfigureStatus status,
  41. ModelTypeSet requested_types) {
  42. if (status == DataTypeManager::OK) {
  43. DataTypeManager::ConfigureResult result(status, requested_types);
  44. migrator_->OnConfigureDone(result);
  45. } else {
  46. DataTypeManager::ConfigureResult result(status, requested_types);
  47. migrator_->OnConfigureDone(result);
  48. }
  49. base::RunLoop run_loop;
  50. run_loop.RunUntilIdle();
  51. }
  52. DataTypeManagerMock* manager() { return &manager_; }
  53. ModelTypeSet preferred_types() { return preferred_types_; }
  54. base::MockCallback<base::RepeatingClosure>* reconfigure_callback() {
  55. return &reconfigure_callback_;
  56. }
  57. base::MockCallback<base::RepeatingClosure>* migration_done_callback() {
  58. return &migration_done_callback_;
  59. }
  60. BackendMigrator* migrator() { return migrator_.get(); }
  61. private:
  62. base::test::SingleThreadTaskEnvironment task_environment_;
  63. ModelTypeSet preferred_types_;
  64. NiceMock<DataTypeManagerMock> manager_;
  65. NiceMock<base::MockCallback<base::RepeatingClosure>> reconfigure_callback_;
  66. NiceMock<base::MockCallback<base::RepeatingClosure>> migration_done_callback_;
  67. std::unique_ptr<BackendMigrator> migrator_;
  68. };
  69. class MockMigrationObserver : public MigrationObserver {
  70. public:
  71. ~MockMigrationObserver() override = default;
  72. MOCK_METHOD(void, OnMigrationStateChange, ());
  73. };
  74. // Test that in the normal case a migration does transition through each state
  75. // and wind up back in IDLE.
  76. TEST_F(SyncBackendMigratorTest, Sanity) {
  77. EXPECT_CALL(*migration_done_callback(), Run()).Times(0);
  78. MockMigrationObserver migration_observer;
  79. migrator()->AddMigrationObserver(&migration_observer);
  80. EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4);
  81. ModelTypeSet to_migrate, difference;
  82. to_migrate.Put(PREFERENCES);
  83. difference.Put(AUTOFILL);
  84. difference.Put(BOOKMARKS);
  85. EXPECT_CALL(*manager(), state())
  86. .WillOnce(Return(DataTypeManager::CONFIGURED));
  87. EXPECT_CALL(*manager(), PurgeForMigration);
  88. EXPECT_CALL(*reconfigure_callback(), Run());
  89. migrator()->MigrateTypes(to_migrate);
  90. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  91. SetUnsyncedTypes(to_migrate);
  92. SendConfigureDone(DataTypeManager::OK, difference);
  93. EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
  94. EXPECT_CALL(*migration_done_callback(), Run());
  95. SetUnsyncedTypes(ModelTypeSet());
  96. SendConfigureDone(DataTypeManager::OK, preferred_types());
  97. EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
  98. migrator()->RemoveMigrationObserver(&migration_observer);
  99. }
  100. // Test that in the normal case with Nigori a migration transitions through
  101. // each state and wind up back in IDLE.
  102. TEST_F(SyncBackendMigratorTest, MigrateNigori) {
  103. EXPECT_CALL(*migration_done_callback(), Run()).Times(0);
  104. ModelTypeSet to_migrate, difference;
  105. to_migrate.Put(NIGORI);
  106. difference.Put(AUTOFILL);
  107. difference.Put(BOOKMARKS);
  108. EXPECT_CALL(*manager(), state())
  109. .WillOnce(Return(DataTypeManager::CONFIGURED));
  110. EXPECT_CALL(*manager(), PurgeForMigration);
  111. migrator()->MigrateTypes(to_migrate);
  112. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  113. EXPECT_CALL(*reconfigure_callback(), Run());
  114. SetUnsyncedTypes(to_migrate);
  115. SendConfigureDone(DataTypeManager::OK, difference);
  116. EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
  117. EXPECT_CALL(*migration_done_callback(), Run());
  118. SetUnsyncedTypes(ModelTypeSet());
  119. SendConfigureDone(DataTypeManager::OK, preferred_types());
  120. EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
  121. }
  122. // Test that the migrator waits for the data type manager to be idle before
  123. // starting a migration.
  124. TEST_F(SyncBackendMigratorTest, WaitToStart) {
  125. ModelTypeSet to_migrate;
  126. to_migrate.Put(PREFERENCES);
  127. EXPECT_CALL(*manager(), state())
  128. .WillOnce(Return(DataTypeManager::CONFIGURING));
  129. EXPECT_CALL(*reconfigure_callback(), Run()).Times(0);
  130. migrator()->MigrateTypes(to_migrate);
  131. EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state());
  132. Mock::VerifyAndClearExpectations(manager());
  133. EXPECT_CALL(*manager(), state())
  134. .WillOnce(Return(DataTypeManager::CONFIGURED));
  135. EXPECT_CALL(*manager(), PurgeForMigration);
  136. SetUnsyncedTypes(ModelTypeSet());
  137. SendConfigureDone(DataTypeManager::OK, ModelTypeSet());
  138. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  139. }
  140. // Test that the migrator can cope with a migration request while a migration
  141. // is in progress.
  142. TEST_F(SyncBackendMigratorTest, RestartMigration) {
  143. ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks;
  144. to_migrate1.Put(PREFERENCES);
  145. to_migrate2.Put(AUTOFILL);
  146. to_migrate_union.Put(PREFERENCES);
  147. to_migrate_union.Put(AUTOFILL);
  148. bookmarks.Put(BOOKMARKS);
  149. EXPECT_CALL(*manager(), state())
  150. .WillOnce(Return(DataTypeManager::CONFIGURED));
  151. EXPECT_CALL(*manager(), PurgeForMigration).Times(2);
  152. migrator()->MigrateTypes(to_migrate1);
  153. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  154. migrator()->MigrateTypes(to_migrate2);
  155. const ModelTypeSet difference1 = Difference(preferred_types(), to_migrate1);
  156. Mock::VerifyAndClearExpectations(manager());
  157. EXPECT_CALL(*manager(), PurgeForMigration);
  158. EXPECT_CALL(*reconfigure_callback(), Run());
  159. SetUnsyncedTypes(to_migrate1);
  160. SendConfigureDone(DataTypeManager::OK, difference1);
  161. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  162. SetUnsyncedTypes(to_migrate_union);
  163. SendConfigureDone(DataTypeManager::OK, bookmarks);
  164. EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
  165. }
  166. // Test that an external invocation of Configure(...) during a migration results
  167. // in a migration reattempt.
  168. TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) {
  169. ModelTypeSet to_migrate;
  170. ModelTypeSet difference;
  171. to_migrate.Put(PREFERENCES);
  172. difference.Put(AUTOFILL);
  173. difference.Put(BOOKMARKS);
  174. EXPECT_CALL(*manager(), state())
  175. .WillOnce(Return(DataTypeManager::CONFIGURED));
  176. EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate)));
  177. migrator()->MigrateTypes(to_migrate);
  178. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  179. Mock::VerifyAndClearExpectations(manager());
  180. EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate)));
  181. SetUnsyncedTypes(ModelTypeSet());
  182. SendConfigureDone(DataTypeManager::OK, preferred_types());
  183. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  184. }
  185. // Test that spurious OnConfigureDone events don't confuse the
  186. // migrator while it's waiting for disabled types to have been purged
  187. // from the sync db.
  188. TEST_F(SyncBackendMigratorTest, WaitingForPurge) {
  189. ModelTypeSet to_migrate, difference;
  190. to_migrate.Put(PREFERENCES);
  191. to_migrate.Put(AUTOFILL);
  192. difference.Put(BOOKMARKS);
  193. EXPECT_CALL(*manager(), state())
  194. .WillOnce(Return(DataTypeManager::CONFIGURED));
  195. EXPECT_CALL(*manager(), PurgeForMigration);
  196. EXPECT_CALL(*reconfigure_callback(), Run());
  197. migrator()->MigrateTypes(to_migrate);
  198. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  199. SendConfigureDone(DataTypeManager::OK, difference);
  200. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  201. ModelTypeSet prefs;
  202. prefs.Put(PREFERENCES);
  203. SetUnsyncedTypes(prefs);
  204. SendConfigureDone(DataTypeManager::OK, difference);
  205. EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
  206. SetUnsyncedTypes(to_migrate);
  207. SendConfigureDone(DataTypeManager::OK, difference);
  208. EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
  209. }
  210. TEST_F(SyncBackendMigratorTest, ConfigureFailure) {
  211. ModelTypeSet to_migrate;
  212. to_migrate.Put(PREFERENCES);
  213. EXPECT_CALL(*manager(), state())
  214. .WillOnce(Return(DataTypeManager::CONFIGURED));
  215. EXPECT_CALL(*manager(), PurgeForMigration);
  216. migrator()->MigrateTypes(to_migrate);
  217. SetUnsyncedTypes(ModelTypeSet());
  218. SendConfigureDone(DataTypeManager::ABORTED, ModelTypeSet());
  219. EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
  220. }
  221. } // namespace syncer