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