OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/sync/syncable/syncable.h" | 5 #include "chrome/browser/sync/syncable/syncable.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #include <sys/types.h> | 9 #include <sys/types.h> |
10 | 10 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 | 293 |
294 void SaveAndReloadDir() { | 294 void SaveAndReloadDir() { |
295 dir_->SaveChanges(); | 295 dir_->SaveChanges(); |
296 ReloadDir(); | 296 ReloadDir(); |
297 } | 297 } |
298 | 298 |
299 bool IsInDirtyMetahandles(int64 metahandle) { | 299 bool IsInDirtyMetahandles(int64 metahandle) { |
300 return 1 == dir_->kernel_->dirty_metahandles->count(metahandle); | 300 return 1 == dir_->kernel_->dirty_metahandles->count(metahandle); |
301 } | 301 } |
302 | 302 |
303 bool IsSafeToPermanentlyDelete(Entry* e) { | 303 bool IsInMetahandlesToPurge(int64 metahandle) { |
304 return e->Get(IS_DEL) && !e->Get(IS_UNSYNCED) && | 304 return 1 == dir_->kernel_->metahandles_to_purge->count(metahandle); |
305 !e->Get(IS_UNAPPLIED_UPDATE); | |
306 } | 305 } |
307 | 306 |
308 void CheckPurgeEntriesWithTypeInSucceeded(const ModelTypeSet& types_to_purge, | 307 void CheckPurgeEntriesWithTypeInSucceeded(const ModelTypeSet& types_to_purge, |
309 bool before_reload) { | 308 bool before_reload) { |
| 309 SCOPED_TRACE(testing::Message("Before reload: ") << before_reload); |
310 { | 310 { |
311 ReadTransaction trans(dir_.get(), __FILE__, __LINE__); | 311 ReadTransaction trans(dir_.get(), __FILE__, __LINE__); |
312 MetahandleSet all_set; | 312 MetahandleSet all_set; |
313 dir_->GetAllMetaHandles(&trans, &all_set); | 313 dir_->GetAllMetaHandles(&trans, &all_set); |
314 EXPECT_EQ(before_reload ? 7U : 3U, all_set.size()); | 314 EXPECT_EQ(3U, all_set.size()); |
| 315 if (before_reload) |
| 316 EXPECT_EQ(4U, dir_->kernel_->metahandles_to_purge->size()); |
315 for (MetahandleSet::iterator iter = all_set.begin(); | 317 for (MetahandleSet::iterator iter = all_set.begin(); |
316 iter != all_set.end(); ++iter) { | 318 iter != all_set.end(); ++iter) { |
317 Entry e(&trans, GET_BY_HANDLE, *iter); | 319 Entry e(&trans, GET_BY_HANDLE, *iter); |
318 if ((types_to_purge.count(e.GetModelType()) || | 320 if ((types_to_purge.count(e.GetModelType()) || |
319 types_to_purge.count(e.GetServerModelType())) && | 321 types_to_purge.count(e.GetServerModelType()))) { |
320 (!before_reload || !IsSafeToPermanentlyDelete(&e))) { | |
321 FAIL() << "Illegal type should have been deleted."; | 322 FAIL() << "Illegal type should have been deleted."; |
322 } | 323 } |
323 } | 324 } |
324 } | 325 } |
325 | 326 |
326 EXPECT_FALSE(dir_->initial_sync_ended_for_type(PREFERENCES)); | 327 EXPECT_FALSE(dir_->initial_sync_ended_for_type(PREFERENCES)); |
327 EXPECT_FALSE(dir_->initial_sync_ended_for_type(AUTOFILL)); | 328 EXPECT_FALSE(dir_->initial_sync_ended_for_type(AUTOFILL)); |
328 EXPECT_TRUE(dir_->initial_sync_ended_for_type(BOOKMARKS)); | 329 EXPECT_TRUE(dir_->initial_sync_ended_for_type(BOOKMARKS)); |
329 | 330 |
330 EXPECT_EQ(0, dir_->last_download_timestamp(PREFERENCES)); | 331 EXPECT_EQ(0, dir_->last_download_timestamp(PREFERENCES)); |
(...skipping 21 matching lines...) Expand all Loading... |
352 me.Put(IS_UNSYNCED, true); | 353 me.Put(IS_UNSYNCED, true); |
353 } | 354 } |
354 | 355 |
355 void ValidateEntry(BaseTransaction* trans, int64 id, bool check_name, | 356 void ValidateEntry(BaseTransaction* trans, int64 id, bool check_name, |
356 string name, int64 base_version, int64 server_version, bool is_del); | 357 string name, int64 base_version, int64 server_version, bool is_del); |
357 void CreateAndCheck(WriteTransaction* trans, int64 parent_id, int64 id, | 358 void CreateAndCheck(WriteTransaction* trans, int64 parent_id, int64 id, |
358 string name, string server_name, int64 version, | 359 string name, string server_name, int64 version, |
359 bool set_server_fields, bool is_dir, bool add_to_lru, int64 *meta_handle); | 360 bool set_server_fields, bool is_dir, bool add_to_lru, int64 *meta_handle); |
360 }; | 361 }; |
361 | 362 |
| 363 TEST_F(SyncableDirectoryTest, TakeSnapshotGetsMetahandlesToPurge) { |
| 364 const int metas_to_create = 50; |
| 365 MetahandleSet expected_purges; |
| 366 MetahandleSet all_handles; |
| 367 { |
| 368 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |
| 369 for (int i = 0; i < metas_to_create; i++) { |
| 370 MutableEntry e(&trans, CREATE, trans.root_id(), "foo"); |
| 371 e.Put(IS_UNSYNCED, true); |
| 372 sync_pb::EntitySpecifics specs; |
| 373 if (i % 2 == 0) { |
| 374 AddDefaultExtensionValue(BOOKMARKS, &specs); |
| 375 expected_purges.insert(e.Get(META_HANDLE)); |
| 376 all_handles.insert(e.Get(META_HANDLE)); |
| 377 } else { |
| 378 AddDefaultExtensionValue(PREFERENCES, &specs); |
| 379 all_handles.insert(e.Get(META_HANDLE)); |
| 380 } |
| 381 e.Put(SPECIFICS, specs); |
| 382 e.Put(SERVER_SPECIFICS, specs); |
| 383 } |
| 384 } |
| 385 |
| 386 ModelTypeSet to_purge; |
| 387 to_purge.insert(BOOKMARKS); |
| 388 dir_->PurgeEntriesWithTypeIn(to_purge); |
| 389 |
| 390 Directory::SaveChangesSnapshot snapshot1; |
| 391 AutoLock scoped_lock(dir_->kernel_->save_changes_mutex); |
| 392 dir_->TakeSnapshotForSaveChanges(&snapshot1); |
| 393 EXPECT_TRUE(expected_purges == snapshot1.metahandles_to_purge); |
| 394 |
| 395 to_purge.clear(); |
| 396 to_purge.insert(PREFERENCES); |
| 397 dir_->PurgeEntriesWithTypeIn(to_purge); |
| 398 |
| 399 dir_->HandleSaveChangesFailure(snapshot1); |
| 400 |
| 401 Directory::SaveChangesSnapshot snapshot2; |
| 402 dir_->TakeSnapshotForSaveChanges(&snapshot2); |
| 403 EXPECT_TRUE(all_handles == snapshot2.metahandles_to_purge); |
| 404 } |
| 405 |
362 TEST_F(SyncableDirectoryTest, TakeSnapshotGetsAllDirtyHandlesTest) { | 406 TEST_F(SyncableDirectoryTest, TakeSnapshotGetsAllDirtyHandlesTest) { |
363 const int metahandles_to_create = 100; | 407 const int metahandles_to_create = 100; |
364 std::vector<int64> expected_dirty_metahandles; | 408 std::vector<int64> expected_dirty_metahandles; |
365 { | 409 { |
366 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 410 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |
367 for (int i = 0; i < metahandles_to_create; i++) { | 411 for (int i = 0; i < metahandles_to_create; i++) { |
368 MutableEntry e(&trans, CREATE, trans.root_id(), "foo"); | 412 MutableEntry e(&trans, CREATE, trans.root_id(), "foo"); |
369 expected_dirty_metahandles.push_back(e.Get(META_HANDLE)); | 413 expected_dirty_metahandles.push_back(e.Get(META_HANDLE)); |
370 e.Put(IS_UNSYNCED, true); | 414 e.Put(IS_UNSYNCED, true); |
371 } | 415 } |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 EntryKernel aguilera = e1.GetKernelCopy(); | 1192 EntryKernel aguilera = e1.GetKernelCopy(); |
1149 Entry kids(&trans, GET_BY_HANDLE, handle2); | 1193 Entry kids(&trans, GET_BY_HANDLE, handle2); |
1150 ASSERT_TRUE(kids.good()); | 1194 ASSERT_TRUE(kids.good()); |
1151 EXPECT_TRUE(kids.GetKernelCopy().is_dirty()); | 1195 EXPECT_TRUE(kids.GetKernelCopy().is_dirty()); |
1152 EXPECT_TRUE(IsInDirtyMetahandles(handle2)); | 1196 EXPECT_TRUE(IsInDirtyMetahandles(handle2)); |
1153 EXPECT_TRUE(aguilera.is_dirty()); | 1197 EXPECT_TRUE(aguilera.is_dirty()); |
1154 EXPECT_TRUE(IsInDirtyMetahandles(handle1)); | 1198 EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
1155 } | 1199 } |
1156 } | 1200 } |
1157 | 1201 |
| 1202 TEST_F(SyncableDirectoryTest, TestSaveChangesFailureWithPurge) { |
| 1203 int64 handle1 = 0; |
| 1204 // Set up an item using a regular, saveable directory. |
| 1205 { |
| 1206 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |
| 1207 |
| 1208 MutableEntry e1(&trans, CREATE, trans.root_id(), "aguilera"); |
| 1209 ASSERT_TRUE(e1.good()); |
| 1210 EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); |
| 1211 handle1 = e1.Get(META_HANDLE); |
| 1212 e1.Put(BASE_VERSION, 1); |
| 1213 e1.Put(IS_DIR, true); |
| 1214 e1.Put(ID, TestIdFactory::FromNumber(101)); |
| 1215 sync_pb::EntitySpecifics bookmark_specs; |
| 1216 AddDefaultExtensionValue(BOOKMARKS, &bookmark_specs); |
| 1217 e1.Put(SPECIFICS, bookmark_specs); |
| 1218 e1.Put(SERVER_SPECIFICS, bookmark_specs); |
| 1219 e1.Put(ID, TestIdFactory::FromNumber(101)); |
| 1220 EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); |
| 1221 EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
| 1222 } |
| 1223 ASSERT_TRUE(dir_->SaveChanges()); |
| 1224 |
| 1225 // Now do some operations using a directory for which SaveChanges will |
| 1226 // always fail. |
| 1227 dir_.reset(new TestUnsaveableDirectory()); |
| 1228 ASSERT_TRUE(dir_.get()); |
| 1229 ASSERT_TRUE(OPENED == dir_->Open(FilePath(kFilePath), kName)); |
| 1230 ASSERT_TRUE(dir_->good()); |
| 1231 |
| 1232 ModelTypeSet set; |
| 1233 set.insert(BOOKMARKS); |
| 1234 dir_->PurgeEntriesWithTypeIn(set); |
| 1235 EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); |
| 1236 ASSERT_FALSE(dir_->SaveChanges()); |
| 1237 EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); |
| 1238 } |
| 1239 |
1158 // Create items of each model type, and check that GetModelType and | 1240 // Create items of each model type, and check that GetModelType and |
1159 // GetServerModelType return the right value. | 1241 // GetServerModelType return the right value. |
1160 TEST_F(SyncableDirectoryTest, GetModelType) { | 1242 TEST_F(SyncableDirectoryTest, GetModelType) { |
1161 TestIdFactory id_factory; | 1243 TestIdFactory id_factory; |
1162 for (int i = 0; i < MODEL_TYPE_COUNT; ++i) { | 1244 for (int i = 0; i < MODEL_TYPE_COUNT; ++i) { |
1163 ModelType datatype = ModelTypeFromInt(i); | 1245 ModelType datatype = ModelTypeFromInt(i); |
1164 SCOPED_TRACE(testing::Message("Testing model type ") << datatype); | 1246 SCOPED_TRACE(testing::Message("Testing model type ") << datatype); |
1165 switch (datatype) { | 1247 switch (datatype) { |
1166 case UNSPECIFIED: | 1248 case UNSPECIFIED: |
1167 case TOP_LEVEL_FOLDER: | 1249 case TOP_LEVEL_FOLDER: |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 TEST_F(SyncableClientTagTest, TestClientTagIndexDuplicateServer) { | 1748 TEST_F(SyncableClientTagTest, TestClientTagIndexDuplicateServer) { |
1667 EXPECT_TRUE(CreateWithDefaultTag(factory_.NewServerId(), true)); | 1749 EXPECT_TRUE(CreateWithDefaultTag(factory_.NewServerId(), true)); |
1668 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), true)); | 1750 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), true)); |
1669 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), false)); | 1751 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), false)); |
1670 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), false)); | 1752 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), false)); |
1671 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), true)); | 1753 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), true)); |
1672 } | 1754 } |
1673 | 1755 |
1674 } // namespace | 1756 } // namespace |
1675 } // namespace syncable | 1757 } // namespace syncable |
OLD | NEW |