| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "sync/internal_api/sync_rollback_manager.h" | 5 #include "sync/internal_api/sync_rollback_manager.h" |
| 6 | 6 |
| 7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
| 8 #include "base/run_loop.h" |
| 8 #include "sync/internal_api/public/read_node.h" | 9 #include "sync/internal_api/public/read_node.h" |
| 9 #include "sync/internal_api/public/read_transaction.h" | 10 #include "sync/internal_api/public/read_transaction.h" |
| 10 #include "sync/internal_api/public/sessions/sync_session_snapshot.h" | 11 #include "sync/internal_api/public/sessions/sync_session_snapshot.h" |
| 11 #include "sync/internal_api/public/test/test_internal_components_factory.h" | 12 #include "sync/internal_api/public/test/test_internal_components_factory.h" |
| 12 #include "sync/internal_api/public/write_node.h" | 13 #include "sync/internal_api/public/write_node.h" |
| 13 #include "sync/internal_api/public/write_transaction.h" | 14 #include "sync/internal_api/public/write_transaction.h" |
| 14 #include "sync/internal_api/sync_backup_manager.h" | 15 #include "sync/internal_api/sync_backup_manager.h" |
| 15 #include "sync/syncable/entry.h" | 16 #include "sync/syncable/entry.h" |
| 16 #include "sync/test/engine/fake_model_worker.h" | 17 #include "sync/test/engine/fake_model_worker.h" |
| 17 #include "sync/test/test_directory_backing_store.h" | 18 #include "sync/test/test_directory_backing_store.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 virtual void SetUp() OVERRIDE { | 70 virtual void SetUp() OVERRIDE { |
| 70 CHECK(temp_dir_.CreateUniqueTempDir()); | 71 CHECK(temp_dir_.CreateUniqueTempDir()); |
| 71 | 72 |
| 72 worker_ = new FakeModelWorker(GROUP_UI); | 73 worker_ = new FakeModelWorker(GROUP_UI); |
| 73 } | 74 } |
| 74 | 75 |
| 75 MOCK_METHOD1(OnSyncCycleCompleted, | 76 MOCK_METHOD1(OnSyncCycleCompleted, |
| 76 void(const sessions::SyncSessionSnapshot&)); | 77 void(const sessions::SyncSessionSnapshot&)); |
| 77 MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus)); | 78 MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus)); |
| 78 MOCK_METHOD4(OnInitializationComplete, | 79 MOCK_METHOD4(OnInitializationComplete, |
| 79 void(const WeakHandle<JsBackend>&, | 80 void(const WeakHandle<JsBackend>&, |
| 80 const WeakHandle<DataTypeDebugInfoListener>&, | 81 const WeakHandle<DataTypeDebugInfoListener>&, |
| 81 bool, ModelTypeSet)); | 82 bool, ModelTypeSet)); |
| 82 MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&)); | 83 MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&)); |
| 83 MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet));; | 84 MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet));; |
| 84 MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&)); | 85 MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&)); |
| 85 | 86 |
| 86 void OnConfigDone(bool success) { | 87 void OnConfigDone(bool success) { |
| 87 EXPECT_TRUE(success); | 88 EXPECT_TRUE(success); |
| 88 } | 89 } |
| 89 | 90 |
| 90 int64 CreateEntry(UserShare* user_share, ModelType type, | 91 int64 CreateEntry(UserShare* user_share, ModelType type, |
| 91 const std::string& client_tag) { | 92 const std::string& client_tag) { |
| 92 WriteTransaction trans(FROM_HERE, user_share); | 93 WriteTransaction trans(FROM_HERE, user_share); |
| 93 ReadNode type_root(&trans); | 94 ReadNode type_root(&trans); |
| 94 EXPECT_EQ(BaseNode::INIT_OK, type_root.InitTypeRoot(type)); | 95 EXPECT_EQ(BaseNode::INIT_OK, type_root.InitTypeRoot(type)); |
| 95 | 96 |
| 96 WriteNode node(&trans); | 97 WriteNode node(&trans); |
| 97 EXPECT_EQ(WriteNode::INIT_SUCCESS, | 98 EXPECT_EQ(WriteNode::INIT_SUCCESS, |
| 98 node.InitUniqueByCreation(type, type_root, client_tag)); | 99 node.InitUniqueByCreation(type, type_root, client_tag)); |
| 99 return node.GetEntry()->GetMetahandle(); | 100 return node.GetEntry()->GetMetahandle(); |
| 100 } | 101 } |
| 101 | 102 |
| 102 void InitManager(SyncManager* manager, ModelTypeSet types, | 103 void InitManager(SyncManager* manager, ModelTypeSet types, |
| 103 TestChangeDelegate* delegate) { | 104 TestChangeDelegate* delegate, StorageOption storage_option) { |
| 105 manager_ = manager; |
| 106 types_ = types; |
| 107 |
| 108 EXPECT_CALL(*this, OnInitializationComplete(_, _, _, _)) |
| 109 .WillOnce(WithArgs<2>(Invoke(this, |
| 110 &SyncRollbackManagerTest::HandleInit))); |
| 111 |
| 104 manager->AddObserver(this); | 112 manager->AddObserver(this); |
| 105 TestInternalComponentsFactory factory(InternalComponentsFactory::Switches(), | 113 TestInternalComponentsFactory factory(InternalComponentsFactory::Switches(), |
| 106 STORAGE_ON_DISK); | 114 storage_option); |
| 107 | 115 |
| 116 base::RunLoop run_loop; |
| 108 manager->Init(temp_dir_.path(), | 117 manager->Init(temp_dir_.path(), |
| 109 MakeWeakHandle(base::WeakPtr<JsEventHandler>()), | 118 MakeWeakHandle(base::WeakPtr<JsEventHandler>()), |
| 110 "", 0, true, scoped_ptr<HttpPostProviderFactory>().Pass(), | 119 "", 0, true, scoped_ptr<HttpPostProviderFactory>().Pass(), |
| 111 std::vector<scoped_refptr<ModelSafeWorker> >(1, | 120 std::vector<scoped_refptr<ModelSafeWorker> >(1, |
| 112 worker_.get()), | 121 worker_.get()), |
| 113 NULL, delegate, SyncCredentials(), "", "", "", &factory, | 122 NULL, delegate, SyncCredentials(), "", "", "", &factory, |
| 114 NULL, scoped_ptr<UnrecoverableErrorHandler>().Pass(), | 123 NULL, scoped_ptr<UnrecoverableErrorHandler>().Pass(), |
| 115 NULL, NULL); | 124 NULL, NULL); |
| 116 manager->ConfigureSyncer( | 125 loop_.PostTask(FROM_HERE, run_loop.QuitClosure()); |
| 117 CONFIGURE_REASON_NEW_CLIENT, | 126 run_loop.Run(); |
| 118 types, | |
| 119 ModelTypeSet(), ModelTypeSet(), ModelTypeSet(), ModelSafeRoutingInfo(), | |
| 120 base::Bind(&SyncRollbackManagerTest::OnConfigDone, | |
| 121 base::Unretained(this), true), | |
| 122 base::Bind(&SyncRollbackManagerTest::OnConfigDone, | |
| 123 base::Unretained(this), false)); | |
| 124 } | 127 } |
| 125 | 128 |
| 126 // Create and persist an entry by unique tag in DB. | 129 // Create and persist an entry by unique tag in DB. |
| 127 void PrepopulateDb(ModelType type, const std::string& client_tag) { | 130 void PrepopulateDb(ModelType type, const std::string& client_tag) { |
| 128 SyncBackupManager backup_manager; | 131 SyncBackupManager backup_manager; |
| 129 TestChangeDelegate delegate; | 132 TestChangeDelegate delegate; |
| 130 InitManager(&backup_manager, ModelTypeSet(type), &delegate); | 133 InitManager(&backup_manager, ModelTypeSet(type), &delegate, |
| 134 STORAGE_ON_DISK); |
| 131 CreateEntry(backup_manager.GetUserShare(), type, client_tag); | 135 CreateEntry(backup_manager.GetUserShare(), type, client_tag); |
| 132 backup_manager.ShutdownOnSyncThread(); | 136 backup_manager.ShutdownOnSyncThread(); |
| 133 } | 137 } |
| 134 | 138 |
| 135 // Verify entry with |client_tag| exists in sync directory. | 139 // Verify entry with |client_tag| exists in sync directory. |
| 136 bool VerifyEntry(UserShare* user_share, ModelType type, | 140 bool VerifyEntry(UserShare* user_share, ModelType type, |
| 137 const std::string& client_tag) { | 141 const std::string& client_tag) { |
| 138 ReadTransaction trans(FROM_HERE, user_share); | 142 ReadTransaction trans(FROM_HERE, user_share); |
| 139 ReadNode node(&trans); | 143 ReadNode node(&trans); |
| 140 return BaseNode::INIT_OK == node.InitByClientTagLookup(type, client_tag); | 144 return BaseNode::INIT_OK == node.InitByClientTagLookup(type, client_tag); |
| 141 } | 145 } |
| 142 | 146 |
| 147 private: |
| 148 void ConfigureSyncer() { |
| 149 manager_->ConfigureSyncer( |
| 150 CONFIGURE_REASON_NEW_CLIENT, |
| 151 types_, |
| 152 ModelTypeSet(), ModelTypeSet(), ModelTypeSet(), |
| 153 ModelSafeRoutingInfo(), |
| 154 base::Bind(&SyncRollbackManagerTest::OnConfigDone, |
| 155 base::Unretained(this), true), |
| 156 base::Bind(&SyncRollbackManagerTest::OnConfigDone, |
| 157 base::Unretained(this), false)); |
| 158 } |
| 159 |
| 160 void HandleInit(bool success) { |
| 161 if (success) { |
| 162 loop_.PostTask(FROM_HERE, |
| 163 base::Bind(&SyncRollbackManagerTest::ConfigureSyncer, |
| 164 base::Unretained(this))); |
| 165 } else { |
| 166 manager_->ShutdownOnSyncThread(); |
| 167 } |
| 168 } |
| 169 |
| 143 base::ScopedTempDir temp_dir_; | 170 base::ScopedTempDir temp_dir_; |
| 144 scoped_refptr<ModelSafeWorker> worker_; | 171 scoped_refptr<ModelSafeWorker> worker_; |
| 145 base::MessageLoop loop_; // Needed for WeakHandle | 172 base::MessageLoop loop_; // Needed for WeakHandle |
| 173 SyncManager* manager_; |
| 174 ModelTypeSet types_; |
| 146 }; | 175 }; |
| 147 | 176 |
| 148 bool IsRollbackDoneAction(SyncProtocolError e) { | 177 bool IsRollbackDoneAction(SyncProtocolError e) { |
| 149 return e.action == syncer::ROLLBACK_DONE; | 178 return e.action == syncer::ROLLBACK_DONE; |
| 150 } | 179 } |
| 151 | 180 |
| 152 TEST_F(SyncRollbackManagerTest, RollbackBasic) { | 181 TEST_F(SyncRollbackManagerTest, RollbackBasic) { |
| 153 PrepopulateDb(PREFERENCES, "pref1"); | 182 PrepopulateDb(PREFERENCES, "pref1"); |
| 154 | 183 |
| 155 TestChangeDelegate delegate; | 184 TestChangeDelegate delegate; |
| 156 SyncRollbackManager rollback_manager; | 185 SyncRollbackManager rollback_manager; |
| 157 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES), &delegate); | 186 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES), &delegate, |
| 187 STORAGE_ON_DISK); |
| 158 | 188 |
| 159 // Simulate a new entry added during type initialization. | 189 // Simulate a new entry added during type initialization. |
| 160 int64 new_pref_id = | 190 int64 new_pref_id = |
| 161 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2"); | 191 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2"); |
| 162 | 192 |
| 163 delegate.add_expected_delete(new_pref_id); | 193 delegate.add_expected_delete(new_pref_id); |
| 164 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _)) | 194 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _)) |
| 165 .Times(1) | 195 .Times(1) |
| 166 .WillOnce(DoDefault()); | 196 .WillOnce(DoDefault()); |
| 167 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1); | 197 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1); |
| 168 EXPECT_CALL(*this, OnActionableError(Truly(IsRollbackDoneAction))).Times(1); | 198 EXPECT_CALL(*this, OnActionableError(Truly(IsRollbackDoneAction))).Times(1); |
| 169 | 199 |
| 170 ModelSafeRoutingInfo routing_info; | 200 ModelSafeRoutingInfo routing_info; |
| 171 routing_info[PREFERENCES] = GROUP_UI; | 201 routing_info[PREFERENCES] = GROUP_UI; |
| 172 rollback_manager.StartSyncingNormally(routing_info); | 202 rollback_manager.StartSyncingNormally(routing_info); |
| 173 } | 203 } |
| 174 | 204 |
| 175 TEST_F(SyncRollbackManagerTest, NoRollbackOfTypesNotBackedUp) { | 205 TEST_F(SyncRollbackManagerTest, NoRollbackOfTypesNotBackedUp) { |
| 176 PrepopulateDb(PREFERENCES, "pref1"); | 206 PrepopulateDb(PREFERENCES, "pref1"); |
| 177 | 207 |
| 178 TestChangeDelegate delegate; | 208 TestChangeDelegate delegate; |
| 179 SyncRollbackManager rollback_manager; | 209 SyncRollbackManager rollback_manager; |
| 180 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES, APPS), &delegate); | 210 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES, APPS), &delegate, |
| 211 STORAGE_ON_DISK); |
| 181 | 212 |
| 182 // Simulate new entry added during type initialization. | 213 // Simulate new entry added during type initialization. |
| 183 int64 new_pref_id = | 214 int64 new_pref_id = |
| 184 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2"); | 215 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2"); |
| 185 CreateEntry(rollback_manager.GetUserShare(), APPS, "app1"); | 216 CreateEntry(rollback_manager.GetUserShare(), APPS, "app1"); |
| 186 | 217 |
| 187 delegate.add_expected_delete(new_pref_id); | 218 delegate.add_expected_delete(new_pref_id); |
| 188 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _)) | 219 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _)) |
| 189 .Times(1) | 220 .Times(1) |
| 190 .WillOnce(DoDefault()); | 221 .WillOnce(DoDefault()); |
| 191 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1); | 222 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1); |
| 192 | 223 |
| 193 ModelSafeRoutingInfo routing_info; | 224 ModelSafeRoutingInfo routing_info; |
| 194 routing_info[PREFERENCES] = GROUP_UI; | 225 routing_info[PREFERENCES] = GROUP_UI; |
| 195 rollback_manager.StartSyncingNormally(routing_info); | 226 rollback_manager.StartSyncingNormally(routing_info); |
| 196 | 227 |
| 197 // APP entry is still valid. | 228 // APP entry is still valid. |
| 198 EXPECT_TRUE(VerifyEntry(rollback_manager.GetUserShare(), APPS, "app1")); | 229 EXPECT_TRUE(VerifyEntry(rollback_manager.GetUserShare(), APPS, "app1")); |
| 199 } | 230 } |
| 200 | 231 |
| 201 TEST_F(SyncRollbackManagerTest, BackupDbNotChangedOnAbort) { | 232 TEST_F(SyncRollbackManagerTest, BackupDbNotChangedOnAbort) { |
| 202 PrepopulateDb(PREFERENCES, "pref1"); | 233 PrepopulateDb(PREFERENCES, "pref1"); |
| 203 | 234 |
| 204 TestChangeDelegate delegate; | 235 TestChangeDelegate delegate; |
| 205 scoped_ptr<SyncRollbackManager> rollback_manager( | 236 scoped_ptr<SyncRollbackManager> rollback_manager( |
| 206 new SyncRollbackManager); | 237 new SyncRollbackManager); |
| 207 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate); | 238 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate, |
| 239 STORAGE_ON_DISK); |
| 208 | 240 |
| 209 // Simulate a new entry added during type initialization. | 241 // Simulate a new entry added during type initialization. |
| 210 CreateEntry(rollback_manager->GetUserShare(), PREFERENCES, "pref2"); | 242 CreateEntry(rollback_manager->GetUserShare(), PREFERENCES, "pref2"); |
| 211 | 243 |
| 212 // Manager was shut down before sync starts. | 244 // Manager was shut down before sync starts. |
| 213 rollback_manager->ShutdownOnSyncThread(); | 245 rollback_manager->ShutdownOnSyncThread(); |
| 214 | 246 |
| 215 // Verify new entry was not persisted. | 247 // Verify new entry was not persisted. |
| 216 rollback_manager.reset(new SyncRollbackManager); | 248 rollback_manager.reset(new SyncRollbackManager); |
| 217 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate); | 249 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate, |
| 250 STORAGE_ON_DISK); |
| 218 EXPECT_FALSE(VerifyEntry(rollback_manager->GetUserShare(), PREFERENCES, | 251 EXPECT_FALSE(VerifyEntry(rollback_manager->GetUserShare(), PREFERENCES, |
| 219 "pref2")); | 252 "pref2")); |
| 220 } | 253 } |
| 221 | 254 |
| 255 TEST_F(SyncRollbackManagerTest, OnInitializationFailure) { |
| 256 // Test graceful shutdown on initialization failure. |
| 257 scoped_ptr<SyncRollbackManager> rollback_manager( |
| 258 new SyncRollbackManager); |
| 259 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), NULL, |
| 260 STORAGE_ON_DISK); |
| 261 } |
| 262 |
| 222 } // anonymous namespace | 263 } // anonymous namespace |
| 223 | 264 |
| 224 } // namespace syncer | 265 } // namespace syncer |
| OLD | NEW |