Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / sync / test / integration / single_client_directory_sync_test.cc
blob520742e33668c2cd6ec76b97d8007f785bc0da7c
1 // Copyright (c) 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 "base/location.h"
6 #include "base/run_loop.h"
7 #include "base/single_thread_task_runner.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/sync/profile_sync_service.h"
13 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
14 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
15 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
16 #include "chrome/browser/sync/test/integration/sync_test.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "sync/syncable/directory.h"
19 #include "sync/test/directory_backing_store_corruption_testing.h"
20 #include "url/gurl.h"
22 using content::BrowserThread;
23 using sync_integration_test_util::AwaitCommitActivityCompletion;
24 using syncer::syncable::corruption_testing::kNumEntriesRequiredForCorruption;
25 using syncer::syncable::corruption_testing::CorruptDatabase;
27 class SingleClientDirectorySyncTest : public SyncTest {
28 public:
29 SingleClientDirectorySyncTest() : SyncTest(SINGLE_CLIENT) {}
30 ~SingleClientDirectorySyncTest() override {}
32 private:
33 DISALLOW_COPY_AND_ASSIGN(SingleClientDirectorySyncTest);
36 void SignalEvent(base::WaitableEvent* e) {
37 e->Signal();
40 bool WaitForExistingTasksOnLoop(base::MessageLoop* loop) {
41 base::WaitableEvent e(true, false);
42 loop->task_runner()->PostTask(FROM_HERE, base::Bind(&SignalEvent, &e));
43 // Timeout stolen from StatusChangeChecker::GetTimeoutDuration().
44 return e.TimedWait(base::TimeDelta::FromSeconds(45));
47 // A status change checker that waits for an unrecoverable sync error to occur.
48 class SyncUnrecoverableErrorChecker : public SingleClientStatusChangeChecker {
49 public:
50 explicit SyncUnrecoverableErrorChecker(ProfileSyncService* service)
51 : SingleClientStatusChangeChecker(service) {}
53 bool IsExitConditionSatisfied() override {
54 return service()->HasUnrecoverableError();
57 std::string GetDebugMessage() const override {
58 return "Sync Unrecoverable Error";
62 IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest,
63 StopThenDisableDeletesDirectory) {
64 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
65 ProfileSyncService* sync_service = GetSyncService(0);
66 base::FilePath directory_path = sync_service->GetDirectoryPathForTest();
67 ASSERT_TRUE(base::DirectoryExists(directory_path));
68 sync_service->RequestStop(ProfileSyncService::CLEAR_DATA);
70 // Wait for StartupController::StartUp()'s tasks to finish.
71 base::RunLoop run_loop;
72 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
73 run_loop.QuitClosure());
74 run_loop.Run();
75 // Wait for the directory deletion to finish.
76 base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest();
77 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop));
79 ASSERT_FALSE(base::DirectoryExists(directory_path));
82 // Verify that when the sync directory's backing store becomes corrupted, we
83 // trigger an unrecoverable error and delete the database.
85 // If this test fails, see the definition of kNumEntriesRequiredForCorruption
86 // for one possible cause.
87 IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest,
88 DeleteDirectoryWhenCorrupted) {
89 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
90 // Sync and wait for syncing to complete.
91 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
92 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
93 ASSERT_TRUE(bookmarks_helper::ModelMatchesVerifier(0));
95 // Flush the directory to the backing store and wait until the flush
96 // completes.
97 ProfileSyncService* sync_service = GetSyncService(0);
98 sync_service->FlushDirectory();
99 base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest();
100 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop));
102 // Now corrupt the database.
103 const base::FilePath directory_path(sync_service->GetDirectoryPathForTest());
104 const base::FilePath sync_db(directory_path.Append(
105 syncer::syncable::Directory::kSyncDatabaseFilename));
106 ASSERT_TRUE(CorruptDatabase(sync_db));
108 // Write a bunch of bookmarks and flush the directory to ensure sync notices
109 // the corruption. The key here is to force sync to actually write a lot of
110 // data to its DB so it will see the corruption we introduced above.
111 const GURL url(
112 "https://"
113 "www."
114 "gooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
115 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
116 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
117 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
118 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
119 "oooooooooooooooooooogle.com");
120 const bookmarks::BookmarkNode* top = bookmarks_helper::AddFolder(
121 0, bookmarks_helper::GetOtherNode(0), 0, "top");
122 for (int i = 0; i < kNumEntriesRequiredForCorruption; ++i) {
123 ASSERT_TRUE(
124 bookmarks_helper::AddURL(0, top, 0, base::Int64ToString(i), url));
126 sync_service->FlushDirectory();
128 // Wait for an unrecoverable error to occur.
129 SyncUnrecoverableErrorChecker checker(sync_service);
130 checker.Wait();
131 ASSERT_TRUE(!checker.TimedOut());
132 ASSERT_TRUE(sync_service->HasUnrecoverableError());
134 // Wait until the sync loop has processed any existing tasks and see that the
135 // directory no longer exists.
136 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop));
137 ASSERT_FALSE(base::DirectoryExists(directory_path));