OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 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 | 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 "base/files/file_enumerator.h" |
| 6 #include "base/files/file_path.h" |
5 #include "base/location.h" | 7 #include "base/location.h" |
6 #include "base/macros.h" | 8 #include "base/macros.h" |
7 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
8 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
9 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
10 #include "base/synchronization/waitable_event.h" | 12 #include "base/synchronization/waitable_event.h" |
11 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
12 #include "base/time/time.h" | 14 #include "base/time/time.h" |
13 #include "chrome/browser/sync/test/integration/bookmarks_helper.h" | 15 #include "chrome/browser/sync/test/integration/bookmarks_helper.h" |
14 #include "chrome/browser/sync/test/integration/single_client_status_change_check
er.h" | 16 #include "chrome/browser/sync/test/integration/single_client_status_change_check
er.h" |
15 #include "chrome/browser/sync/test/integration/sync_test.h" | 17 #include "chrome/browser/sync/test/integration/sync_test.h" |
16 #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h
" | 18 #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h
" |
17 #include "components/browser_sync/profile_sync_service.h" | 19 #include "components/browser_sync/profile_sync_service.h" |
18 #include "components/sync/syncable/directory.h" | 20 #include "components/sync/syncable/directory.h" |
19 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
20 #include "sql/test/test_helpers.h" | 22 #include "sql/test/test_helpers.h" |
21 #include "url/gurl.h" | 23 #include "url/gurl.h" |
22 | 24 |
23 using content::BrowserThread; | 25 using content::BrowserThread; |
| 26 using base::FileEnumerator; |
| 27 using base::FilePath; |
| 28 |
| 29 namespace { |
| 30 |
| 31 // USS ModelTypeStore uses the same folder as the Directory. However, all of its |
| 32 // content is in a sub-folder. By not asking for recursive files, this function |
| 33 // will avoid seeing any of those, and return iff Directory database files still |
| 34 // exist. |
| 35 bool FolderContainsFiles(const FilePath& folder) { |
| 36 if (base::DirectoryExists(folder)) { |
| 37 return !FileEnumerator(folder, false, FileEnumerator::FILES).Next().empty(); |
| 38 } else { |
| 39 return false; |
| 40 } |
| 41 } |
24 | 42 |
25 class SingleClientDirectorySyncTest : public SyncTest { | 43 class SingleClientDirectorySyncTest : public SyncTest { |
26 public: | 44 public: |
27 SingleClientDirectorySyncTest() : SyncTest(SINGLE_CLIENT) {} | 45 SingleClientDirectorySyncTest() : SyncTest(SINGLE_CLIENT) {} |
28 ~SingleClientDirectorySyncTest() override {} | 46 ~SingleClientDirectorySyncTest() override {} |
29 | 47 |
30 private: | 48 private: |
31 DISALLOW_COPY_AND_ASSIGN(SingleClientDirectorySyncTest); | 49 DISALLOW_COPY_AND_ASSIGN(SingleClientDirectorySyncTest); |
32 }; | 50 }; |
33 | 51 |
(...skipping 22 matching lines...) Expand all Loading... |
56 | 74 |
57 std::string GetDebugMessage() const override { | 75 std::string GetDebugMessage() const override { |
58 return "Sync Unrecoverable Error"; | 76 return "Sync Unrecoverable Error"; |
59 } | 77 } |
60 }; | 78 }; |
61 | 79 |
62 IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest, | 80 IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest, |
63 StopThenDisableDeletesDirectory) { | 81 StopThenDisableDeletesDirectory) { |
64 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; | 82 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; |
65 browser_sync::ProfileSyncService* sync_service = GetSyncService(0); | 83 browser_sync::ProfileSyncService* sync_service = GetSyncService(0); |
66 base::FilePath directory_path = sync_service->GetDirectoryPathForTest(); | 84 FilePath directory_path = sync_service->GetDirectoryPathForTest(); |
67 ASSERT_TRUE(base::DirectoryExists(directory_path)); | 85 ASSERT_TRUE(FolderContainsFiles(directory_path)); |
68 sync_service->RequestStop(browser_sync::ProfileSyncService::CLEAR_DATA); | 86 sync_service->RequestStop(browser_sync::ProfileSyncService::CLEAR_DATA); |
69 | 87 |
70 // Wait for StartupController::StartUp()'s tasks to finish. | 88 // Wait for StartupController::StartUp()'s tasks to finish. |
71 base::RunLoop run_loop; | 89 base::RunLoop run_loop; |
72 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 90 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
73 run_loop.QuitClosure()); | 91 run_loop.QuitClosure()); |
74 run_loop.Run(); | 92 run_loop.Run(); |
75 // Wait for the directory deletion to finish. | 93 // Wait for the directory deletion to finish. |
76 base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest(); | 94 base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest(); |
77 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); | 95 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); |
78 | 96 ASSERT_FALSE(FolderContainsFiles(directory_path)); |
79 ASSERT_FALSE(base::DirectoryExists(directory_path)); | |
80 } | 97 } |
81 | 98 |
82 // Verify that when the sync directory's backing store becomes corrupted, we | 99 // Verify that when the sync directory's backing store becomes corrupted, we |
83 // trigger an unrecoverable error and delete the database. | 100 // trigger an unrecoverable error and delete the database. |
84 // | 101 // |
85 // If this test fails, see the definition of kNumEntriesRequiredForCorruption | 102 // If this test fails, see the definition of kNumEntriesRequiredForCorruption |
86 // for one possible cause. | 103 // for one possible cause. |
87 IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest, | 104 IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest, |
88 DeleteDirectoryWhenCorrupted) { | 105 DeleteDirectoryWhenCorrupted) { |
89 ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; | 106 ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; |
90 // Sync and wait for syncing to complete. | 107 // Sync and wait for syncing to complete. |
91 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; | 108 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; |
92 ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); | 109 ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); |
93 ASSERT_TRUE(bookmarks_helper::ModelMatchesVerifier(0)); | 110 ASSERT_TRUE(bookmarks_helper::ModelMatchesVerifier(0)); |
94 | 111 |
95 // Flush the directory to the backing store and wait until the flush | 112 // Flush the directory to the backing store and wait until the flush |
96 // completes. | 113 // completes. |
97 browser_sync::ProfileSyncService* sync_service = GetSyncService(0); | 114 browser_sync::ProfileSyncService* sync_service = GetSyncService(0); |
98 sync_service->FlushDirectory(); | 115 sync_service->FlushDirectory(); |
99 base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest(); | 116 base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest(); |
100 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); | 117 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); |
101 | 118 |
102 // Now corrupt the database. | 119 // Now corrupt the database. |
103 const base::FilePath directory_path(sync_service->GetDirectoryPathForTest()); | 120 const FilePath directory_path(sync_service->GetDirectoryPathForTest()); |
104 const base::FilePath sync_db(directory_path.Append( | 121 const FilePath sync_db(directory_path.Append( |
105 syncer::syncable::Directory::kSyncDatabaseFilename)); | 122 syncer::syncable::Directory::kSyncDatabaseFilename)); |
106 ASSERT_TRUE(sql::test::CorruptSizeInHeaderWithLock(sync_db)); | 123 ASSERT_TRUE(sql::test::CorruptSizeInHeaderWithLock(sync_db)); |
107 | 124 |
108 // Write some bookmarks and flush the directory to force sync to | 125 // Write some bookmarks and flush the directory to force sync to |
109 // notice the corruption. | 126 // notice the corruption. |
110 const GURL url("https://www.example.com"); | 127 const GURL url("https://www.example.com"); |
111 const bookmarks::BookmarkNode* top = bookmarks_helper::AddFolder( | 128 const bookmarks::BookmarkNode* top = bookmarks_helper::AddFolder( |
112 0, bookmarks_helper::GetOtherNode(0), 0, "top"); | 129 0, bookmarks_helper::GetOtherNode(0), 0, "top"); |
113 for (int i = 0; i < 100; ++i) { | 130 for (int i = 0; i < 100; ++i) { |
114 ASSERT_TRUE( | 131 ASSERT_TRUE( |
115 bookmarks_helper::AddURL(0, top, 0, base::Int64ToString(i), url)); | 132 bookmarks_helper::AddURL(0, top, 0, base::Int64ToString(i), url)); |
116 } | 133 } |
117 sync_service->FlushDirectory(); | 134 sync_service->FlushDirectory(); |
118 | 135 |
119 // Wait for an unrecoverable error to occur. | 136 // Wait for an unrecoverable error to occur. |
120 ASSERT_TRUE(SyncUnrecoverableErrorChecker(sync_service).Wait()); | 137 ASSERT_TRUE(SyncUnrecoverableErrorChecker(sync_service).Wait()); |
121 ASSERT_TRUE(sync_service->HasUnrecoverableError()); | 138 ASSERT_TRUE(sync_service->HasUnrecoverableError()); |
122 | 139 |
123 // Wait until the sync loop has processed any existing tasks and see that the | 140 // Wait until the sync loop has processed any existing tasks and see that the |
124 // directory no longer exists. | 141 // directory no longer exists. |
125 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); | 142 ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop)); |
126 ASSERT_FALSE(base::DirectoryExists(directory_path)); | 143 ASSERT_FALSE(FolderContainsFiles(directory_path)); |
127 } | 144 } |
| 145 |
| 146 } // namespace |
OLD | NEW |