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