register_app_task_unittest.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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/register_app_task.h" 6 7#include "base/files/scoped_temp_dir.h" 8#include "base/format_macros.h" 9#include "base/run_loop.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/strings/stringprintf.h" 12#include "chrome/browser/drive/fake_drive_service.h" 13#include "chrome/browser/google_apis/gdata_wapi_parser.h" 14#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h" 15#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 16#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 17#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 18#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h" 19#include "chrome/browser/sync_file_system/drive_backend_v1/fake_drive_service_helper.h" 20#include "chrome/browser/sync_file_system/sync_file_system_test_util.h" 21#include "content/public/test/test_browser_thread_bundle.h" 22#include "testing/gtest/include/gtest/gtest.h" 23#include "third_party/leveldatabase/src/include/leveldb/db.h" 24#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 25 26namespace sync_file_system { 27namespace drive_backend { 28 29namespace { 30const int64 kSyncRootTrackerID = 100; 31} // namespace 32 33class RegisterAppTaskTest : public testing::Test, 34 public SyncEngineContext { 35 public: 36 RegisterAppTaskTest() 37 : next_file_id_(1000), 38 next_tracker_id_(10000) {} 39 virtual ~RegisterAppTaskTest() {} 40 41 virtual void SetUp() OVERRIDE { 42 ASSERT_TRUE(database_dir_.CreateUniqueTempDir()); 43 44 fake_drive_service_.reset(new drive::FakeDriveService); 45 ASSERT_TRUE(fake_drive_service_->LoadAccountMetadataForWapi( 46 "sync_file_system/account_metadata.json")); 47 ASSERT_TRUE(fake_drive_service_->LoadResourceListForWapi( 48 "gdata/empty_feed.json")); 49 50 drive_uploader_.reset(new drive::DriveUploader( 51 fake_drive_service_.get(), base::MessageLoopProxy::current())); 52 53 fake_drive_service_helper_.reset(new FakeDriveServiceHelper( 54 fake_drive_service_.get(), drive_uploader_.get())); 55 56 ASSERT_EQ(google_apis::HTTP_CREATED, 57 fake_drive_service_helper_->AddOrphanedFolder( 58 kSyncRootFolderTitle, &sync_root_folder_id_)); 59 } 60 61 virtual void TearDown() OVERRIDE { 62 metadata_database_.reset(); 63 base::RunLoop().RunUntilIdle(); 64 } 65 66 virtual drive::DriveServiceInterface* GetDriveService() OVERRIDE { 67 return fake_drive_service_.get(); 68 } 69 70 virtual MetadataDatabase* GetMetadataDatabase() OVERRIDE { 71 return metadata_database_.get(); 72 } 73 74 protected: 75 scoped_ptr<leveldb::DB> OpenLevelDB() { 76 leveldb::DB* db = NULL; 77 leveldb::Options options; 78 options.create_if_missing = true; 79 leveldb::Status status = 80 leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db); 81 EXPECT_TRUE(status.ok()); 82 return make_scoped_ptr<leveldb::DB>(db); 83 } 84 85 void SetUpInitialData(leveldb::DB* db) { 86 ServiceMetadata service_metadata; 87 service_metadata.set_largest_change_id(100); 88 service_metadata.set_sync_root_tracker_id(kSyncRootTrackerID); 89 service_metadata.set_next_tracker_id(next_tracker_id_); 90 91 FileDetails sync_root_details; 92 sync_root_details.set_title(kSyncRootFolderTitle); 93 sync_root_details.set_file_kind(FILE_KIND_FOLDER); 94 sync_root_details.set_change_id(1); 95 96 FileMetadata sync_root_metadata; 97 sync_root_metadata.set_file_id(sync_root_folder_id_); 98 *sync_root_metadata.mutable_details() = sync_root_details; 99 100 FileTracker sync_root_tracker; 101 sync_root_tracker.set_tracker_id(service_metadata.sync_root_tracker_id()); 102 sync_root_tracker.set_parent_tracker_id(0); 103 sync_root_tracker.set_file_id(sync_root_metadata.file_id()); 104 sync_root_tracker.set_tracker_kind(TRACKER_KIND_REGULAR); 105 *sync_root_tracker.mutable_synced_details() = sync_root_details; 106 sync_root_tracker.set_active(true); 107 108 leveldb::WriteBatch batch; 109 batch.Put(kDatabaseVersionKey, 110 base::Int64ToString(kCurrentDatabaseVersion)); 111 PutServiceMetadataToBatch(service_metadata, &batch); 112 PutFileToBatch(sync_root_metadata, &batch); 113 PutTrackerToBatch(sync_root_tracker, &batch); 114 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok()); 115 } 116 117 void CreateMetadataDatabase(scoped_ptr<leveldb::DB> db) { 118 ASSERT_TRUE(db); 119 ASSERT_FALSE(metadata_database_); 120 ASSERT_EQ(SYNC_STATUS_OK, 121 MetadataDatabase::CreateForTesting( 122 db.Pass(), &metadata_database_)); 123 } 124 125 SyncStatusCode RunRegisterAppTask(const std::string& app_id) { 126 RegisterAppTask task(this, app_id); 127 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 128 task.Run(CreateResultReceiver(&status)); 129 base::RunLoop().RunUntilIdle(); 130 return status; 131 } 132 133 void SetUpRegisteredAppRoot( 134 const std::string& app_id, 135 leveldb::DB* db) { 136 FileDetails details; 137 details.set_title(app_id); 138 details.set_file_kind(FILE_KIND_FOLDER); 139 details.add_parent_folder_ids(sync_root_folder_id_); 140 141 FileMetadata metadata; 142 metadata.set_file_id(GenerateFileID()); 143 *metadata.mutable_details() = details; 144 145 FileTracker tracker; 146 tracker.set_parent_tracker_id(kSyncRootTrackerID); 147 tracker.set_tracker_id(next_tracker_id_++); 148 tracker.set_file_id(metadata.file_id()); 149 tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 150 tracker.set_app_id(app_id); 151 *tracker.mutable_synced_details() = details; 152 tracker.set_active(true); 153 154 leveldb::WriteBatch batch; 155 PutFileToBatch(metadata, &batch); 156 PutTrackerToBatch(tracker, &batch); 157 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok()); 158 } 159 160 void SetUpUnregisteredAppRoot(const std::string& app_id, 161 leveldb::DB* db) { 162 FileDetails details; 163 details.set_title(app_id); 164 details.set_file_kind(FILE_KIND_FOLDER); 165 details.add_parent_folder_ids(sync_root_folder_id_); 166 167 FileMetadata metadata; 168 metadata.set_file_id(GenerateFileID()); 169 *metadata.mutable_details() = details; 170 171 FileTracker tracker; 172 tracker.set_parent_tracker_id(kSyncRootTrackerID); 173 tracker.set_tracker_id(next_tracker_id_++); 174 tracker.set_file_id(metadata.file_id()); 175 tracker.set_tracker_kind(TRACKER_KIND_REGULAR); 176 *tracker.mutable_synced_details() = details; 177 tracker.set_active(false); 178 179 leveldb::WriteBatch batch; 180 PutFileToBatch(metadata, &batch); 181 PutTrackerToBatch(tracker, &batch); 182 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok()); 183 } 184 185 size_t CountRegisteredAppRoot() { 186 // TODO(tzik): Add function to MetadataDatabase to list trackers by parent. 187 typedef MetadataDatabase::TrackersByTitle TrackersByTitle; 188 const TrackersByTitle& trackers_by_title = 189 metadata_database_->trackers_by_parent_and_title_[kSyncRootTrackerID]; 190 191 size_t count = 0; 192 for (TrackersByTitle::const_iterator itr = trackers_by_title.begin(); 193 itr != trackers_by_title.end(); ++itr) { 194 if (itr->second.has_active()) 195 ++count; 196 } 197 198 return count; 199 } 200 201 bool IsAppRegistered(const std::string& app_id) { 202 TrackerSet trackers; 203 if (!metadata_database_->FindTrackersByParentAndTitle( 204 kSyncRootTrackerID, app_id, &trackers)) 205 return false; 206 return trackers.has_active(); 207 } 208 209 size_t CountRemoteFileInSyncRoot() { 210 ScopedVector<google_apis::ResourceEntry> files; 211 EXPECT_EQ(google_apis::HTTP_SUCCESS, 212 fake_drive_service_helper_->ListFilesInFolder( 213 sync_root_folder_id_, &files)); 214 return files.size(); 215 } 216 217 bool HasRemoteAppRoot(const std::string& app_id) { 218 TrackerSet files; 219 if (!metadata_database_->FindTrackersByParentAndTitle( 220 kSyncRootTrackerID, app_id, &files) || 221 !files.has_active()) 222 return false; 223 224 std::string app_root_folder_id = files.active_tracker()->file_id(); 225 scoped_ptr<google_apis::ResourceEntry> entry; 226 if (google_apis::HTTP_SUCCESS != 227 fake_drive_service_helper_->GetResourceEntry( 228 app_root_folder_id, &entry)) 229 return false; 230 231 return !entry->deleted(); 232 } 233 234 private: 235 std::string GenerateFileID() { 236 return base::StringPrintf("file_id_%" PRId64, next_file_id_++); 237 } 238 239 std::string sync_root_folder_id_; 240 241 int64 next_file_id_; 242 int64 next_tracker_id_; 243 244 content::TestBrowserThreadBundle browser_threads_; 245 base::ScopedTempDir database_dir_; 246 247 scoped_ptr<drive::FakeDriveService> fake_drive_service_; 248 scoped_ptr<drive::DriveUploader> drive_uploader_; 249 scoped_ptr<FakeDriveServiceHelper> fake_drive_service_helper_; 250 251 scoped_ptr<MetadataDatabase> metadata_database_; 252 253 DISALLOW_COPY_AND_ASSIGN(RegisterAppTaskTest); 254}; 255 256TEST_F(RegisterAppTaskTest, AlreadyRegistered) { 257 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 258 ASSERT_TRUE(db); 259 SetUpInitialData(db.get()); 260 261 const std::string kAppID = "app_id"; 262 SetUpRegisteredAppRoot(kAppID, db.get()); 263 264 CreateMetadataDatabase(db.Pass()); 265 EXPECT_EQ(SYNC_STATUS_OK, RunRegisterAppTask(kAppID)); 266 267 EXPECT_EQ(1u, CountRegisteredAppRoot()); 268 EXPECT_TRUE(IsAppRegistered(kAppID)); 269} 270 271TEST_F(RegisterAppTaskTest, CreateAppFolder) { 272 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 273 ASSERT_TRUE(db); 274 SetUpInitialData(db.get()); 275 276 const std::string kAppID = "app_id"; 277 CreateMetadataDatabase(db.Pass()); 278 RunRegisterAppTask(kAppID); 279 280 EXPECT_EQ(1u, CountRegisteredAppRoot()); 281 EXPECT_TRUE(IsAppRegistered(kAppID)); 282 283 EXPECT_EQ(1u, CountRemoteFileInSyncRoot()); 284 EXPECT_TRUE(HasRemoteAppRoot(kAppID)); 285} 286 287TEST_F(RegisterAppTaskTest, RegisterExistingFolder) { 288 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 289 ASSERT_TRUE(db); 290 SetUpInitialData(db.get()); 291 292 const std::string kAppID = "app_id"; 293 SetUpUnregisteredAppRoot(kAppID, db.get()); 294 295 CreateMetadataDatabase(db.Pass()); 296 RunRegisterAppTask(kAppID); 297 298 EXPECT_EQ(1u, CountRegisteredAppRoot()); 299 EXPECT_TRUE(IsAppRegistered(kAppID)); 300} 301 302TEST_F(RegisterAppTaskTest, RegisterExistingFolder_MultipleCandidate) { 303 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 304 ASSERT_TRUE(db); 305 SetUpInitialData(db.get()); 306 307 const std::string kAppID = "app_id"; 308 SetUpUnregisteredAppRoot(kAppID, db.get()); 309 SetUpUnregisteredAppRoot(kAppID, db.get()); 310 311 CreateMetadataDatabase(db.Pass()); 312 RunRegisterAppTask(kAppID); 313 314 EXPECT_EQ(1u, CountRegisteredAppRoot()); 315 EXPECT_TRUE(IsAppRegistered(kAppID)); 316} 317 318} // namespace drive_backend 319} // namespace sync_file_system 320