Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / drive_backend / sync_engine_initializer_unittest.cc
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.
4
5 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
6
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/drive/drive_api_util.h"
12 #include "chrome/browser/drive/drive_uploader.h"
13 #include "chrome/browser/drive/fake_drive_service.h"
14 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
15 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
16 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
17 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
18 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
19 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
20 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "google_apis/drive/drive_api_parser.h"
23 #include "google_apis/drive/gdata_wapi_parser.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
26 #include "third_party/leveldatabase/src/include/leveldb/env.h"
27
28 namespace sync_file_system {
29 namespace drive_backend {
30
31 namespace {
32
33 const int64 kInitialLargestChangeID = 1234;
34
35 }  // namespace
36
37 class SyncEngineInitializerTest : public testing::Test {
38  public:
39   struct TrackedFile {
40     scoped_ptr<google_apis::FileResource> resource;
41     FileMetadata metadata;
42     FileTracker tracker;
43   };
44
45   SyncEngineInitializerTest() {}
46   virtual ~SyncEngineInitializerTest() {}
47
48   virtual void SetUp() OVERRIDE {
49     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
50     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
51
52     scoped_ptr<drive::DriveServiceInterface>
53         fake_drive_service(new drive::FakeDriveService);
54
55     sync_context_.reset(new SyncEngineContext(
56         fake_drive_service.Pass(),
57         scoped_ptr<drive::DriveUploaderInterface>(),
58         NULL,
59         base::ThreadTaskRunnerHandle::Get(),
60         base::ThreadTaskRunnerHandle::Get()));
61
62     sync_task_manager_.reset(new SyncTaskManager(
63         base::WeakPtr<SyncTaskManager::Client>(),
64         1 /* maximum_parallel_task */,
65         base::ThreadTaskRunnerHandle::Get()));
66     sync_task_manager_->Initialize(SYNC_STATUS_OK);
67   }
68
69   virtual void TearDown() OVERRIDE {
70     sync_task_manager_.reset();
71     metadata_database_.reset();
72     sync_context_.reset();
73     base::RunLoop().RunUntilIdle();
74   }
75
76   base::FilePath database_path() {
77     return database_dir_.path();
78   }
79
80   SyncStatusCode RunInitializer() {
81     SyncEngineInitializer* initializer =
82         new SyncEngineInitializer(sync_context_.get(),
83                                   database_path(),
84                                   in_memory_env_.get());
85     SyncStatusCode status = SYNC_STATUS_UNKNOWN;
86
87     sync_task_manager_->ScheduleSyncTask(
88         FROM_HERE,
89         scoped_ptr<SyncTask>(initializer),
90         SyncTaskManager::PRIORITY_MED,
91         base::Bind(&SyncEngineInitializerTest::DidRunInitializer,
92                    base::Unretained(this), initializer, &status));
93
94     base::RunLoop().RunUntilIdle();
95     return status;
96   }
97
98   void DidRunInitializer(SyncEngineInitializer* initializer,
99                          SyncStatusCode* status_out,
100                          SyncStatusCode status) {
101     *status_out = status;
102     metadata_database_ = initializer->PassMetadataDatabase();
103   }
104
105   SyncStatusCode PopulateDatabase(
106       const google_apis::FileResource& sync_root,
107       const google_apis::FileResource** app_roots,
108       size_t app_roots_count) {
109     SyncStatusCode status = SYNC_STATUS_UNKNOWN;
110     scoped_ptr<MetadataDatabase> database = MetadataDatabase::Create(
111         database_path(), in_memory_env_.get(), &status);
112     if (status != SYNC_STATUS_OK)
113       return status;
114
115     // |app_root_list| must not own the resources here. Be sure to call
116     // weak_clear later.
117     ScopedVector<google_apis::FileResource> app_root_list;
118     for (size_t i = 0; i < app_roots_count; ++i) {
119       app_root_list.push_back(
120           const_cast<google_apis::FileResource*>(app_roots[i]));
121     }
122
123     status = database->PopulateInitialData(
124         kInitialLargestChangeID, sync_root, app_root_list);
125
126     app_root_list.weak_clear();
127     return status;
128   }
129
130   scoped_ptr<google_apis::FileResource> CreateRemoteFolder(
131       const std::string& parent_folder_id,
132       const std::string& title) {
133     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
134     scoped_ptr<google_apis::FileResource> entry;
135     sync_context_->GetDriveService()->AddNewDirectory(
136         parent_folder_id, title,
137         drive::DriveServiceInterface::AddNewDirectoryOptions(),
138         CreateResultReceiver(&error, &entry));
139     base::RunLoop().RunUntilIdle();
140
141     EXPECT_EQ(google_apis::HTTP_CREATED, error);
142     return entry.Pass();
143   }
144
145   scoped_ptr<google_apis::FileResource> CreateRemoteSyncRoot() {
146     scoped_ptr<google_apis::FileResource> sync_root(
147         CreateRemoteFolder(std::string(), kSyncRootFolderTitle));
148
149     for (size_t i = 0; i < sync_root->parents().size(); ++i) {
150       google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
151       sync_context_->GetDriveService()->RemoveResourceFromDirectory(
152           sync_root->parents()[i].file_id(),
153           sync_root->file_id(),
154           CreateResultReceiver(&error));
155       base::RunLoop().RunUntilIdle();
156       EXPECT_EQ(google_apis::HTTP_NO_CONTENT, error);
157     }
158
159     return sync_root.Pass();
160   }
161
162   std::string GetSyncRootFolderID() {
163     int64 sync_root_tracker_id = metadata_database_->GetSyncRootTrackerID();
164     FileTracker sync_root_tracker;
165     EXPECT_TRUE(metadata_database_->FindTrackerByTrackerID(
166         sync_root_tracker_id, &sync_root_tracker));
167     return sync_root_tracker.file_id();
168   }
169
170   size_t CountTrackersForFile(const std::string& file_id) {
171     TrackerIDSet trackers;
172     metadata_database_->FindTrackersByFileID(file_id, &trackers);
173     return trackers.size();
174   }
175
176   bool HasActiveTracker(const std::string& file_id) {
177     TrackerIDSet trackers;
178     return metadata_database_->FindTrackersByFileID(file_id, &trackers) &&
179         trackers.has_active();
180   }
181
182   bool HasNoParent(const std::string& file_id) {
183     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
184     scoped_ptr<google_apis::FileResource> entry;
185     sync_context_->GetDriveService()->GetFileResource(
186         file_id,
187         CreateResultReceiver(&error, &entry));
188     base::RunLoop().RunUntilIdle();
189     EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
190     return entry->parents().empty();
191   }
192
193   size_t CountFileMetadata() {
194     return metadata_database_->CountFileMetadata();
195   }
196
197   size_t CountFileTracker() {
198     return metadata_database_->CountFileTracker();
199   }
200
201   google_apis::GDataErrorCode AddParentFolder(
202       const std::string& new_parent_folder_id,
203       const std::string& file_id) {
204     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
205     sync_context_->GetDriveService()->AddResourceToDirectory(
206         new_parent_folder_id, file_id,
207         CreateResultReceiver(&error));
208     base::RunLoop().RunUntilIdle();
209     return error;
210   }
211
212  private:
213   content::TestBrowserThreadBundle browser_threads_;
214   base::ScopedTempDir database_dir_;
215   scoped_ptr<leveldb::Env> in_memory_env_;
216
217   scoped_ptr<MetadataDatabase> metadata_database_;
218   scoped_ptr<SyncTaskManager> sync_task_manager_;
219   scoped_ptr<SyncEngineContext> sync_context_;
220
221   DISALLOW_COPY_AND_ASSIGN(SyncEngineInitializerTest);
222 };
223
224 TEST_F(SyncEngineInitializerTest, EmptyDatabase_NoRemoteSyncRoot) {
225   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
226
227   std::string sync_root_folder_id = GetSyncRootFolderID();
228   EXPECT_EQ(1u, CountTrackersForFile(sync_root_folder_id));
229
230   EXPECT_TRUE(HasActiveTracker(sync_root_folder_id));
231
232   EXPECT_EQ(1u, CountFileMetadata());
233   EXPECT_EQ(1u, CountFileTracker());
234 }
235
236 TEST_F(SyncEngineInitializerTest, EmptyDatabase_RemoteSyncRootExists) {
237   scoped_ptr<google_apis::FileResource> sync_root(
238       CreateRemoteSyncRoot());
239   scoped_ptr<google_apis::FileResource> app_root_1(
240       CreateRemoteFolder(sync_root->file_id(), "app-root 1"));
241   scoped_ptr<google_apis::FileResource> app_root_2(
242       CreateRemoteFolder(sync_root->file_id(), "app-root 2"));
243
244   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
245
246   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
247   EXPECT_EQ(1u, CountTrackersForFile(app_root_1->file_id()));
248   EXPECT_EQ(1u, CountTrackersForFile(app_root_2->file_id()));
249
250   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
251   EXPECT_FALSE(HasActiveTracker(app_root_1->file_id()));
252   EXPECT_FALSE(HasActiveTracker(app_root_2->file_id()));
253
254   EXPECT_EQ(3u, CountFileMetadata());
255   EXPECT_EQ(3u, CountFileTracker());
256 }
257
258 TEST_F(SyncEngineInitializerTest, DatabaseAlreadyInitialized) {
259   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteSyncRoot());
260   scoped_ptr<google_apis::FileResource> app_root_1(
261       CreateRemoteFolder(sync_root->file_id(), "app-root 1"));
262   scoped_ptr<google_apis::FileResource> app_root_2(
263       CreateRemoteFolder(sync_root->file_id(), "app-root 2"));
264
265   const google_apis::FileResource* app_roots[] = {
266     app_root_1.get(), app_root_2.get()
267   };
268   EXPECT_EQ(SYNC_STATUS_OK,
269             PopulateDatabase(*sync_root, app_roots, arraysize(app_roots)));
270
271   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
272
273   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
274   EXPECT_EQ(1u, CountTrackersForFile(app_root_1->file_id()));
275   EXPECT_EQ(1u, CountTrackersForFile(app_root_2->file_id()));
276
277   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
278   EXPECT_FALSE(HasActiveTracker(app_root_1->file_id()));
279   EXPECT_FALSE(HasActiveTracker(app_root_2->file_id()));
280
281   EXPECT_EQ(3u, CountFileMetadata());
282   EXPECT_EQ(3u, CountFileTracker());
283 }
284
285 TEST_F(SyncEngineInitializerTest, EmptyDatabase_MultiCandidate) {
286   scoped_ptr<google_apis::FileResource> sync_root_1(CreateRemoteSyncRoot());
287   scoped_ptr<google_apis::FileResource> sync_root_2(CreateRemoteSyncRoot());
288
289   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
290
291   EXPECT_EQ(1u, CountTrackersForFile(sync_root_1->file_id()));
292   EXPECT_EQ(0u, CountTrackersForFile(sync_root_2->file_id()));
293
294   EXPECT_TRUE(HasActiveTracker(sync_root_1->file_id()));
295   EXPECT_FALSE(HasActiveTracker(sync_root_2->file_id()));
296
297   EXPECT_EQ(1u, CountFileMetadata());
298   EXPECT_EQ(1u, CountFileTracker());
299 }
300
301 TEST_F(SyncEngineInitializerTest, EmptyDatabase_UndetachedRemoteSyncRoot) {
302   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
303       std::string(), kSyncRootFolderTitle));
304   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
305
306   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
307   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
308
309   EXPECT_TRUE(HasNoParent(sync_root->file_id()));
310
311   EXPECT_EQ(1u, CountFileMetadata());
312   EXPECT_EQ(1u, CountFileTracker());
313 }
314
315 TEST_F(SyncEngineInitializerTest, EmptyDatabase_MultiparentSyncRoot) {
316   scoped_ptr<google_apis::FileResource> folder(CreateRemoteFolder(
317       std::string(), "folder"));
318   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
319       std::string(), kSyncRootFolderTitle));
320   AddParentFolder(sync_root->file_id(), folder->file_id());
321
322   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
323
324   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
325   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
326
327   EXPECT_TRUE(HasNoParent(sync_root->file_id()));
328
329   EXPECT_EQ(1u, CountFileMetadata());
330   EXPECT_EQ(1u, CountFileTracker());
331 }
332
333 TEST_F(SyncEngineInitializerTest, EmptyDatabase_FakeRemoteSyncRoot) {
334   scoped_ptr<google_apis::FileResource> folder(CreateRemoteFolder(
335       std::string(), "folder"));
336   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
337       folder->file_id(), kSyncRootFolderTitle));
338
339   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
340
341   EXPECT_EQ(0u, CountTrackersForFile(sync_root->file_id()));
342   EXPECT_FALSE(HasNoParent(sync_root->file_id()));
343
344   EXPECT_EQ(1u, CountFileMetadata());
345   EXPECT_EQ(1u, CountFileTracker());
346 }
347
348 }  // namespace drive_backend
349 }  // namespace sync_file_system