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/sync_file_system/drive_backend/drive_backend_constants.h"
13 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
14 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
15 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
16 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "google_apis/drive/drive_api_parser.h"
19 #include "google_apis/drive/gdata_wapi_parser.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(
63 base::MessageLoopProxy::current(),
66 SyncStatusCode status
= SYNC_STATUS_UNKNOWN
;
68 initializer_
->Run(CreateResultReceiver(&status
));
69 base::RunLoop().RunUntilIdle();
71 metadata_database_
= initializer_
->PassMetadataDatabase();
75 SyncStatusCode
PopulateDatabase(
76 const google_apis::FileResource
& sync_root
,
77 const google_apis::FileResource
** app_roots
,
78 size_t app_roots_count
) {
79 SyncStatusCode status
= SYNC_STATUS_UNKNOWN
;
80 scoped_ptr
<MetadataDatabase
> database
;
81 MetadataDatabase::Create(
82 base::MessageLoopProxy::current(),
84 CreateResultReceiver(&status
, &database
));
85 base::RunLoop().RunUntilIdle();
86 if (status
!= SYNC_STATUS_OK
)
89 // |app_root_list| must not own the resources here. Be sure to call
91 ScopedVector
<google_apis::FileResource
> app_root_list
;
92 for (size_t i
= 0; i
< app_roots_count
; ++i
) {
93 app_root_list
.push_back(
94 const_cast<google_apis::FileResource
*>(app_roots
[i
]));
97 status
= SYNC_STATUS_UNKNOWN
;
98 database
->PopulateInitialData(kInitialLargestChangeID
,
101 CreateResultReceiver(&status
));
102 base::RunLoop().RunUntilIdle();
104 app_root_list
.weak_clear();
106 return SYNC_STATUS_OK
;
109 scoped_ptr
<google_apis::FileResource
> CreateRemoteFolder(
110 const std::string
& parent_folder_id
,
111 const std::string
& title
) {
112 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
113 scoped_ptr
<google_apis::ResourceEntry
> entry
;
114 fake_drive_service_
.AddNewDirectory(
115 parent_folder_id
, title
,
116 CreateResultReceiver(&error
, &entry
));
117 base::RunLoop().RunUntilIdle();
119 EXPECT_EQ(google_apis::HTTP_CREATED
, error
);
121 scoped_ptr
<google_apis::FileResource
>();
122 return drive::util::ConvertResourceEntryToFileResource(*entry
);
125 scoped_ptr
<google_apis::FileResource
> CreateRemoteSyncRoot() {
126 scoped_ptr
<google_apis::FileResource
> sync_root(
127 CreateRemoteFolder(std::string(), kSyncRootFolderTitle
));
129 for (size_t i
= 0; i
< sync_root
->parents().size(); ++i
) {
130 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
131 fake_drive_service_
.RemoveResourceFromDirectory(
132 sync_root
->parents()[i
]->file_id(),
133 sync_root
->file_id(),
134 CreateResultReceiver(&error
));
135 base::RunLoop().RunUntilIdle();
136 EXPECT_EQ(google_apis::HTTP_NO_CONTENT
, error
);
139 return sync_root
.Pass();
142 std::string
GetSyncRootFolderID() {
143 int64 sync_root_tracker_id
= metadata_database_
->GetSyncRootTrackerID();
144 FileTracker sync_root_tracker
;
145 EXPECT_TRUE(metadata_database_
->FindTrackerByTrackerID(
146 sync_root_tracker_id
, &sync_root_tracker
));
147 return sync_root_tracker
.file_id();
150 size_t CountTrackersForFile(const std::string
& file_id
) {
152 metadata_database_
->FindTrackersByFileID(file_id
, &trackers
);
153 return trackers
.tracker_set().size();
156 bool HasActiveTracker(const std::string
& file_id
) {
158 return metadata_database_
->FindTrackersByFileID(file_id
, &trackers
) &&
159 trackers
.has_active();
162 bool HasNoParent(const std::string
& file_id
) {
163 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
164 scoped_ptr
<google_apis::ResourceEntry
> entry
;
165 fake_drive_service_
.GetResourceEntry(
167 CreateResultReceiver(&error
, &entry
));
168 base::RunLoop().RunUntilIdle();
169 EXPECT_EQ(google_apis::HTTP_SUCCESS
, error
);
170 return !entry
->GetLinkByType(google_apis::Link::LINK_PARENT
);
173 size_t NumberOfMetadata() {
174 return metadata_database_
->file_by_id_
.size();
177 size_t NumberOfTrackers() {
178 return metadata_database_
->tracker_by_id_
.size();
181 google_apis::GDataErrorCode
AddParentFolder(
182 const std::string
& new_parent_folder_id
,
183 const std::string
& file_id
) {
184 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
185 fake_drive_service_
.AddResourceToDirectory(
186 new_parent_folder_id
, file_id
,
187 CreateResultReceiver(&error
));
188 base::RunLoop().RunUntilIdle();
193 content::TestBrowserThreadBundle browser_threads_
;
194 base::ScopedTempDir database_dir_
;
195 drive::FakeDriveService fake_drive_service_
;
197 scoped_ptr
<SyncEngineInitializer
> initializer_
;
198 scoped_ptr
<MetadataDatabase
> metadata_database_
;
200 DISALLOW_COPY_AND_ASSIGN(SyncEngineInitializerTest
);
203 TEST_F(SyncEngineInitializerTest
, EmptyDatabase_NoRemoteSyncRoot
) {
204 EXPECT_EQ(SYNC_STATUS_OK
, RunInitializer());
206 std::string sync_root_folder_id
= GetSyncRootFolderID();
207 EXPECT_EQ(1u, CountTrackersForFile(sync_root_folder_id
));
209 EXPECT_TRUE(HasActiveTracker(sync_root_folder_id
));
211 EXPECT_EQ(1u, NumberOfMetadata());
212 EXPECT_EQ(1u, NumberOfTrackers());
215 TEST_F(SyncEngineInitializerTest
, EmptyDatabase_RemoteSyncRootExists
) {
216 scoped_ptr
<google_apis::FileResource
> sync_root(
217 CreateRemoteSyncRoot());
218 scoped_ptr
<google_apis::FileResource
> app_root_1(
219 CreateRemoteFolder(sync_root
->file_id(), "app-root 1"));
220 scoped_ptr
<google_apis::FileResource
> app_root_2(
221 CreateRemoteFolder(sync_root
->file_id(), "app-root 2"));
223 EXPECT_EQ(SYNC_STATUS_OK
, RunInitializer());
225 EXPECT_EQ(1u, CountTrackersForFile(sync_root
->file_id()));
226 EXPECT_EQ(1u, CountTrackersForFile(app_root_1
->file_id()));
227 EXPECT_EQ(1u, CountTrackersForFile(app_root_2
->file_id()));
229 EXPECT_TRUE(HasActiveTracker(sync_root
->file_id()));
230 EXPECT_FALSE(HasActiveTracker(app_root_1
->file_id()));
231 EXPECT_FALSE(HasActiveTracker(app_root_2
->file_id()));
233 EXPECT_EQ(3u, NumberOfMetadata());
234 EXPECT_EQ(3u, NumberOfTrackers());
237 TEST_F(SyncEngineInitializerTest
, DatabaseAlreadyInitialized
) {
238 scoped_ptr
<google_apis::FileResource
> sync_root(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"));
244 const google_apis::FileResource
* app_roots
[] = {
245 app_root_1
.get(), app_root_2
.get()
247 EXPECT_EQ(SYNC_STATUS_OK
,
248 PopulateDatabase(*sync_root
, app_roots
, arraysize(app_roots
)));
250 EXPECT_EQ(SYNC_STATUS_OK
, RunInitializer());
252 EXPECT_EQ(1u, CountTrackersForFile(sync_root
->file_id()));
253 EXPECT_EQ(1u, CountTrackersForFile(app_root_1
->file_id()));
254 EXPECT_EQ(1u, CountTrackersForFile(app_root_2
->file_id()));
256 EXPECT_TRUE(HasActiveTracker(sync_root
->file_id()));
257 EXPECT_FALSE(HasActiveTracker(app_root_1
->file_id()));
258 EXPECT_FALSE(HasActiveTracker(app_root_2
->file_id()));
260 EXPECT_EQ(3u, NumberOfMetadata());
261 EXPECT_EQ(3u, NumberOfTrackers());
264 TEST_F(SyncEngineInitializerTest
, EmptyDatabase_MultiCandidate
) {
265 scoped_ptr
<google_apis::FileResource
> sync_root_1(CreateRemoteSyncRoot());
266 scoped_ptr
<google_apis::FileResource
> sync_root_2(CreateRemoteSyncRoot());
268 EXPECT_EQ(SYNC_STATUS_OK
, RunInitializer());
270 EXPECT_EQ(1u, CountTrackersForFile(sync_root_1
->file_id()));
271 EXPECT_EQ(0u, CountTrackersForFile(sync_root_2
->file_id()));
273 EXPECT_TRUE(HasActiveTracker(sync_root_1
->file_id()));
274 EXPECT_FALSE(HasActiveTracker(sync_root_2
->file_id()));
276 EXPECT_EQ(1u, NumberOfMetadata());
277 EXPECT_EQ(1u, NumberOfTrackers());
280 TEST_F(SyncEngineInitializerTest
, EmptyDatabase_UndetachedRemoteSyncRoot
) {
281 scoped_ptr
<google_apis::FileResource
> sync_root(CreateRemoteFolder(
282 std::string(), kSyncRootFolderTitle
));
283 EXPECT_EQ(SYNC_STATUS_OK
, RunInitializer());
285 EXPECT_EQ(1u, CountTrackersForFile(sync_root
->file_id()));
286 EXPECT_TRUE(HasActiveTracker(sync_root
->file_id()));
288 EXPECT_TRUE(HasNoParent(sync_root
->file_id()));
290 EXPECT_EQ(1u, NumberOfMetadata());
291 EXPECT_EQ(1u, NumberOfTrackers());
294 TEST_F(SyncEngineInitializerTest
, EmptyDatabase_MultiparentSyncRoot
) {
295 scoped_ptr
<google_apis::FileResource
> folder(CreateRemoteFolder(
296 std::string(), "folder"));
297 scoped_ptr
<google_apis::FileResource
> sync_root(CreateRemoteFolder(
298 std::string(), kSyncRootFolderTitle
));
299 AddParentFolder(sync_root
->file_id(), folder
->file_id());
301 EXPECT_EQ(SYNC_STATUS_OK
, RunInitializer());
303 EXPECT_EQ(1u, CountTrackersForFile(sync_root
->file_id()));
304 EXPECT_TRUE(HasActiveTracker(sync_root
->file_id()));
306 EXPECT_TRUE(HasNoParent(sync_root
->file_id()));
308 EXPECT_EQ(1u, NumberOfMetadata());
309 EXPECT_EQ(1u, NumberOfTrackers());
312 TEST_F(SyncEngineInitializerTest
, EmptyDatabase_FakeRemoteSyncRoot
) {
313 scoped_ptr
<google_apis::FileResource
> folder(CreateRemoteFolder(
314 std::string(), "folder"));
315 scoped_ptr
<google_apis::FileResource
> sync_root(CreateRemoteFolder(
316 folder
->file_id(), kSyncRootFolderTitle
));
318 EXPECT_EQ(SYNC_STATUS_OK
, RunInitializer());
320 EXPECT_EQ(0u, CountTrackersForFile(sync_root
->file_id()));
321 EXPECT_FALSE(HasNoParent(sync_root
->file_id()));
323 EXPECT_EQ(1u, NumberOfMetadata());
324 EXPECT_EQ(1u, NumberOfTrackers());
327 } // namespace drive_backend
328 } // namespace sync_file_system