- add sources.
[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/fake_drive_service.h"
12 #include "chrome/browser/google_apis/drive_api_parser.h"
13 #include "chrome/browser/google_apis/gdata_wapi_parser.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/sync_file_system_test_util.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace sync_file_system {
23 namespace drive_backend {
24
25 namespace {
26
27 const int64 kInitialLargestChangeID = 1234;
28
29 }  // namespace
30
31 class SyncEngineInitializerTest : public testing::Test {
32  public:
33   struct TrackedFile {
34     scoped_ptr<google_apis::FileResource> resource;
35     FileMetadata metadata;
36     FileTracker tracker;
37   };
38
39   SyncEngineInitializerTest() {}
40   virtual ~SyncEngineInitializerTest() {}
41
42   virtual void SetUp() OVERRIDE {
43     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
44     ASSERT_TRUE(fake_drive_service_.LoadAccountMetadataForWapi(
45         "sync_file_system/account_metadata.json"));
46     ASSERT_TRUE(fake_drive_service_.LoadResourceListForWapi(
47         "gdata/empty_feed.json"));
48   }
49
50   virtual void TearDown() OVERRIDE {
51     initializer_.reset();
52     metadata_database_.reset();
53     base::RunLoop().RunUntilIdle();
54   }
55
56   base::FilePath database_path() {
57     return database_dir_.path();
58   }
59
60   SyncStatusCode RunInitializer() {
61     initializer_.reset(new SyncEngineInitializer(
62         base::MessageLoopProxy::current(),
63         &fake_drive_service_,
64         database_path()));
65     SyncStatusCode status = SYNC_STATUS_UNKNOWN;
66
67     initializer_->Run(CreateResultReceiver(&status));
68     base::RunLoop().RunUntilIdle();
69
70     metadata_database_ = initializer_->PassMetadataDatabase();
71     return status;
72   }
73
74   google_apis::GDataErrorCode FillTrackedFileByTrackerID(
75       int64 tracker_id,
76       scoped_ptr<TrackedFile>* file_out) {
77     scoped_ptr<TrackedFile> file(new TrackedFile);
78     if (!metadata_database_->FindTrackerByTrackerID(
79             tracker_id, &file->tracker))
80       return google_apis::HTTP_NOT_FOUND;
81     if (!metadata_database_->FindFileByFileID(
82             file->tracker.file_id(), &file->metadata))
83       return google_apis::HTTP_NOT_FOUND;
84
85     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
86     scoped_ptr<google_apis::ResourceEntry> entry;
87     fake_drive_service_.GetResourceEntry(file->metadata.file_id(),
88                                          CreateResultReceiver(&error, &entry));
89     base::RunLoop().RunUntilIdle();
90
91     if (entry) {
92       file->resource =
93           drive::util::ConvertResourceEntryToFileResource(*entry);
94     }
95
96     if (file_out)
97       *file_out = file.Pass();
98     return error;
99   }
100
101   SyncStatusCode PopulateDatabase(
102       const google_apis::FileResource& sync_root,
103       const google_apis::FileResource** app_roots,
104       size_t app_roots_count) {
105     SyncStatusCode status = SYNC_STATUS_UNKNOWN;
106     scoped_ptr<MetadataDatabase> database;
107     MetadataDatabase::Create(
108         base::MessageLoopProxy::current(),
109         database_path(),
110         CreateResultReceiver(&status, &database));
111     base::RunLoop().RunUntilIdle();
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 = SYNC_STATUS_UNKNOWN;
124     database->PopulateInitialData(kInitialLargestChangeID,
125                                   sync_root,
126                                   app_root_list,
127                                   CreateResultReceiver(&status));
128     base::RunLoop().RunUntilIdle();
129
130     app_root_list.weak_clear();
131
132     return SYNC_STATUS_OK;
133   }
134
135   scoped_ptr<google_apis::FileResource> CreateRemoteFolder(
136       const std::string& parent_folder_id,
137       const std::string& title) {
138     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
139     scoped_ptr<google_apis::ResourceEntry> entry;
140     fake_drive_service_.AddNewDirectory(
141         parent_folder_id, title,
142         CreateResultReceiver(&error, &entry));
143     base::RunLoop().RunUntilIdle();
144
145     EXPECT_EQ(google_apis::HTTP_CREATED, error);
146     if (!entry)
147       scoped_ptr<google_apis::FileResource>();
148     return drive::util::ConvertResourceEntryToFileResource(*entry);
149   }
150
151   scoped_ptr<google_apis::FileResource> CreateRemoteSyncRoot() {
152     scoped_ptr<google_apis::FileResource> sync_root(
153         CreateRemoteFolder(std::string(), kSyncRootFolderTitle));
154
155     for (size_t i = 0; i < sync_root->parents().size(); ++i) {
156       google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
157       fake_drive_service_.RemoveResourceFromDirectory(
158           sync_root->parents()[i]->file_id(),
159           sync_root->file_id(),
160           CreateResultReceiver(&error));
161       base::RunLoop().RunUntilIdle();
162       EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
163     }
164
165     return sync_root.Pass();
166   }
167
168   std::string GetSyncRootFolderID() {
169     int64 sync_root_tracker_id = metadata_database_->GetSyncRootTrackerID();
170     FileTracker sync_root_tracker;
171     EXPECT_TRUE(metadata_database_->FindTrackerByTrackerID(
172         sync_root_tracker_id, &sync_root_tracker));
173     return sync_root_tracker.file_id();
174   }
175
176   size_t CountTrackersForFile(const std::string& file_id) {
177     TrackerSet trackers;
178     metadata_database_->FindTrackersByFileID(file_id, &trackers);
179     return trackers.tracker_set().size();
180   }
181
182   bool HasActiveTracker(const std::string& file_id) {
183     TrackerSet trackers;
184     return metadata_database_->FindTrackersByFileID(file_id, &trackers) &&
185         trackers.has_active();
186   }
187
188   bool HasNoParent(const std::string& file_id) {
189     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
190     scoped_ptr<google_apis::ResourceEntry> entry;
191     fake_drive_service_.GetResourceEntry(
192         file_id,
193         CreateResultReceiver(&error, &entry));
194     base::RunLoop().RunUntilIdle();
195     EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
196     return !entry->GetLinkByType(google_apis::Link::LINK_PARENT);
197   }
198
199   size_t NumberOfMetadata() {
200     return metadata_database_->file_by_id_.size();
201   }
202
203   size_t NumberOfTrackers() {
204     return metadata_database_->tracker_by_id_.size();
205   }
206
207   google_apis::GDataErrorCode AddParentFolder(
208       const std::string& new_parent_folder_id,
209       const std::string& file_id) {
210     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
211     fake_drive_service_.AddResourceToDirectory(
212         new_parent_folder_id, file_id,
213         CreateResultReceiver(&error));
214     base::RunLoop().RunUntilIdle();
215     return error;
216   }
217
218  private:
219   content::TestBrowserThreadBundle browser_threads_;
220   base::ScopedTempDir database_dir_;
221   drive::FakeDriveService fake_drive_service_;
222
223   scoped_ptr<SyncEngineInitializer> initializer_;
224   scoped_ptr<MetadataDatabase> metadata_database_;
225
226   DISALLOW_COPY_AND_ASSIGN(SyncEngineInitializerTest);
227 };
228
229 TEST_F(SyncEngineInitializerTest, EmptyDatabase_NoRemoteSyncRoot) {
230   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
231
232   std::string sync_root_folder_id = GetSyncRootFolderID();
233   EXPECT_EQ(1u, CountTrackersForFile(sync_root_folder_id));
234
235   EXPECT_TRUE(HasActiveTracker(sync_root_folder_id));
236
237   EXPECT_EQ(1u, NumberOfMetadata());
238   EXPECT_EQ(1u, NumberOfTrackers());
239 }
240
241 TEST_F(SyncEngineInitializerTest, EmptyDatabase_RemoteSyncRootExists) {
242   scoped_ptr<google_apis::FileResource> sync_root(
243       CreateRemoteSyncRoot());
244   scoped_ptr<google_apis::FileResource> app_root_1(
245       CreateRemoteFolder(sync_root->file_id(), "app-root 1"));
246   scoped_ptr<google_apis::FileResource> app_root_2(
247       CreateRemoteFolder(sync_root->file_id(), "app-root 2"));
248
249   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
250
251   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
252   EXPECT_EQ(1u, CountTrackersForFile(app_root_1->file_id()));
253   EXPECT_EQ(1u, CountTrackersForFile(app_root_2->file_id()));
254
255   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
256   EXPECT_FALSE(HasActiveTracker(app_root_1->file_id()));
257   EXPECT_FALSE(HasActiveTracker(app_root_2->file_id()));
258
259   EXPECT_EQ(3u, NumberOfMetadata());
260   EXPECT_EQ(3u, NumberOfTrackers());
261 }
262
263 TEST_F(SyncEngineInitializerTest, DatabaseAlreadyInitialized) {
264   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteSyncRoot());
265   scoped_ptr<google_apis::FileResource> app_root_1(
266       CreateRemoteFolder(sync_root->file_id(), "app-root 1"));
267   scoped_ptr<google_apis::FileResource> app_root_2(
268       CreateRemoteFolder(sync_root->file_id(), "app-root 2"));
269
270   const google_apis::FileResource* app_roots[] = {
271     app_root_1.get(), app_root_2.get()
272   };
273   EXPECT_EQ(SYNC_STATUS_OK,
274             PopulateDatabase(*sync_root, app_roots, arraysize(app_roots)));
275
276   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
277
278   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
279   EXPECT_EQ(1u, CountTrackersForFile(app_root_1->file_id()));
280   EXPECT_EQ(1u, CountTrackersForFile(app_root_2->file_id()));
281
282   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
283   EXPECT_FALSE(HasActiveTracker(app_root_1->file_id()));
284   EXPECT_FALSE(HasActiveTracker(app_root_2->file_id()));
285
286   EXPECT_EQ(3u, NumberOfMetadata());
287   EXPECT_EQ(3u, NumberOfTrackers());
288 }
289
290 TEST_F(SyncEngineInitializerTest, EmptyDatabase_MultiCandidate) {
291   scoped_ptr<google_apis::FileResource> sync_root_1(CreateRemoteSyncRoot());
292   scoped_ptr<google_apis::FileResource> sync_root_2(CreateRemoteSyncRoot());
293
294   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
295
296   EXPECT_EQ(1u, CountTrackersForFile(sync_root_1->file_id()));
297   EXPECT_EQ(0u, CountTrackersForFile(sync_root_2->file_id()));
298
299   EXPECT_TRUE(HasActiveTracker(sync_root_1->file_id()));
300   EXPECT_FALSE(HasActiveTracker(sync_root_2->file_id()));
301
302   EXPECT_EQ(1u, NumberOfMetadata());
303   EXPECT_EQ(1u, NumberOfTrackers());
304 }
305
306 TEST_F(SyncEngineInitializerTest, EmptyDatabase_UndetachedRemoteSyncRoot) {
307   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
308       std::string(), kSyncRootFolderTitle));
309   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
310
311   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
312   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
313
314   EXPECT_TRUE(HasNoParent(sync_root->file_id()));
315
316   EXPECT_EQ(1u, NumberOfMetadata());
317   EXPECT_EQ(1u, NumberOfTrackers());
318 }
319
320 TEST_F(SyncEngineInitializerTest, EmptyDatabase_MultiparentSyncRoot) {
321   scoped_ptr<google_apis::FileResource> folder(CreateRemoteFolder(
322       std::string(), "folder"));
323   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
324       std::string(), kSyncRootFolderTitle));
325   AddParentFolder(sync_root->file_id(), folder->file_id());
326
327   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
328
329   EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
330   EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
331
332   EXPECT_TRUE(HasNoParent(sync_root->file_id()));
333
334   EXPECT_EQ(1u, NumberOfMetadata());
335   EXPECT_EQ(1u, NumberOfTrackers());
336 }
337
338 TEST_F(SyncEngineInitializerTest, EmptyDatabase_FakeRemoteSyncRoot) {
339   scoped_ptr<google_apis::FileResource> folder(CreateRemoteFolder(
340       std::string(), "folder"));
341   scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder(
342       folder->file_id(), kSyncRootFolderTitle));
343
344   EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
345
346   EXPECT_EQ(0u, CountTrackersForFile(sync_root->file_id()));
347   EXPECT_FALSE(HasNoParent(sync_root->file_id()));
348
349   EXPECT_EQ(1u, NumberOfMetadata());
350   EXPECT_EQ(1u, NumberOfTrackers());
351 }
352
353 }  // namespace drive_backend
354 }  // namespace sync_file_system