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