Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 ExpectDictBooleanValue(true, *value, "good"); | 385 ExpectDictBooleanValue(true, *value, "good"); |
| 386 EXPECT_TRUE(value->HasKey("kernel")); | 386 EXPECT_TRUE(value->HasKey("kernel")); |
| 387 ExpectDictStringValue("Unspecified", *value, "modelType"); | 387 ExpectDictStringValue("Unspecified", *value, "modelType"); |
| 388 ExpectDictBooleanValue(true, *value, "existsOnClientBecauseNameIsNonEmpty"); | 388 ExpectDictBooleanValue(true, *value, "existsOnClientBecauseNameIsNonEmpty"); |
| 389 ExpectDictBooleanValue(false, *value, "isRoot"); | 389 ExpectDictBooleanValue(false, *value, "isRoot"); |
| 390 } | 390 } |
| 391 | 391 |
| 392 dir.SaveChanges(); | 392 dir.SaveChanges(); |
| 393 } | 393 } |
| 394 | 394 |
| 395 // A Directory whose backing store always fails SaveChanges by returning false. | |
| 396 class TestUnsaveableDirectory : public Directory { | |
| 397 public: | |
| 398 class UnsaveableBackingStore : public OnDiskDirectoryBackingStore { | |
| 399 public: | |
| 400 UnsaveableBackingStore(const std::string& dir_name, | |
| 401 const FilePath& backing_filepath) | |
| 402 : OnDiskDirectoryBackingStore(dir_name, backing_filepath) { } | |
| 403 virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot) { | |
| 404 return false; | |
| 405 } | |
| 406 }; | |
| 407 | |
| 408 TestUnsaveableDirectory(const std::string& dir_name, | |
| 409 const FilePath& backing_filepath) | |
| 410 : Directory(&encryptor_, &handler_, NULL, | |
| 411 new UnsaveableBackingStore(dir_name, backing_filepath)) {} | |
| 412 private: | |
| 413 FakeEncryptor encryptor_; | |
| 414 TestUnrecoverableErrorHandler handler_; | |
| 415 }; | |
| 416 | |
| 417 // A test fixture for syncable::Directory. Uses an in-memory database to keep | 395 // A test fixture for syncable::Directory. Uses an in-memory database to keep |
| 418 // the unit tests fast. | 396 // the unit tests fast. |
| 419 class SyncableDirectoryTest : public testing::Test { | 397 class SyncableDirectoryTest : public testing::Test { |
| 420 protected: | 398 protected: |
| 421 MessageLoop message_loop_; | 399 MessageLoop message_loop_; |
| 422 static const char kName[]; | 400 static const char kName[]; |
| 423 | 401 |
| 424 virtual void SetUp() { | 402 virtual void SetUp() { |
| 425 dir_.reset(new Directory(&encryptor_, &handler_, NULL, | 403 dir_.reset(new Directory(&encryptor_, &handler_, NULL, |
| 426 new InMemoryDirectoryBackingStore(kName))); | 404 new InMemoryDirectoryBackingStore(kName))); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 bool is_del); | 491 bool is_del); |
| 514 | 492 |
| 515 // When a directory is saved then loaded from disk, it will pass through | 493 // When a directory is saved then loaded from disk, it will pass through |
| 516 // DropDeletedEntries(). This will remove some entries from the directory. | 494 // DropDeletedEntries(). This will remove some entries from the directory. |
| 517 // This function is intended to simulate that process. | 495 // This function is intended to simulate that process. |
| 518 // | 496 // |
| 519 // WARNING: The directory will be deleted by this operation. You should | 497 // WARNING: The directory will be deleted by this operation. You should |
| 520 // not have any pointers to the directory (open transactions included) | 498 // not have any pointers to the directory (open transactions included) |
| 521 // when you call this. | 499 // when you call this. |
| 522 DirOpenResult SimulateSaveAndReloadDir(); | 500 DirOpenResult SimulateSaveAndReloadDir(); |
| 501 | |
| 502 // This function will close and re-open the directory without saving any | |
| 503 // pending changes. This is intended to simulate the recovery from a crash | |
| 504 // scenario. The same warnings for SimulateSaveAndReloadDir apply here. | |
| 505 DirOpenResult SimulateCrashAndReloadDir(); | |
| 506 | |
| 507 private: | |
| 508 // A helper function for Simulate{Save,Crash}AndReloadDir. | |
| 509 DirOpenResult ReloadDirImpl(); | |
| 523 }; | 510 }; |
| 524 | 511 |
| 525 TEST_F(SyncableDirectoryTest, TakeSnapshotGetsMetahandlesToPurge) { | 512 TEST_F(SyncableDirectoryTest, TakeSnapshotGetsMetahandlesToPurge) { |
| 526 const int metas_to_create = 50; | 513 const int metas_to_create = 50; |
| 527 MetahandleSet expected_purges; | 514 MetahandleSet expected_purges; |
| 528 MetahandleSet all_handles; | 515 MetahandleSet all_handles; |
| 529 { | 516 { |
| 530 WriteTransaction trans(FROM_HERE, UNITTEST, dir_.get()); | 517 WriteTransaction trans(FROM_HERE, UNITTEST, dir_.get()); |
| 531 for (int i = 0; i < metas_to_create; i++) { | 518 for (int i = 0; i < metas_to_create; i++) { |
| 532 MutableEntry e(&trans, CREATE, trans.root_id(), "foo"); | 519 MutableEntry e(&trans, CREATE, trans.root_id(), "foo"); |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1254 ChangeEntryIDAndUpdateChildren(&trans, &parent, id_factory.NewServerId()); | 1241 ChangeEntryIDAndUpdateChildren(&trans, &parent, id_factory.NewServerId()); |
| 1255 parent.Put(IS_UNSYNCED, false); | 1242 parent.Put(IS_UNSYNCED, false); |
| 1256 parent.Put(BASE_VERSION, 1); | 1243 parent.Put(BASE_VERSION, 1); |
| 1257 parent.Put(SERVER_VERSION, 1); | 1244 parent.Put(SERVER_VERSION, 1); |
| 1258 } | 1245 } |
| 1259 | 1246 |
| 1260 // Final check for validity. | 1247 // Final check for validity. |
| 1261 EXPECT_EQ(OPENED, SimulateSaveAndReloadDir()); | 1248 EXPECT_EQ(OPENED, SimulateSaveAndReloadDir()); |
| 1262 } | 1249 } |
| 1263 | 1250 |
| 1251 // Ask the directory to generate a unique ID. Close and re-open the database | |
| 1252 // without saving, then ask for another unique ID. Verify IDs are not reused. | |
| 1253 // This scenario simulates a crash within the first few seconds of operation. | |
| 1254 TEST_F(SyncableDirectoryTest, LocalIdReuseTest) { | |
| 1255 Id pre_crash_id = dir_->NextId(); | |
| 1256 SimulateCrashAndReloadDir(); | |
| 1257 Id post_crash_id = dir_->NextId(); | |
| 1258 EXPECT_NE(pre_crash_id, post_crash_id); | |
| 1259 } | |
| 1260 | |
| 1261 // Ask the directory to generate a unique ID. Save the directory. Close and | |
| 1262 // re-open the database without saving, then ask for another unique ID. Verify | |
| 1263 // IDs are not reused. This scenario simulates a steady-state crash. | |
| 1264 TEST_F(SyncableDirectoryTest, LocalIdReuseTestWithSave) { | |
| 1265 Id pre_crash_id = dir_->NextId(); | |
| 1266 dir_->SaveChanges(); | |
| 1267 SimulateCrashAndReloadDir(); | |
| 1268 Id post_crash_id = dir_->NextId(); | |
| 1269 EXPECT_NE(pre_crash_id, post_crash_id); | |
| 1270 } | |
| 1271 | |
| 1264 // Ensure that the unsynced, is_del and server unkown entries that may have been | 1272 // Ensure that the unsynced, is_del and server unkown entries that may have been |
| 1265 // left in the database by old clients will be deleted when we open the old | 1273 // left in the database by old clients will be deleted when we open the old |
| 1266 // database. | 1274 // database. |
| 1267 TEST_F(SyncableDirectoryTest, OldClientLeftUnsyncedDeletedLocalItem) { | 1275 TEST_F(SyncableDirectoryTest, OldClientLeftUnsyncedDeletedLocalItem) { |
| 1268 // We must create an entry with the offending properties. This is done with | 1276 // We must create an entry with the offending properties. This is done with |
| 1269 // some abuse of the MutableEntry's API; it doesn't expect us to modify an | 1277 // some abuse of the MutableEntry's API; it doesn't expect us to modify an |
| 1270 // item after it is deleted. If this hack becomes impractical we will need to | 1278 // item after it is deleted. If this hack becomes impractical we will need to |
| 1271 // find a new way to simulate this scenario. | 1279 // find a new way to simulate this scenario. |
| 1272 | 1280 |
| 1273 TestIdFactory id_factory; | 1281 TestIdFactory id_factory; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1326 EXPECT_TRUE(server_knows.good()); | 1334 EXPECT_TRUE(server_knows.good()); |
| 1327 | 1335 |
| 1328 Entry not_is_del(&trans, GET_BY_ID, not_is_del_id); | 1336 Entry not_is_del(&trans, GET_BY_ID, not_is_del_id); |
| 1329 EXPECT_TRUE(not_is_del.good()); | 1337 EXPECT_TRUE(not_is_del.good()); |
| 1330 | 1338 |
| 1331 Entry zombie(&trans, GET_BY_ID, zombie_id); | 1339 Entry zombie(&trans, GET_BY_ID, zombie_id); |
| 1332 EXPECT_FALSE(zombie.good()); | 1340 EXPECT_FALSE(zombie.good()); |
| 1333 } | 1341 } |
| 1334 } | 1342 } |
| 1335 | 1343 |
| 1344 // An OnDirectoryBackingStore that can be set to always fail SaveChanges. | |
| 1345 class TestBackingStore : public OnDiskDirectoryBackingStore { | |
| 1346 public: | |
| 1347 TestBackingStore(const std::string& dir_name, | |
| 1348 const FilePath& backing_filepath); | |
| 1349 | |
| 1350 virtual ~TestBackingStore(); | |
| 1351 | |
| 1352 virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot) | |
| 1353 OVERRIDE; | |
| 1354 | |
| 1355 void StartFailingSaveChanges() { | |
| 1356 fail_save_changes_ = true; | |
| 1357 } | |
| 1358 | |
| 1359 private: | |
| 1360 bool fail_save_changes_; | |
| 1361 }; | |
| 1362 | |
| 1363 TestBackingStore::TestBackingStore(const std::string& dir_name, | |
| 1364 const FilePath& backing_filepath) | |
| 1365 : OnDiskDirectoryBackingStore(dir_name, backing_filepath), | |
| 1366 fail_save_changes_(false) { | |
| 1367 } | |
| 1368 | |
| 1369 TestBackingStore::~TestBackingStore() { } | |
| 1370 | |
| 1371 bool TestBackingStore::SaveChanges( | |
| 1372 const Directory::SaveChangesSnapshot& snapshot){ | |
| 1373 if (fail_save_changes_) { | |
| 1374 return false; | |
| 1375 } else { | |
| 1376 return OnDiskDirectoryBackingStore::SaveChanges(snapshot); | |
| 1377 } | |
| 1378 } | |
| 1379 | |
| 1380 // A directory whose Save() function can be set to always fail. | |
| 1381 class TestDirectory : public Directory { | |
| 1382 public: | |
| 1383 // A factory function used to work around some initialization order issues. | |
| 1384 static TestDirectory* Create( | |
| 1385 Encryptor *encryptor, | |
| 1386 UnrecoverableErrorHandler *handler, | |
| 1387 const std::string& dir_name, | |
| 1388 const FilePath& backing_filepath); | |
| 1389 | |
| 1390 virtual ~TestDirectory(); | |
| 1391 | |
| 1392 void StartFailingSaveChanges() { | |
| 1393 backing_store_->StartFailingSaveChanges(); | |
| 1394 } | |
| 1395 | |
| 1396 private: | |
| 1397 TestDirectory(Encryptor* encryptor, | |
| 1398 UnrecoverableErrorHandler* handler, | |
| 1399 TestBackingStore* backing_store); | |
| 1400 | |
| 1401 TestBackingStore* backing_store_; | |
| 1402 }; | |
| 1403 | |
| 1404 TestDirectory* TestDirectory::Create( | |
| 1405 Encryptor *encryptor, | |
| 1406 UnrecoverableErrorHandler *handler, | |
| 1407 const std::string& dir_name, | |
| 1408 const FilePath& backing_filepath) { | |
| 1409 TestBackingStore* backing_store = | |
| 1410 new TestBackingStore(dir_name, backing_filepath); | |
| 1411 return new TestDirectory(encryptor, handler, backing_store); | |
| 1412 } | |
| 1413 | |
| 1414 TestDirectory::TestDirectory(Encryptor* encryptor, | |
| 1415 UnrecoverableErrorHandler* handler, | |
| 1416 TestBackingStore* backing_store) | |
| 1417 : Directory(encryptor, handler, NULL, backing_store), | |
| 1418 backing_store_(backing_store) { | |
| 1419 } | |
| 1420 | |
| 1421 TestDirectory::~TestDirectory() { } | |
| 1422 | |
| 1423 TEST(OnDiskSyncableDirectory, FailInitialWrite) { | |
| 1424 FakeEncryptor encryptor; | |
| 1425 TestUnrecoverableErrorHandler handler; | |
| 1426 ScopedTempDir temp_dir; | |
| 1427 FilePath file_path = temp_dir.path().Append("Test.sqlite3"); | |
| 1428 std::string name = "user@x.com"; | |
| 1429 NullDirectoryChangeDelegate delegate; | |
| 1430 | |
| 1431 scoped_ptr<TestDirectory> test_dir( | |
| 1432 TestDirectory::Create(&encryptor, &handler, name, file_path)); | |
| 1433 | |
| 1434 test_dir->StartFailingSaveChanges(); | |
| 1435 ASSERT_EQ(FAILED_INITIAL_WRITE, test_dir->Open(name, &delegate, | |
| 1436 NullTransactionObserver())); | |
| 1437 } | |
| 1438 | |
| 1336 // A variant of SyncableDirectoryTest that uses a real sqlite database. | 1439 // A variant of SyncableDirectoryTest that uses a real sqlite database. |
| 1337 class OnDiskSyncableDirectoryTest : public SyncableDirectoryTest { | 1440 class OnDiskSyncableDirectoryTest : public SyncableDirectoryTest { |
| 1338 protected: | 1441 protected: |
| 1339 // SetUp() is called before each test case is run. | 1442 // SetUp() is called before each test case is run. |
| 1340 // The sqlite3 DB is deleted before each test is run. | 1443 // The sqlite3 DB is deleted before each test is run. |
| 1341 virtual void SetUp() { | 1444 virtual void SetUp() { |
| 1342 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 1445 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 1343 file_path_ = temp_dir_.path().Append( | 1446 file_path_ = temp_dir_.path().Append( |
| 1344 FILE_PATH_LITERAL("Test.sqlite3")); | 1447 FILE_PATH_LITERAL("Test.sqlite3")); |
| 1345 file_util::Delete(file_path_, true); | 1448 file_util::Delete(file_path_, true); |
| 1346 dir_.reset(new Directory(&encryptor_, &handler_, NULL, | 1449 |
| 1347 new OnDiskDirectoryBackingStore(kName, file_path_))); | 1450 CreateDirectory(); |
| 1348 ASSERT_TRUE(dir_.get()); | |
| 1349 ASSERT_EQ(OPENED, dir_->Open(kName, &delegate_, | 1451 ASSERT_EQ(OPENED, dir_->Open(kName, &delegate_, |
|
Nicolas Zea
2012/08/21 01:08:56
This can be removed.
rlarocque
2012/08/21 18:27:29
Done.
| |
| 1350 NullTransactionObserver())); | 1452 NullTransactionObserver())); |
| 1351 ASSERT_TRUE(dir_->good()); | 1453 ASSERT_TRUE(dir_->good()); |
|
Nicolas Zea
2012/08/21 01:08:56
Move into CreateDirectory()?
rlarocque
2012/08/21 18:27:29
Done.
| |
| 1352 } | 1454 } |
| 1353 | 1455 |
| 1354 virtual void TearDown() { | 1456 virtual void TearDown() { |
| 1355 // This also closes file handles. | 1457 // This also closes file handles. |
| 1356 dir_->SaveChanges(); | 1458 dir_->SaveChanges(); |
| 1357 dir_.reset(); | 1459 dir_.reset(); |
| 1358 file_util::Delete(file_path_, true); | 1460 file_util::Delete(file_path_, true); |
| 1359 } | 1461 } |
| 1360 | 1462 |
| 1361 void ReloadDir() { | 1463 // Creates a new directory. Deletes the old directory, if it exists. |
| 1362 dir_.reset(new Directory(&encryptor_, &handler_, NULL, | 1464 void CreateDirectory() { |
| 1363 new OnDiskDirectoryBackingStore(kName, file_path_))); | 1465 test_directory_ = |
| 1466 TestDirectory::Create(&encryptor_, &handler_, kName, file_path_); | |
| 1467 dir_.reset(test_directory_); | |
| 1364 ASSERT_TRUE(dir_.get()); | 1468 ASSERT_TRUE(dir_.get()); |
| 1365 ASSERT_EQ(OPENED, dir_->Open(kName, &delegate_, | 1469 ASSERT_EQ(OPENED, dir_->Open(kName, &delegate_, |
| 1366 NullTransactionObserver())); | 1470 NullTransactionObserver())); |
| 1367 } | 1471 } |
| 1368 | 1472 |
| 1369 void SaveAndReloadDir() { | 1473 void SaveAndReloadDir() { |
| 1370 dir_->SaveChanges(); | 1474 dir_->SaveChanges(); |
| 1371 ReloadDir(); | 1475 CreateDirectory(); |
| 1372 } | 1476 } |
| 1373 | 1477 |
| 1374 void SwapInUnsaveableDirectory() { | 1478 void StartFailingSaveChanges() { |
| 1375 dir_.reset(); // Delete the old directory. | 1479 test_directory_->StartFailingSaveChanges(); |
| 1376 | |
| 1377 // We first assign the object to a pointer of type TestUnsaveableDirectory | |
| 1378 // because the OpenUnsaveable function is not available in the parent class. | |
| 1379 scoped_ptr<TestUnsaveableDirectory> dir(new TestUnsaveableDirectory( | |
| 1380 kName, file_path_)); | |
| 1381 ASSERT_TRUE(dir.get()); | |
| 1382 ASSERT_EQ(OPENED, dir->Open(kName, &delegate_, NullTransactionObserver())); | |
| 1383 | |
| 1384 // Finally, move the unsaveable directory to the dir_ variable. | |
| 1385 dir_ = dir.Pass(); | |
| 1386 } | 1480 } |
| 1387 | 1481 |
| 1482 TestDirectory *test_directory_; // mirrors scoped_ptr<Directory> dir_ | |
| 1388 ScopedTempDir temp_dir_; | 1483 ScopedTempDir temp_dir_; |
| 1389 FilePath file_path_; | 1484 FilePath file_path_; |
| 1390 }; | 1485 }; |
| 1391 | 1486 |
| 1392 TEST_F(OnDiskSyncableDirectoryTest, TestPurgeEntriesWithTypeIn) { | 1487 TEST_F(OnDiskSyncableDirectoryTest, TestPurgeEntriesWithTypeIn) { |
| 1393 sync_pb::EntitySpecifics bookmark_specs; | 1488 sync_pb::EntitySpecifics bookmark_specs; |
| 1394 sync_pb::EntitySpecifics autofill_specs; | 1489 sync_pb::EntitySpecifics autofill_specs; |
| 1395 sync_pb::EntitySpecifics preference_specs; | 1490 sync_pb::EntitySpecifics preference_specs; |
| 1396 AddDefaultFieldValue(BOOKMARKS, &bookmark_specs); | 1491 AddDefaultFieldValue(BOOKMARKS, &bookmark_specs); |
| 1397 AddDefaultFieldValue(PREFERENCES, &preference_specs); | 1492 AddDefaultFieldValue(PREFERENCES, &preference_specs); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1608 MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); | 1703 MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); |
| 1609 ASSERT_TRUE(aguilera.good()); | 1704 ASSERT_TRUE(aguilera.good()); |
| 1610 EXPECT_FALSE(aguilera.GetKernelCopy().is_dirty()); | 1705 EXPECT_FALSE(aguilera.GetKernelCopy().is_dirty()); |
| 1611 EXPECT_EQ(aguilera.Get(NON_UNIQUE_NAME), "aguilera"); | 1706 EXPECT_EQ(aguilera.Get(NON_UNIQUE_NAME), "aguilera"); |
| 1612 aguilera.Put(NON_UNIQUE_NAME, "overwritten"); | 1707 aguilera.Put(NON_UNIQUE_NAME, "overwritten"); |
| 1613 EXPECT_TRUE(aguilera.GetKernelCopy().is_dirty()); | 1708 EXPECT_TRUE(aguilera.GetKernelCopy().is_dirty()); |
| 1614 EXPECT_TRUE(IsInDirtyMetahandles(handle1)); | 1709 EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
| 1615 } | 1710 } |
| 1616 ASSERT_TRUE(dir_->SaveChanges()); | 1711 ASSERT_TRUE(dir_->SaveChanges()); |
| 1617 | 1712 |
| 1618 // Now do some operations using a directory for which SaveChanges will | 1713 // Now do some operations when SaveChanges() will fail. |
| 1619 // always fail. | 1714 StartFailingSaveChanges(); |
| 1620 SwapInUnsaveableDirectory(); | |
| 1621 ASSERT_TRUE(dir_->good()); | 1715 ASSERT_TRUE(dir_->good()); |
| 1622 | 1716 |
| 1623 int64 handle2 = 0; | 1717 int64 handle2 = 0; |
| 1624 { | 1718 { |
| 1625 WriteTransaction trans(FROM_HERE, UNITTEST, dir_.get()); | 1719 WriteTransaction trans(FROM_HERE, UNITTEST, dir_.get()); |
| 1626 | 1720 |
| 1627 MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); | 1721 MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); |
| 1628 ASSERT_TRUE(aguilera.good()); | 1722 ASSERT_TRUE(aguilera.good()); |
| 1629 EXPECT_FALSE(aguilera.GetKernelCopy().is_dirty()); | 1723 EXPECT_FALSE(aguilera.GetKernelCopy().is_dirty()); |
| 1630 EXPECT_EQ(aguilera.Get(NON_UNIQUE_NAME), "overwritten"); | 1724 EXPECT_EQ(aguilera.Get(NON_UNIQUE_NAME), "overwritten"); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1680 sync_pb::EntitySpecifics bookmark_specs; | 1774 sync_pb::EntitySpecifics bookmark_specs; |
| 1681 AddDefaultFieldValue(BOOKMARKS, &bookmark_specs); | 1775 AddDefaultFieldValue(BOOKMARKS, &bookmark_specs); |
| 1682 e1.Put(SPECIFICS, bookmark_specs); | 1776 e1.Put(SPECIFICS, bookmark_specs); |
| 1683 e1.Put(SERVER_SPECIFICS, bookmark_specs); | 1777 e1.Put(SERVER_SPECIFICS, bookmark_specs); |
| 1684 e1.Put(ID, TestIdFactory::FromNumber(101)); | 1778 e1.Put(ID, TestIdFactory::FromNumber(101)); |
| 1685 EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); | 1779 EXPECT_TRUE(e1.GetKernelCopy().is_dirty()); |
| 1686 EXPECT_TRUE(IsInDirtyMetahandles(handle1)); | 1780 EXPECT_TRUE(IsInDirtyMetahandles(handle1)); |
| 1687 } | 1781 } |
| 1688 ASSERT_TRUE(dir_->SaveChanges()); | 1782 ASSERT_TRUE(dir_->SaveChanges()); |
| 1689 | 1783 |
| 1690 // Now do some operations using a directory for which SaveChanges will | 1784 // Now do some operations while SaveChanges() is set to fail. |
| 1691 // always fail. | 1785 StartFailingSaveChanges(); |
| 1692 SwapInUnsaveableDirectory(); | |
| 1693 ASSERT_TRUE(dir_->good()); | 1786 ASSERT_TRUE(dir_->good()); |
| 1694 | 1787 |
| 1695 ModelTypeSet set(BOOKMARKS); | 1788 ModelTypeSet set(BOOKMARKS); |
| 1696 dir_->PurgeEntriesWithTypeIn(set); | 1789 dir_->PurgeEntriesWithTypeIn(set); |
| 1697 EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); | 1790 EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); |
| 1698 ASSERT_FALSE(dir_->SaveChanges()); | 1791 ASSERT_FALSE(dir_->SaveChanges()); |
| 1699 EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); | 1792 EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); |
| 1700 } | 1793 } |
| 1701 | 1794 |
| 1702 } // namespace | 1795 } // namespace |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1714 ASSERT_TRUE(name == e.Get(NON_UNIQUE_NAME)); | 1807 ASSERT_TRUE(name == e.Get(NON_UNIQUE_NAME)); |
| 1715 ASSERT_TRUE(base_version == e.Get(BASE_VERSION)); | 1808 ASSERT_TRUE(base_version == e.Get(BASE_VERSION)); |
| 1716 ASSERT_TRUE(server_version == e.Get(SERVER_VERSION)); | 1809 ASSERT_TRUE(server_version == e.Get(SERVER_VERSION)); |
| 1717 ASSERT_TRUE(is_del == e.Get(IS_DEL)); | 1810 ASSERT_TRUE(is_del == e.Get(IS_DEL)); |
| 1718 } | 1811 } |
| 1719 | 1812 |
| 1720 DirOpenResult SyncableDirectoryTest::SimulateSaveAndReloadDir() { | 1813 DirOpenResult SyncableDirectoryTest::SimulateSaveAndReloadDir() { |
| 1721 if (!dir_->SaveChanges()) | 1814 if (!dir_->SaveChanges()) |
| 1722 return FAILED_IN_UNITTEST; | 1815 return FAILED_IN_UNITTEST; |
| 1723 | 1816 |
| 1817 return ReloadDirImpl(); | |
| 1818 } | |
| 1819 | |
| 1820 DirOpenResult SyncableDirectoryTest::SimulateCrashAndReloadDir() { | |
| 1821 return ReloadDirImpl(); | |
| 1822 } | |
| 1823 | |
| 1824 DirOpenResult SyncableDirectoryTest::ReloadDirImpl() { | |
| 1724 // Do some tricky things to preserve the backing store. | 1825 // Do some tricky things to preserve the backing store. |
| 1725 DirectoryBackingStore* saved_store = dir_->store_.release(); | 1826 DirectoryBackingStore* saved_store = dir_->store_.release(); |
| 1726 | 1827 |
| 1727 // Close the current directory. | 1828 // Close the current directory. |
| 1728 dir_->Close(); | 1829 dir_->Close(); |
| 1729 dir_.reset(); | 1830 dir_.reset(); |
| 1730 | 1831 |
| 1731 dir_.reset(new Directory(&encryptor_, &handler_, NULL, saved_store)); | 1832 dir_.reset(new Directory(&encryptor_, &handler_, NULL, saved_store)); |
| 1732 DirOpenResult result = dir_->OpenImpl(kName, &delegate_, | 1833 DirOpenResult result = dir_->OpenImpl(kName, &delegate_, |
| 1733 NullTransactionObserver()); | 1834 NullTransactionObserver()); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1940 EXPECT_TRUE(CreateWithDefaultTag(factory_.NewServerId(), true)); | 2041 EXPECT_TRUE(CreateWithDefaultTag(factory_.NewServerId(), true)); |
| 1941 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), true)); | 2042 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), true)); |
| 1942 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), false)); | 2043 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewServerId(), false)); |
| 1943 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), false)); | 2044 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), false)); |
| 1944 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), true)); | 2045 EXPECT_FALSE(CreateWithDefaultTag(factory_.NewLocalId(), true)); |
| 1945 } | 2046 } |
| 1946 | 2047 |
| 1947 } // namespace | 2048 } // namespace |
| 1948 } // namespace syncable | 2049 } // namespace syncable |
| 1949 } // namespace syncer | 2050 } // namespace syncer |
| OLD | NEW |