Revert of Mandoline filesystem: Enable windows build. (patchset #8 id:140001 of https...
[chromium-blink-merge.git] / sync / internal_api / sync_rollback_manager_unittest.cc
blob0b5a6b658e36a3807749fd336a5a25445373b952
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
3 // found in the LICENSE file.
5 #include "sync/internal_api/sync_rollback_manager.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/run_loop.h"
9 #include "sync/internal_api/public/read_node.h"
10 #include "sync/internal_api/public/read_transaction.h"
11 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
12 #include "sync/internal_api/public/test/test_internal_components_factory.h"
13 #include "sync/internal_api/public/write_node.h"
14 #include "sync/internal_api/public/write_transaction.h"
15 #include "sync/internal_api/sync_backup_manager.h"
16 #include "sync/syncable/entry.h"
17 #include "sync/test/engine/fake_model_worker.h"
18 #include "sync/test/test_directory_backing_store.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/gurl.h"
23 using ::testing::_;
24 using ::testing::DoDefault;
25 using ::testing::Invoke;
26 using ::testing::Truly;
27 using ::testing::WithArgs;
29 namespace syncer {
31 namespace {
33 class TestChangeDelegate : public SyncManager::ChangeDelegate {
34 public:
35 TestChangeDelegate() {
36 ON_CALL(*this, OnChangesApplied(_, _, _, _))
37 .WillByDefault(
38 WithArgs<3>(Invoke(this,
39 &TestChangeDelegate::VerifyDeletes)));
42 void add_expected_delete(int64 v) {
43 expected_deletes_.insert(v);
46 MOCK_METHOD4(OnChangesApplied,
47 void(ModelType model_type,
48 int64 model_version,
49 const BaseTransaction* trans,
50 const ImmutableChangeRecordList& changes));
51 MOCK_METHOD1(OnChangesComplete, void(ModelType model_type));
53 private:
54 void VerifyDeletes(const ImmutableChangeRecordList& changes) {
55 std::set<int64> deleted;
56 for (size_t i = 0; i < changes.Get().size(); ++i) {
57 const ChangeRecord& change = (changes.Get())[i];
58 EXPECT_EQ(ChangeRecord::ACTION_DELETE, change.action);
59 EXPECT_TRUE(deleted.find(change.id) == deleted.end());
60 deleted.insert(change.id);
62 EXPECT_TRUE(expected_deletes_ == deleted);
65 std::set<int64> expected_deletes_;
68 class SyncRollbackManagerTest : public testing::Test,
69 public SyncManager::Observer {
70 protected:
71 void SetUp() override {
72 CHECK(temp_dir_.CreateUniqueTempDir());
74 worker_ = new FakeModelWorker(GROUP_UI);
77 MOCK_METHOD1(OnSyncCycleCompleted,
78 void(const sessions::SyncSessionSnapshot&));
79 MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus));
80 MOCK_METHOD4(OnInitializationComplete,
81 void(const WeakHandle<JsBackend>&,
82 const WeakHandle<DataTypeDebugInfoListener>&,
83 bool, ModelTypeSet));
84 MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&));
85 MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet));;
86 MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&));
88 void OnConfigDone(bool success) {
89 EXPECT_TRUE(success);
92 int64 CreateEntry(UserShare* user_share, ModelType type,
93 const std::string& client_tag) {
94 WriteTransaction trans(FROM_HERE, user_share);
95 ReadNode type_root(&trans);
96 EXPECT_EQ(BaseNode::INIT_OK, type_root.InitTypeRoot(type));
98 WriteNode node(&trans);
99 EXPECT_EQ(WriteNode::INIT_SUCCESS,
100 node.InitUniqueByCreation(type, type_root, client_tag));
101 return node.GetEntry()->GetMetahandle();
104 void InitManager(SyncManager* manager, ModelTypeSet types,
105 TestChangeDelegate* delegate,
106 InternalComponentsFactory::StorageOption storage_option) {
107 manager_ = manager;
108 types_ = types;
110 EXPECT_CALL(*this, OnInitializationComplete(_, _, _, _))
111 .WillOnce(WithArgs<2>(Invoke(this,
112 &SyncRollbackManagerTest::HandleInit)));
114 manager->AddObserver(this);
116 base::RunLoop run_loop;
117 SyncManager::InitArgs args;
118 args.database_location = temp_dir_.path();
119 args.service_url = GURL("https://example.com/");
120 args.workers.push_back(worker_);
121 args.change_delegate = delegate;
123 InternalComponentsFactory::StorageOption storage_used;
124 args.internal_components_factory.reset(new TestInternalComponentsFactory(
125 InternalComponentsFactory::Switches(), storage_option, &storage_used));
126 manager->Init(&args);
127 EXPECT_EQ(storage_option, storage_used);
128 loop_.PostTask(FROM_HERE, run_loop.QuitClosure());
129 run_loop.Run();
132 // Create and persist an entry by unique tag in DB.
133 void PrepopulateDb(ModelType type, const std::string& client_tag) {
134 SyncBackupManager backup_manager;
135 TestChangeDelegate delegate;
136 InitManager(&backup_manager, ModelTypeSet(type), &delegate,
137 InternalComponentsFactory::STORAGE_ON_DISK_DEFERRED);
138 CreateEntry(backup_manager.GetUserShare(), type, client_tag);
139 backup_manager.ShutdownOnSyncThread(SWITCH_MODE_SYNC);
142 // Verify entry with |client_tag| exists in sync directory.
143 bool VerifyEntry(UserShare* user_share, ModelType type,
144 const std::string& client_tag) {
145 ReadTransaction trans(FROM_HERE, user_share);
146 ReadNode node(&trans);
147 return BaseNode::INIT_OK == node.InitByClientTagLookup(type, client_tag);
150 private:
151 void ConfigureSyncer() {
152 manager_->ConfigureSyncer(
153 CONFIGURE_REASON_NEW_CLIENT,
154 types_,
155 ModelTypeSet(), ModelTypeSet(), ModelTypeSet(),
156 ModelSafeRoutingInfo(),
157 base::Bind(&SyncRollbackManagerTest::OnConfigDone,
158 base::Unretained(this), true),
159 base::Bind(&SyncRollbackManagerTest::OnConfigDone,
160 base::Unretained(this), false));
163 void HandleInit(bool success) {
164 if (success) {
165 loop_.PostTask(FROM_HERE,
166 base::Bind(&SyncRollbackManagerTest::ConfigureSyncer,
167 base::Unretained(this)));
168 } else {
169 manager_->ShutdownOnSyncThread(STOP_SYNC);
173 base::ScopedTempDir temp_dir_;
174 scoped_refptr<ModelSafeWorker> worker_;
175 base::MessageLoop loop_; // Needed for WeakHandle
176 SyncManager* manager_;
177 ModelTypeSet types_;
180 bool IsRollbackDoneAction(SyncProtocolError e) {
181 return e.action == syncer::ROLLBACK_DONE;
184 TEST_F(SyncRollbackManagerTest, RollbackBasic) {
185 PrepopulateDb(PREFERENCES, "pref1");
187 TestChangeDelegate delegate;
188 SyncRollbackManager rollback_manager;
189 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES), &delegate,
190 InternalComponentsFactory::STORAGE_ON_DISK);
192 // Simulate a new entry added during type initialization.
193 int64 new_pref_id =
194 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2");
196 delegate.add_expected_delete(new_pref_id);
197 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _))
198 .Times(1)
199 .WillOnce(DoDefault());
200 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1);
201 EXPECT_CALL(*this, OnActionableError(Truly(IsRollbackDoneAction))).Times(1);
203 ModelSafeRoutingInfo routing_info;
204 routing_info[PREFERENCES] = GROUP_UI;
205 rollback_manager.StartSyncingNormally(routing_info, base::Time());
208 TEST_F(SyncRollbackManagerTest, NoRollbackOfTypesNotBackedUp) {
209 PrepopulateDb(PREFERENCES, "pref1");
211 TestChangeDelegate delegate;
212 SyncRollbackManager rollback_manager;
213 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES, APPS), &delegate,
214 InternalComponentsFactory::STORAGE_ON_DISK);
216 // Simulate new entry added during type initialization.
217 int64 new_pref_id =
218 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2");
219 CreateEntry(rollback_manager.GetUserShare(), APPS, "app1");
221 delegate.add_expected_delete(new_pref_id);
222 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _))
223 .Times(1)
224 .WillOnce(DoDefault());
225 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1);
227 ModelSafeRoutingInfo routing_info;
228 routing_info[PREFERENCES] = GROUP_UI;
229 rollback_manager.StartSyncingNormally(routing_info, base::Time());
231 // APP entry is still valid.
232 EXPECT_TRUE(VerifyEntry(rollback_manager.GetUserShare(), APPS, "app1"));
235 TEST_F(SyncRollbackManagerTest, BackupDbNotChangedOnAbort) {
236 PrepopulateDb(PREFERENCES, "pref1");
238 TestChangeDelegate delegate;
239 scoped_ptr<SyncRollbackManager> rollback_manager(
240 new SyncRollbackManager);
241 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate,
242 InternalComponentsFactory::STORAGE_ON_DISK);
244 // Simulate a new entry added during type initialization.
245 CreateEntry(rollback_manager->GetUserShare(), PREFERENCES, "pref2");
247 // Manager was shut down before sync starts.
248 rollback_manager->ShutdownOnSyncThread(STOP_SYNC);
250 // Verify new entry was not persisted.
251 rollback_manager.reset(new SyncRollbackManager);
252 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate,
253 InternalComponentsFactory::STORAGE_ON_DISK);
254 EXPECT_FALSE(VerifyEntry(rollback_manager->GetUserShare(), PREFERENCES,
255 "pref2"));
258 TEST_F(SyncRollbackManagerTest, OnInitializationFailure) {
259 // Test graceful shutdown on initialization failure.
260 scoped_ptr<SyncRollbackManager> rollback_manager(
261 new SyncRollbackManager);
262 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), NULL,
263 InternalComponentsFactory::STORAGE_ON_DISK);
266 } // anonymous namespace
268 } // namespace syncer