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