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