Chromium Code Reviews| Index: chrome/browser/sync/test/integration/single_client_directory_sync_test.cc |
| diff --git a/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc b/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc |
| index 14d9d2a9ec7bd6eb27c411c1e57f36ea609d9a35..46503b17282b91ee8dacdc677488fff32c2ab230 100644 |
| --- a/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc |
| +++ b/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc |
| @@ -4,13 +4,23 @@ |
| #include "base/message_loop/message_loop.h" |
| #include "base/run_loop.h" |
| +#include "base/strings/string_number_conversions.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/sync/profile_sync_service.h" |
| +#include "chrome/browser/sync/test/integration/bookmarks_helper.h" |
| +#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" |
| +#include "chrome/browser/sync/test/integration/sync_integration_test_util.h" |
| #include "chrome/browser/sync/test/integration/sync_test.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "sync/syncable/directory.h" |
| +#include "sync/test/directory_backing_store_corruption_testing.h" |
| +#include "url/gurl.h" |
| using content::BrowserThread; |
| +using sync_integration_test_util::AwaitCommitActivityCompletion; |
| +using syncer::syncable::corruption_testing::kNumEntriesRequiredForCorruption; |
| +using syncer::syncable::corruption_testing::CorruptDatabase; |
| class SingleClientDirectorySyncTest : public SyncTest { |
| public: |
| @@ -32,6 +42,21 @@ bool WaitForExistingTasksOnLoop(base::MessageLoop* loop) { |
| return e.TimedWait(base::TimeDelta::FromSeconds(45)); |
| } |
| +// A status change checker that waits for an unrecoverable sync error to occur. |
| +class SyncUnrecoverableErrorChecker : public SingleClientStatusChangeChecker { |
| + public: |
| + explicit SyncUnrecoverableErrorChecker(ProfileSyncService* service) |
| + : SingleClientStatusChangeChecker(service) {} |
| + |
| + bool IsExitConditionSatisfied() override { |
| + return service()->HasUnrecoverableError(); |
| + } |
| + |
| + std::string GetDebugMessage() const override { |
| + return "Sync Unrecoverable Error"; |
| + } |
| +}; |
| + |
| IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest, |
| StopThenDisableDeletesDirectory) { |
| ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; |
| @@ -51,3 +76,58 @@ IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest, |
| ASSERT_FALSE(base::DirectoryExists(directory_path)); |
| } |
| + |
| +// Verify that when the sync directory's backing store becomes corrupted, we |
| +// trigger an unrecoverable error and delete the database. |
| +// |
| +// If this test fails, see the definition of kNumEntriesRequiredForCorruption |
| +// for one possible cause. |
| +IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest, |
| + DeleteDirectoryWhenCorrupted) { |
| + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; |
| + |
| + // Create some bookmarks. |
| + const GURL url("https://www.google.com"); |
| + const bookmarks::BookmarkNode* top = bookmarks_helper::AddFolder( |
| + 0, bookmarks_helper::GetOtherNode(0), 0, "top"); |
| + for (int i = 0; i < kNumEntriesRequiredForCorruption; ++i) { |
| + ASSERT_TRUE( |
| + bookmarks_helper::AddURL(0, top, 0, base::Int64ToString(i), url)); |
| + } |
| + |
| + // Sync and wait for syncing to complete. |
| + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; |
| + ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); |
| + ASSERT_TRUE(bookmarks_helper::ModelMatchesVerifier(0)); |
| + |
| + // Flush the directory to the backing store and wait until the flush |
| + // completes. |
| + ProfileSyncService* sync_service = GetSyncService(0); |
| + sync_service->FlushDirectory(); |
| + base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest(); |
| + ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); |
| + |
| + // Now corrupt the database. |
| + const base::FilePath directory_path(sync_service->GetDirectoryPathForTest()); |
| + const base::FilePath sync_db(directory_path.Append( |
| + syncer::syncable::Directory::kSyncDatabaseFilename)); |
| + ASSERT_TRUE(CorruptDatabase(sync_db)); |
| + |
| + // Write a bunch more bookmarks to ensure the sync DB notices the corruption. |
|
pval...(no longer on Chromium)
2015/04/27 19:09:34
Re: "sync DB notices the corruption"
Does this ha
maniscalco
2015/04/27 19:16:41
Good point. Flushing the directory is an importan
|
| + for (int i = 0; i < kNumEntriesRequiredForCorruption; ++i) { |
| + ASSERT_TRUE( |
| + bookmarks_helper::AddURL(0, top, 0, base::Int64ToString(i), url)); |
| + } |
| + sync_service->FlushDirectory(); |
| + |
| + // Wait for an unrecoverable error to occur. |
| + SyncUnrecoverableErrorChecker checker(sync_service); |
| + checker.Wait(); |
| + ASSERT_TRUE(!checker.TimedOut()); |
| + ASSERT_TRUE(sync_service->HasUnrecoverableError()); |
| + |
| + // Wait until the sync loop has processed any existing tasks and see that the |
| + // directory no longer exists. |
| + ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); |
| + ASSERT_FALSE(base::DirectoryExists(directory_path)); |
| +} |