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"
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"
22 namespace sync_file_system {
23 namespace drive_backend {
27 const int64 kInitialLargestChangeID = 1234;
31 class SyncEngineInitializerTest : public testing::Test {
34 scoped_ptr<google_apis::FileResource> resource;
35 FileMetadata metadata;
39 SyncEngineInitializerTest() {}
40 virtual ~SyncEngineInitializerTest() {}
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"));
50 virtual void TearDown() OVERRIDE {
52 metadata_database_.reset();
53 base::RunLoop().RunUntilIdle();
56 base::FilePath database_path() {
57 return database_dir_.path();
60 SyncStatusCode RunInitializer() {
61 initializer_.reset(new SyncEngineInitializer(
62 base::MessageLoopProxy::current(),
65 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
67 initializer_->Run(CreateResultReceiver(&status));
68 base::RunLoop().RunUntilIdle();
70 metadata_database_ = initializer_->PassMetadataDatabase();
74 google_apis::GDataErrorCode FillTrackedFileByTrackerID(
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;
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();
93 drive::util::ConvertResourceEntryToFileResource(*entry);
97 *file_out = file.Pass();
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(),
110 CreateResultReceiver(&status, &database));
111 base::RunLoop().RunUntilIdle();
112 if (status != SYNC_STATUS_OK)
115 // |app_root_list| must not own the resources here. Be sure to call
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]));
123 status = SYNC_STATUS_UNKNOWN;
124 database->PopulateInitialData(kInitialLargestChangeID,
127 CreateResultReceiver(&status));
128 base::RunLoop().RunUntilIdle();
130 app_root_list.weak_clear();
132 return SYNC_STATUS_OK;
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();
145 EXPECT_EQ(google_apis::HTTP_CREATED, error);
147 scoped_ptr<google_apis::FileResource>();
148 return drive::util::ConvertResourceEntryToFileResource(*entry);
151 scoped_ptr<google_apis::FileResource> CreateRemoteSyncRoot() {
152 scoped_ptr<google_apis::FileResource> sync_root(
153 CreateRemoteFolder(std::string(), kSyncRootFolderTitle));
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);
165 return sync_root.Pass();
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();
176 size_t CountTrackersForFile(const std::string& file_id) {
178 metadata_database_->FindTrackersByFileID(file_id, &trackers);
179 return trackers.tracker_set().size();
182 bool HasActiveTracker(const std::string& file_id) {
184 return metadata_database_->FindTrackersByFileID(file_id, &trackers) &&
185 trackers.has_active();
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(
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);
199 size_t NumberOfMetadata() {
200 return metadata_database_->file_by_id_.size();
203 size_t NumberOfTrackers() {
204 return metadata_database_->tracker_by_id_.size();
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();
219 content::TestBrowserThreadBundle browser_threads_;
220 base::ScopedTempDir database_dir_;
221 drive::FakeDriveService fake_drive_service_;
223 scoped_ptr<SyncEngineInitializer> initializer_;
224 scoped_ptr<MetadataDatabase> metadata_database_;
226 DISALLOW_COPY_AND_ASSIGN(SyncEngineInitializerTest);
229 TEST_F(SyncEngineInitializerTest, EmptyDatabase_NoRemoteSyncRoot) {
230 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
232 std::string sync_root_folder_id = GetSyncRootFolderID();
233 EXPECT_EQ(1u, CountTrackersForFile(sync_root_folder_id));
235 EXPECT_TRUE(HasActiveTracker(sync_root_folder_id));
237 EXPECT_EQ(1u, NumberOfMetadata());
238 EXPECT_EQ(1u, NumberOfTrackers());
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"));
249 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
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()));
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()));
259 EXPECT_EQ(3u, NumberOfMetadata());
260 EXPECT_EQ(3u, NumberOfTrackers());
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"));
270 const google_apis::FileResource* app_roots[] = {
271 app_root_1.get(), app_root_2.get()
273 EXPECT_EQ(SYNC_STATUS_OK,
274 PopulateDatabase(*sync_root, app_roots, arraysize(app_roots)));
276 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
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()));
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()));
286 EXPECT_EQ(3u, NumberOfMetadata());
287 EXPECT_EQ(3u, NumberOfTrackers());
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());
294 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
296 EXPECT_EQ(1u, CountTrackersForFile(sync_root_1->file_id()));
297 EXPECT_EQ(0u, CountTrackersForFile(sync_root_2->file_id()));
299 EXPECT_TRUE(HasActiveTracker(sync_root_1->file_id()));
300 EXPECT_FALSE(HasActiveTracker(sync_root_2->file_id()));
302 EXPECT_EQ(1u, NumberOfMetadata());
303 EXPECT_EQ(1u, NumberOfTrackers());
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());
311 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
312 EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
314 EXPECT_TRUE(HasNoParent(sync_root->file_id()));
316 EXPECT_EQ(1u, NumberOfMetadata());
317 EXPECT_EQ(1u, NumberOfTrackers());
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());
327 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
329 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id()));
330 EXPECT_TRUE(HasActiveTracker(sync_root->file_id()));
332 EXPECT_TRUE(HasNoParent(sync_root->file_id()));
334 EXPECT_EQ(1u, NumberOfMetadata());
335 EXPECT_EQ(1u, NumberOfTrackers());
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));
344 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer());
346 EXPECT_EQ(0u, CountTrackersForFile(sync_root->file_id()));
347 EXPECT_FALSE(HasNoParent(sync_root->file_id()));
349 EXPECT_EQ(1u, NumberOfMetadata());
350 EXPECT_EQ(1u, NumberOfTrackers());
353 } // namespace drive_backend
354 } // namespace sync_file_system