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