[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / sync / internal_api / sync_rollback_manager_unittest.cc
blob11f875f56a0f4ad97967ce72403eaf1d50ad11e9
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"
22 using ::testing::_;
23 using ::testing::DoDefault;
24 using ::testing::Invoke;
25 using ::testing::Truly;
26 using ::testing::WithArgs;
28 namespace syncer {
30 namespace {
32 class TestChangeDelegate : public SyncManager::ChangeDelegate {
33 public:
34 TestChangeDelegate() {
35 ON_CALL(*this, OnChangesApplied(_, _, _, _))
36 .WillByDefault(
37 WithArgs<3>(Invoke(this,
38 &TestChangeDelegate::VerifyDeletes)));
41 void add_expected_delete(int64 v) {
42 expected_deletes_.insert(v);
45 MOCK_METHOD4(OnChangesApplied,
46 void(ModelType model_type,
47 int64 model_version,
48 const BaseTransaction* trans,
49 const ImmutableChangeRecordList& changes));
50 MOCK_METHOD1(OnChangesComplete, void(ModelType model_type));
52 private:
53 void VerifyDeletes(const ImmutableChangeRecordList& changes) {
54 std::set<int64> deleted;
55 for (size_t i = 0; i < changes.Get().size(); ++i) {
56 const ChangeRecord& change = (changes.Get())[i];
57 EXPECT_EQ(ChangeRecord::ACTION_DELETE, change.action);
58 EXPECT_TRUE(deleted.find(change.id) == deleted.end());
59 deleted.insert(change.id);
61 EXPECT_TRUE(expected_deletes_ == deleted);
64 std::set<int64> expected_deletes_;
67 class SyncRollbackManagerTest : public testing::Test,
68 public SyncManager::Observer {
69 protected:
70 virtual void SetUp() OVERRIDE {
71 CHECK(temp_dir_.CreateUniqueTempDir());
73 worker_ = new FakeModelWorker(GROUP_UI);
76 MOCK_METHOD1(OnSyncCycleCompleted,
77 void(const sessions::SyncSessionSnapshot&));
78 MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus));
79 MOCK_METHOD4(OnInitializationComplete,
80 void(const WeakHandle<JsBackend>&,
81 const WeakHandle<DataTypeDebugInfoListener>&,
82 bool, ModelTypeSet));
83 MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&));
84 MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet));;
85 MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&));
87 void OnConfigDone(bool success) {
88 EXPECT_TRUE(success);
91 int64 CreateEntry(UserShare* user_share, ModelType type,
92 const std::string& client_tag) {
93 WriteTransaction trans(FROM_HERE, user_share);
94 ReadNode type_root(&trans);
95 EXPECT_EQ(BaseNode::INIT_OK, type_root.InitTypeRoot(type));
97 WriteNode node(&trans);
98 EXPECT_EQ(WriteNode::INIT_SUCCESS,
99 node.InitUniqueByCreation(type, type_root, client_tag));
100 return node.GetEntry()->GetMetahandle();
103 void InitManager(SyncManager* manager, ModelTypeSet types,
104 TestChangeDelegate* delegate, StorageOption storage_option) {
105 manager_ = manager;
106 types_ = types;
108 EXPECT_CALL(*this, OnInitializationComplete(_, _, _, _))
109 .WillOnce(WithArgs<2>(Invoke(this,
110 &SyncRollbackManagerTest::HandleInit)));
112 manager->AddObserver(this);
113 TestInternalComponentsFactory factory(InternalComponentsFactory::Switches(),
114 storage_option);
116 base::RunLoop run_loop;
117 manager->Init(temp_dir_.path(),
118 MakeWeakHandle(base::WeakPtr<JsEventHandler>()),
119 "", 0, true, scoped_ptr<HttpPostProviderFactory>().Pass(),
120 std::vector<scoped_refptr<ModelSafeWorker> >(1,
121 worker_.get()),
122 NULL, delegate, SyncCredentials(), "", "", "", &factory,
123 NULL, scoped_ptr<UnrecoverableErrorHandler>().Pass(),
124 NULL, NULL);
125 loop_.PostTask(FROM_HERE, run_loop.QuitClosure());
126 run_loop.Run();
129 // Create and persist an entry by unique tag in DB.
130 void PrepopulateDb(ModelType type, const std::string& client_tag) {
131 SyncBackupManager backup_manager;
132 TestChangeDelegate delegate;
133 InitManager(&backup_manager, ModelTypeSet(type), &delegate,
134 STORAGE_ON_DISK);
135 CreateEntry(backup_manager.GetUserShare(), type, client_tag);
136 backup_manager.ShutdownOnSyncThread();
139 // Verify entry with |client_tag| exists in sync directory.
140 bool VerifyEntry(UserShare* user_share, ModelType type,
141 const std::string& client_tag) {
142 ReadTransaction trans(FROM_HERE, user_share);
143 ReadNode node(&trans);
144 return BaseNode::INIT_OK == node.InitByClientTagLookup(type, client_tag);
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));
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();
170 base::ScopedTempDir temp_dir_;
171 scoped_refptr<ModelSafeWorker> worker_;
172 base::MessageLoop loop_; // Needed for WeakHandle
173 SyncManager* manager_;
174 ModelTypeSet types_;
177 bool IsRollbackDoneAction(SyncProtocolError e) {
178 return e.action == syncer::ROLLBACK_DONE;
181 TEST_F(SyncRollbackManagerTest, RollbackBasic) {
182 PrepopulateDb(PREFERENCES, "pref1");
184 TestChangeDelegate delegate;
185 SyncRollbackManager rollback_manager;
186 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES), &delegate,
187 STORAGE_ON_DISK);
189 // Simulate a new entry added during type initialization.
190 int64 new_pref_id =
191 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2");
193 delegate.add_expected_delete(new_pref_id);
194 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _))
195 .Times(1)
196 .WillOnce(DoDefault());
197 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1);
198 EXPECT_CALL(*this, OnActionableError(Truly(IsRollbackDoneAction))).Times(1);
200 ModelSafeRoutingInfo routing_info;
201 routing_info[PREFERENCES] = GROUP_UI;
202 rollback_manager.StartSyncingNormally(routing_info);
205 TEST_F(SyncRollbackManagerTest, NoRollbackOfTypesNotBackedUp) {
206 PrepopulateDb(PREFERENCES, "pref1");
208 TestChangeDelegate delegate;
209 SyncRollbackManager rollback_manager;
210 InitManager(&rollback_manager, ModelTypeSet(PREFERENCES, APPS), &delegate,
211 STORAGE_ON_DISK);
213 // Simulate new entry added during type initialization.
214 int64 new_pref_id =
215 CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2");
216 CreateEntry(rollback_manager.GetUserShare(), APPS, "app1");
218 delegate.add_expected_delete(new_pref_id);
219 EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _))
220 .Times(1)
221 .WillOnce(DoDefault());
222 EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1);
224 ModelSafeRoutingInfo routing_info;
225 routing_info[PREFERENCES] = GROUP_UI;
226 rollback_manager.StartSyncingNormally(routing_info);
228 // APP entry is still valid.
229 EXPECT_TRUE(VerifyEntry(rollback_manager.GetUserShare(), APPS, "app1"));
232 TEST_F(SyncRollbackManagerTest, BackupDbNotChangedOnAbort) {
233 PrepopulateDb(PREFERENCES, "pref1");
235 TestChangeDelegate delegate;
236 scoped_ptr<SyncRollbackManager> rollback_manager(
237 new SyncRollbackManager);
238 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate,
239 STORAGE_ON_DISK);
241 // Simulate a new entry added during type initialization.
242 CreateEntry(rollback_manager->GetUserShare(), PREFERENCES, "pref2");
244 // Manager was shut down before sync starts.
245 rollback_manager->ShutdownOnSyncThread();
247 // Verify new entry was not persisted.
248 rollback_manager.reset(new SyncRollbackManager);
249 InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate,
250 STORAGE_ON_DISK);
251 EXPECT_FALSE(VerifyEntry(rollback_manager->GetUserShare(), PREFERENCES,
252 "pref2"));
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);
263 } // anonymous namespace
265 } // namespace syncer