sync_engine_initializer_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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/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" 21 22namespace sync_file_system { 23namespace drive_backend { 24 25namespace { 26 27const int64 kInitialLargestChangeID = 1234; 28 29} // namespace 30 31class 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 NULL, 63 base::MessageLoopProxy::current(), 64 &fake_drive_service_, 65 database_path())); 66 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 67 68 initializer_->Run(CreateResultReceiver(&status)); 69 base::RunLoop().RunUntilIdle(); 70 71 metadata_database_ = initializer_->PassMetadataDatabase(); 72 return status; 73 } 74 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(), 83 database_path(), 84 CreateResultReceiver(&status, &database)); 85 base::RunLoop().RunUntilIdle(); 86 if (status != SYNC_STATUS_OK) 87 return status; 88 89 // |app_root_list| must not own the resources here. Be sure to call 90 // weak_clear later. 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])); 95 } 96 97 status = SYNC_STATUS_UNKNOWN; 98 database->PopulateInitialData(kInitialLargestChangeID, 99 sync_root, 100 app_root_list, 101 CreateResultReceiver(&status)); 102 base::RunLoop().RunUntilIdle(); 103 104 app_root_list.weak_clear(); 105 106 return SYNC_STATUS_OK; 107 } 108 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(); 118 119 EXPECT_EQ(google_apis::HTTP_CREATED, error); 120 if (!entry) 121 scoped_ptr<google_apis::FileResource>(); 122 return drive::util::ConvertResourceEntryToFileResource(*entry); 123 } 124 125 scoped_ptr<google_apis::FileResource> CreateRemoteSyncRoot() { 126 scoped_ptr<google_apis::FileResource> sync_root( 127 CreateRemoteFolder(std::string(), kSyncRootFolderTitle)); 128 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); 137 } 138 139 return sync_root.Pass(); 140 } 141 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(); 148 } 149 150 size_t CountTrackersForFile(const std::string& file_id) { 151 TrackerSet trackers; 152 metadata_database_->FindTrackersByFileID(file_id, &trackers); 153 return trackers.tracker_set().size(); 154 } 155 156 bool HasActiveTracker(const std::string& file_id) { 157 TrackerSet trackers; 158 return metadata_database_->FindTrackersByFileID(file_id, &trackers) && 159 trackers.has_active(); 160 } 161 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( 166 file_id, 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); 171 } 172 173 size_t NumberOfMetadata() { 174 return metadata_database_->file_by_id_.size(); 175 } 176 177 size_t NumberOfTrackers() { 178 return metadata_database_->tracker_by_id_.size(); 179 } 180 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(); 189 return error; 190 } 191 192 private: 193 content::TestBrowserThreadBundle browser_threads_; 194 base::ScopedTempDir database_dir_; 195 drive::FakeDriveService fake_drive_service_; 196 197 scoped_ptr<SyncEngineInitializer> initializer_; 198 scoped_ptr<MetadataDatabase> metadata_database_; 199 200 DISALLOW_COPY_AND_ASSIGN(SyncEngineInitializerTest); 201}; 202 203TEST_F(SyncEngineInitializerTest, EmptyDatabase_NoRemoteSyncRoot) { 204 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer()); 205 206 std::string sync_root_folder_id = GetSyncRootFolderID(); 207 EXPECT_EQ(1u, CountTrackersForFile(sync_root_folder_id)); 208 209 EXPECT_TRUE(HasActiveTracker(sync_root_folder_id)); 210 211 EXPECT_EQ(1u, NumberOfMetadata()); 212 EXPECT_EQ(1u, NumberOfTrackers()); 213} 214 215TEST_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")); 222 223 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer()); 224 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())); 228 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())); 232 233 EXPECT_EQ(3u, NumberOfMetadata()); 234 EXPECT_EQ(3u, NumberOfTrackers()); 235} 236 237TEST_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")); 243 244 const google_apis::FileResource* app_roots[] = { 245 app_root_1.get(), app_root_2.get() 246 }; 247 EXPECT_EQ(SYNC_STATUS_OK, 248 PopulateDatabase(*sync_root, app_roots, arraysize(app_roots))); 249 250 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer()); 251 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())); 255 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())); 259 260 EXPECT_EQ(3u, NumberOfMetadata()); 261 EXPECT_EQ(3u, NumberOfTrackers()); 262} 263 264TEST_F(SyncEngineInitializerTest, EmptyDatabase_MultiCandidate) { 265 scoped_ptr<google_apis::FileResource> sync_root_1(CreateRemoteSyncRoot()); 266 scoped_ptr<google_apis::FileResource> sync_root_2(CreateRemoteSyncRoot()); 267 268 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer()); 269 270 EXPECT_EQ(1u, CountTrackersForFile(sync_root_1->file_id())); 271 EXPECT_EQ(0u, CountTrackersForFile(sync_root_2->file_id())); 272 273 EXPECT_TRUE(HasActiveTracker(sync_root_1->file_id())); 274 EXPECT_FALSE(HasActiveTracker(sync_root_2->file_id())); 275 276 EXPECT_EQ(1u, NumberOfMetadata()); 277 EXPECT_EQ(1u, NumberOfTrackers()); 278} 279 280TEST_F(SyncEngineInitializerTest, EmptyDatabase_UndetachedRemoteSyncRoot) { 281 scoped_ptr<google_apis::FileResource> sync_root(CreateRemoteFolder( 282 std::string(), kSyncRootFolderTitle)); 283 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer()); 284 285 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id())); 286 EXPECT_TRUE(HasActiveTracker(sync_root->file_id())); 287 288 EXPECT_TRUE(HasNoParent(sync_root->file_id())); 289 290 EXPECT_EQ(1u, NumberOfMetadata()); 291 EXPECT_EQ(1u, NumberOfTrackers()); 292} 293 294TEST_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()); 300 301 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer()); 302 303 EXPECT_EQ(1u, CountTrackersForFile(sync_root->file_id())); 304 EXPECT_TRUE(HasActiveTracker(sync_root->file_id())); 305 306 EXPECT_TRUE(HasNoParent(sync_root->file_id())); 307 308 EXPECT_EQ(1u, NumberOfMetadata()); 309 EXPECT_EQ(1u, NumberOfTrackers()); 310} 311 312TEST_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)); 317 318 EXPECT_EQ(SYNC_STATUS_OK, RunInitializer()); 319 320 EXPECT_EQ(0u, CountTrackersForFile(sync_root->file_id())); 321 EXPECT_FALSE(HasNoParent(sync_root->file_id())); 322 323 EXPECT_EQ(1u, NumberOfMetadata()); 324 EXPECT_EQ(1u, NumberOfTrackers()); 325} 326 327} // namespace drive_backend 328} // namespace sync_file_system 329