register_app_task_unittest.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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/gdata_wapi_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 fake_drive_service_.reset(new drive::FakeDriveService); 50 51 drive_uploader_.reset(new drive::DriveUploader( 52 fake_drive_service_.get(), base::MessageLoopProxy::current())); 53 54 fake_drive_service_helper_.reset(new FakeDriveServiceHelper( 55 fake_drive_service_.get(), drive_uploader_.get(), 56 kSyncRootFolderTitle)); 57 58 context_.reset( 59 new SyncEngineContext(fake_drive_service_.get(), 60 drive_uploader_.get(), 61 base::MessageLoopProxy::current())); 62 63 ASSERT_EQ(google_apis::HTTP_CREATED, 64 fake_drive_service_helper_->AddOrphanedFolder( 65 kSyncRootFolderTitle, &sync_root_folder_id_)); 66 } 67 68 virtual void TearDown() OVERRIDE { 69 context_.reset(); 70 fake_drive_service_.reset(); 71 drive_uploader_.reset(); 72 base::RunLoop().RunUntilIdle(); 73 } 74 75 protected: 76 scoped_ptr<leveldb::DB> OpenLevelDB() { 77 leveldb::DB* db = NULL; 78 leveldb::Options options; 79 options.create_if_missing = true; 80 options.env = in_memory_env_.get(); 81 leveldb::Status status = 82 leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db); 83 EXPECT_TRUE(status.ok()); 84 return make_scoped_ptr<leveldb::DB>(db); 85 } 86 87 void SetUpInitialData(leveldb::DB* db) { 88 ServiceMetadata service_metadata; 89 service_metadata.set_largest_change_id(100); 90 service_metadata.set_sync_root_tracker_id(kSyncRootTrackerID); 91 service_metadata.set_next_tracker_id(next_tracker_id_); 92 93 FileDetails sync_root_details; 94 sync_root_details.set_title(kSyncRootFolderTitle); 95 sync_root_details.set_file_kind(FILE_KIND_FOLDER); 96 sync_root_details.set_change_id(1); 97 98 FileMetadata sync_root_metadata; 99 sync_root_metadata.set_file_id(sync_root_folder_id_); 100 *sync_root_metadata.mutable_details() = sync_root_details; 101 102 FileTracker sync_root_tracker; 103 sync_root_tracker.set_tracker_id(service_metadata.sync_root_tracker_id()); 104 sync_root_tracker.set_parent_tracker_id(0); 105 sync_root_tracker.set_file_id(sync_root_metadata.file_id()); 106 sync_root_tracker.set_tracker_kind(TRACKER_KIND_REGULAR); 107 *sync_root_tracker.mutable_synced_details() = sync_root_details; 108 sync_root_tracker.set_active(true); 109 110 leveldb::WriteBatch batch; 111 batch.Put(kDatabaseVersionKey, 112 base::Int64ToString(kCurrentDatabaseVersion)); 113 PutServiceMetadataToBatch(service_metadata, &batch); 114 PutFileMetadataToBatch(sync_root_metadata, &batch); 115 PutFileTrackerToBatch(sync_root_tracker, &batch); 116 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok()); 117 } 118 119 void CreateMetadataDatabase(scoped_ptr<leveldb::DB> db) { 120 ASSERT_TRUE(db); 121 ASSERT_FALSE(context_->GetMetadataDatabase()); 122 scoped_ptr<MetadataDatabase> metadata_db; 123 ASSERT_EQ(SYNC_STATUS_OK, 124 MetadataDatabase::CreateForTesting( 125 db.Pass(), &metadata_db)); 126 context_->SetMetadataDatabase(metadata_db.Pass()); 127 } 128 129 SyncStatusCode RunRegisterAppTask(const std::string& app_id) { 130 RegisterAppTask task(context_.get(), app_id); 131 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 132 task.RunExclusive(CreateResultReceiver(&status)); 133 base::RunLoop().RunUntilIdle(); 134 return status; 135 } 136 137 void SetUpRegisteredAppRoot( 138 const std::string& app_id, 139 leveldb::DB* db) { 140 FileDetails details; 141 details.set_title(app_id); 142 details.set_file_kind(FILE_KIND_FOLDER); 143 details.add_parent_folder_ids(sync_root_folder_id_); 144 145 FileMetadata metadata; 146 metadata.set_file_id(GenerateFileID()); 147 *metadata.mutable_details() = details; 148 149 FileTracker tracker; 150 tracker.set_parent_tracker_id(kSyncRootTrackerID); 151 tracker.set_tracker_id(next_tracker_id_++); 152 tracker.set_file_id(metadata.file_id()); 153 tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 154 tracker.set_app_id(app_id); 155 *tracker.mutable_synced_details() = details; 156 tracker.set_active(true); 157 158 leveldb::WriteBatch batch; 159 PutFileMetadataToBatch(metadata, &batch); 160 PutFileTrackerToBatch(tracker, &batch); 161 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok()); 162 } 163 164 void SetUpUnregisteredAppRoot(const std::string& app_id, 165 leveldb::DB* db) { 166 FileDetails details; 167 details.set_title(app_id); 168 details.set_file_kind(FILE_KIND_FOLDER); 169 details.add_parent_folder_ids(sync_root_folder_id_); 170 171 FileMetadata metadata; 172 metadata.set_file_id(GenerateFileID()); 173 *metadata.mutable_details() = details; 174 175 FileTracker tracker; 176 tracker.set_parent_tracker_id(kSyncRootTrackerID); 177 tracker.set_tracker_id(next_tracker_id_++); 178 tracker.set_file_id(metadata.file_id()); 179 tracker.set_tracker_kind(TRACKER_KIND_REGULAR); 180 *tracker.mutable_synced_details() = details; 181 tracker.set_active(false); 182 183 leveldb::WriteBatch batch; 184 PutFileMetadataToBatch(metadata, &batch); 185 PutFileTrackerToBatch(tracker, &batch); 186 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok()); 187 } 188 189 size_t CountRegisteredAppRoot() { 190 std::vector<std::string> app_ids; 191 context_->GetMetadataDatabase()->GetRegisteredAppIDs(&app_ids); 192 return app_ids.size(); 193 } 194 195 bool IsAppRegistered(const std::string& app_id) { 196 TrackerIDSet trackers; 197 if (!context_->GetMetadataDatabase()->FindTrackersByParentAndTitle( 198 kSyncRootTrackerID, app_id, &trackers)) 199 return false; 200 return trackers.has_active(); 201 } 202 203 size_t CountRemoteFileInSyncRoot() { 204 ScopedVector<google_apis::ResourceEntry> files; 205 EXPECT_EQ(google_apis::HTTP_SUCCESS, 206 fake_drive_service_helper_->ListFilesInFolder( 207 sync_root_folder_id_, &files)); 208 return files.size(); 209 } 210 211 bool HasRemoteAppRoot(const std::string& app_id) { 212 TrackerIDSet files; 213 if (!context_->GetMetadataDatabase()->FindTrackersByParentAndTitle( 214 kSyncRootTrackerID, app_id, &files) || 215 !files.has_active()) 216 return false; 217 218 FileTracker app_root_tracker; 219 EXPECT_TRUE(context_->GetMetadataDatabase()->FindTrackerByTrackerID( 220 files.active_tracker(), &app_root_tracker)); 221 std::string app_root_folder_id = app_root_tracker.file_id(); 222 scoped_ptr<google_apis::ResourceEntry> entry; 223 if (google_apis::HTTP_SUCCESS != 224 fake_drive_service_helper_->GetResourceEntry( 225 app_root_folder_id, &entry)) 226 return false; 227 228 return !entry->deleted(); 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<drive::FakeDriveService> fake_drive_service_; 248 scoped_ptr<drive::DriveUploaderInterface> drive_uploader_; 249 scoped_ptr<FakeDriveServiceHelper> fake_drive_service_helper_; 250 251 DISALLOW_COPY_AND_ASSIGN(RegisterAppTaskTest); 252}; 253 254TEST_F(RegisterAppTaskTest, AlreadyRegistered) { 255 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 256 ASSERT_TRUE(db); 257 SetUpInitialData(db.get()); 258 259 const std::string kAppID = "app_id"; 260 SetUpRegisteredAppRoot(kAppID, db.get()); 261 262 CreateMetadataDatabase(db.Pass()); 263 EXPECT_EQ(SYNC_STATUS_OK, RunRegisterAppTask(kAppID)); 264 265 EXPECT_EQ(1u, CountRegisteredAppRoot()); 266 EXPECT_TRUE(IsAppRegistered(kAppID)); 267} 268 269TEST_F(RegisterAppTaskTest, CreateAppFolder) { 270 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 271 ASSERT_TRUE(db); 272 SetUpInitialData(db.get()); 273 274 const std::string kAppID = "app_id"; 275 CreateMetadataDatabase(db.Pass()); 276 RunRegisterAppTask(kAppID); 277 278 EXPECT_EQ(1u, CountRegisteredAppRoot()); 279 EXPECT_TRUE(IsAppRegistered(kAppID)); 280 281 EXPECT_EQ(1u, CountRemoteFileInSyncRoot()); 282 EXPECT_TRUE(HasRemoteAppRoot(kAppID)); 283} 284 285TEST_F(RegisterAppTaskTest, RegisterExistingFolder) { 286 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 287 ASSERT_TRUE(db); 288 SetUpInitialData(db.get()); 289 290 const std::string kAppID = "app_id"; 291 SetUpUnregisteredAppRoot(kAppID, db.get()); 292 293 CreateMetadataDatabase(db.Pass()); 294 RunRegisterAppTask(kAppID); 295 296 EXPECT_EQ(1u, CountRegisteredAppRoot()); 297 EXPECT_TRUE(IsAppRegistered(kAppID)); 298} 299 300TEST_F(RegisterAppTaskTest, RegisterExistingFolder_MultipleCandidate) { 301 scoped_ptr<leveldb::DB> db(OpenLevelDB()); 302 ASSERT_TRUE(db); 303 SetUpInitialData(db.get()); 304 305 const std::string kAppID = "app_id"; 306 SetUpUnregisteredAppRoot(kAppID, db.get()); 307 SetUpUnregisteredAppRoot(kAppID, db.get()); 308 309 CreateMetadataDatabase(db.Pass()); 310 RunRegisterAppTask(kAppID); 311 312 EXPECT_EQ(1u, CountRegisteredAppRoot()); 313 EXPECT_TRUE(IsAppRegistered(kAppID)); 314} 315 316} // namespace drive_backend 317} // namespace sync_file_system 318