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