Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / sync_file_system / drive_backend / sync_engine_initializer_unittest.cc
blob079dc88624d5071be799b9662191d78d37629f01
1 // Copyright 2013 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 "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
7 #include "base/bind.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
12 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
13 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
14 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
15 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
16 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
17 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
18 #include "components/drive/drive_api_util.h"
19 #include "components/drive/drive_uploader.h"
20 #include "components/drive/service/fake_drive_service.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "google_apis/drive/drive_api_parser.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
25 #include "third_party/leveldatabase/src/include/leveldb/env.h"
27 namespace sync_file_system {
28 namespace drive_backend {
30 namespace {
32 const int64 kInitialLargestChangeID = 1234;
34 } // namespace
36 class SyncEngineInitializerTest : public testing::Test {
37 public:
38 struct TrackedFile {
39 scoped_ptr<google_apis::FileResource> resource;
40 FileMetadata metadata;
41 FileTracker tracker;
44 SyncEngineInitializerTest() {}
45 ~SyncEngineInitializerTest() override {}
47 void SetUp() override {
48 ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
49 in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
51 scoped_ptr<drive::FakeDriveService>
52 fake_drive_service(new drive::FakeDriveService);
53 fake_drive_service_ = fake_drive_service.get();
55 sync_context_.reset(new SyncEngineContext(
56 fake_drive_service.Pass(),
57 scoped_ptr<drive::DriveUploaderInterface>(),
58 nullptr /* task_logger */,
59 base::ThreadTaskRunnerHandle::Get(),
60 base::ThreadTaskRunnerHandle::Get(),
61 nullptr /* worker_pool */));
63 sync_task_manager_.reset(new SyncTaskManager(
64 base::WeakPtr<SyncTaskManager::Client>(),
65 1 /* maximum_parallel_task */,
66 base::ThreadTaskRunnerHandle::Get(),
67 nullptr /* worker_pool */));
68 sync_task_manager_->Initialize(SYNC_STATUS_OK);
71 void TearDown() override {
72 sync_task_manager_.reset();
73 metadata_database_.reset();
74 sync_context_.reset();
75 base::RunLoop().RunUntilIdle();
78 base::FilePath database_path() {
79 return database_dir_.path();
82 SyncStatusCode RunInitializer() {
83 SyncEngineInitializer* initializer =
84 new SyncEngineInitializer(sync_context_.get(),
85 database_path(),
86 in_memory_env_.get());
87 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
89 sync_task_manager_->ScheduleSyncTask(
90 FROM_HERE,
91 scoped_ptr<SyncTask>(initializer),
92 SyncTaskManager::PRIORITY_MED,
93 base::Bind(&SyncEngineInitializerTest::DidRunInitializer,
94 base::Unretained(this), initializer, &status));
96 base::RunLoop().RunUntilIdle();
97 return status;
100 void DidRunInitializer(SyncEngineInitializer* initializer,
101 SyncStatusCode* status_out,
102 SyncStatusCode status) {
103 *status_out = status;
104 metadata_database_ = initializer->PassMetadataDatabase();
107 SyncStatusCode PopulateDatabase(
108 const google_apis::FileResource& sync_root,
109 const google_apis::FileResource** app_roots,
110 size_t app_roots_count) {
111 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
112 scoped_ptr<MetadataDatabase> database = MetadataDatabase::Create(
113 database_path(), in_memory_env_.get(), &status);
114 if (status != SYNC_STATUS_OK)
115 return status;
117 // |app_root_list| must not own the resources here. Be sure to call
118 // weak_clear later.
119 ScopedVector<google_apis::FileResource> app_root_list;
120 for (size_t i = 0; i < app_roots_count; ++i) {
121 app_root_list.push_back(
122 const_cast<google_apis::FileResource*>(app_roots[i]));
125 status = database->PopulateInitialData(
126 kInitialLargestChangeID, sync_root, app_root_list);
128 app_root_list.weak_clear();
129 return status;
132 scoped_ptr<google_apis::FileResource> CreateRemoteFolder(
133 const std::string& parent_folder_id,
134 const std::string& title) {
135 google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
136 scoped_ptr<google_apis::FileResource> entry;
137 drive::AddNewDirectoryOptions options;
138 options.visibility = google_apis::drive::FILE_VISIBILITY_PRIVATE;
139 sync_context_->GetDriveService()->AddNewDirectory(
140 parent_folder_id, title, options,
141 CreateResultReceiver(&error, &entry));
142 base::RunLoop().RunUntilIdle();
144 EXPECT_EQ(google_apis::HTTP_CREATED, error);
145 return entry.Pass();
148 scoped_ptr<google_apis::FileResource> CreateRemoteSyncRoot() {
149 scoped_ptr<google_apis::FileResource> sync_root(
150 CreateRemoteFolder(std::string(), kSyncRootFolderTitle));
152 for (size_t i = 0; i < sync_root->parents().size(); ++i) {
153 google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
154 sync_context_->GetDriveService()->RemoveResourceFromDirectory(
155 sync_root->parents()[i].file_id(),
156 sync_root->file_id(),
157 CreateResultReceiver(&error));
158 base::RunLoop().RunUntilIdle();
159 EXPECT_EQ(google_apis::HTTP_NO_CONTENT, error);
162 return sync_root.Pass();
165 std::string GetSyncRootFolderID() {
166 int64 sync_root_tracker_id = metadata_database_->GetSyncRootTrackerID();
167 FileTracker sync_root_tracker;
168 EXPECT_TRUE(metadata_database_->FindTrackerByTrackerID(
169 sync_root_tracker_id, &sync_root_tracker));
170 return sync_root_tracker.file_id();
173 bool VerifyFolderVisibility(const std::string& folder_id) {
174 google_apis::drive::FileVisibility visibility;
175 if (google_apis::HTTP_SUCCESS !=
176 fake_drive_service_->GetFileVisibility(
177 folder_id, &visibility))
178 return false;
179 if (visibility != google_apis::drive::FILE_VISIBILITY_PRIVATE)
180 return false;
181 return true;
184 size_t CountTrackersForFile(const std::string& file_id) {
185 TrackerIDSet trackers;
186 metadata_database_->FindTrackersByFileID(file_id, &trackers);
187 return trackers.size();
190 bool HasActiveTracker(const std::string& file_id) {
191 TrackerIDSet trackers;
192 return metadata_database_->FindTrackersByFileID(file_id, &trackers) &&
193 trackers.has_active();
196 bool HasNoParent(const std::string& file_id) {
197 google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
198 scoped_ptr<google_apis::FileResource> entry;
199 sync_context_->GetDriveService()->GetFileResource(
200 file_id,
201 CreateResultReceiver(&error, &entry));
202 base::RunLoop().RunUntilIdle();
203 EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
204 return entry->parents().empty();
207 size_t CountFileMetadata() {
208 return metadata_database_->CountFileMetadata();
211 size_t CountFileTracker() {
212 return metadata_database_->CountFileTracker();
215 google_apis::DriveApiErrorCode AddParentFolder(
216 const std::string& new_parent_folder_id,
217 const std::string& file_id) {
218 google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
219 sync_context_->GetDriveService()->AddResourceToDirectory(
220 new_parent_folder_id, file_id,
221 CreateResultReceiver(&error));
222 base::RunLoop().RunUntilIdle();
223 return error;
226 private:
227 content::TestBrowserThreadBundle browser_threads_;
228 base::ScopedTempDir database_dir_;
229 scoped_ptr<leveldb::Env> in_memory_env_;
231 scoped_ptr<MetadataDatabase> metadata_database_;
232 scoped_ptr<SyncTaskManager> sync_task_manager_;
233 scoped_ptr<SyncEngineContext> sync_context_;
234 drive::FakeDriveService* fake_drive_service_ = nullptr;
236 DISALLOW_COPY_AND_ASSIGN(SyncEngineInitializerTest);
239 TEST_F(SyncEngineInitializerTest, EmptyDatabase_NoRemoteSyncRoot) {
240 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
242 std::string sync_root_folder_id = GetSyncRootFolderID();
243 EXPECT_EQ(1u, CountTrackersForFile(sync_root_folder_id));
245 EXPECT_TRUE(HasActiveTracker(sync_root_folder_id));
247 EXPECT_EQ(1u, CountFileMetadata());
248 EXPECT_EQ(1u, CountFileTracker());
249 EXPECT_TRUE(VerifyFolderVisibility(sync_root_folder_id));
252 TEST_F(SyncEngineInitializerTest, EmptyDatabase_RemoteSyncRootExists) {
253 scoped_ptr<google_apis::FileResource> sync_root(
254 CreateRemoteSyncRoot());
255 scoped_ptr<google_apis::FileResource> app_root_1(
256 CreateRemoteFolder(sync_root->file_id(), "app-root 1"));
257 scoped_ptr<google_apis::FileResource> app_root_2(
258 CreateRemoteFolder(sync_root->file_id(), "app-root 2"));
260 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
262 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
263 EXPECT_EQ(1u, CountTrackersForFile(app_root_1->file_id()));
264 EXPECT_EQ(1u, CountTrackersForFile(app_root_2->file_id()));
266 EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
267 EXPECT_FALSE(HasActiveTracker(app_root_1->file_id()));
268 EXPECT_FALSE(HasActiveTracker(app_root_2->file_id()));
270 EXPECT_EQ(3u, CountFileMetadata());
271 EXPECT_EQ(3u, CountFileTracker());
274 TEST_F(SyncEngineInitializerTest, DatabaseAlreadyInitialized) {
275 scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteSyncRoot());
276 scoped_ptr<google_apis::FileResource> app_root_1(
277 CreateRemoteFolder(sync_root->file_id(), "app-root 1"));
278 scoped_ptr<google_apis::FileResource> app_root_2(
279 CreateRemoteFolder(sync_root->file_id(), "app-root 2"));
281 const google_apis::FileResource* app_roots[] = {
282 app_root_1.get(), app_root_2.get()
284 EXPECT_EQ(SYNC_STATUS_OK,
285 PopulateDatabase(*sync_root, app_roots, arraysize(app_roots)));
287 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
289 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
290 EXPECT_EQ(1u, CountTrackersForFile(app_root_1->file_id()));
291 EXPECT_EQ(1u, CountTrackersForFile(app_root_2->file_id()));
293 EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
294 EXPECT_FALSE(HasActiveTracker(app_root_1->file_id()));
295 EXPECT_FALSE(HasActiveTracker(app_root_2->file_id()));
297 EXPECT_EQ(3u, CountFileMetadata());
298 EXPECT_EQ(3u, CountFileTracker());
301 TEST_F(SyncEngineInitializerTest, EmptyDatabase_MultiCandidate) {
302 scoped_ptr<google_apis::FileResource> sync_root_1(CreateRemoteSyncRoot());
303 scoped_ptr<google_apis::FileResource> sync_root_2(CreateRemoteSyncRoot());
305 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
307 EXPECT_EQ(1u, CountTrackersForFile(sync_root_1->file_id()));
308 EXPECT_EQ(0u, CountTrackersForFile(sync_root_2->file_id()));
310 EXPECT_TRUE(HasActiveTracker(sync_root_1->file_id()));
311 EXPECT_FALSE(HasActiveTracker(sync_root_2->file_id()));
313 EXPECT_EQ(1u, CountFileMetadata());
314 EXPECT_EQ(1u, CountFileTracker());
317 TEST_F(SyncEngineInitializerTest, EmptyDatabase_UndetachedRemoteSyncRoot) {
318 scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
319 std::string(), kSyncRootFolderTitle));
320 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
322 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
323 EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
325 EXPECT_TRUE(HasNoParent(sync_root->file_id()));
327 EXPECT_EQ(1u, CountFileMetadata());
328 EXPECT_EQ(1u, CountFileTracker());
331 TEST_F(SyncEngineInitializerTest, EmptyDatabase_MultiparentSyncRoot) {
332 scoped_ptr<google_apis::FileResource> folder(CreateRemoteFolder(
333 std::string(), "folder"));
334 scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
335 std::string(), kSyncRootFolderTitle));
336 AddParentFolder(sync_root->file_id(), folder->file_id());
338 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
340 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
341 EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
343 EXPECT_TRUE(HasNoParent(sync_root->file_id()));
345 EXPECT_EQ(1u, CountFileMetadata());
346 EXPECT_EQ(1u, CountFileTracker());
349 TEST_F(SyncEngineInitializerTest, EmptyDatabase_FakeRemoteSyncRoot) {
350 scoped_ptr<google_apis::FileResource> folder(CreateRemoteFolder(
351 std::string(), "folder"));
352 scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
353 folder->file_id(), kSyncRootFolderTitle));
355 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
357 EXPECT_EQ(0u, CountTrackersForFile(sync_root->file_id()));
358 EXPECT_FALSE(HasNoParent(sync_root->file_id()));
360 EXPECT_EQ(1u, CountFileMetadata());
361 EXPECT_EQ(1u, CountFileTracker());
364 } // namespace drive_backend
365 } // namespace sync_file_system