metadata_database_unittest.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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/metadata_database.h" 6 7#include "base/bind.h" 8#include "base/files/scoped_temp_dir.h" 9#include "base/message_loop/message_loop.h" 10#include "base/message_loop/message_loop_proxy.h" 11#include "base/strings/string_number_conversions.h" 12#include "chrome/browser/google_apis/drive_api_parser.h" 13#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 14#include "testing/gtest/include/gtest/gtest.h" 15#include "third_party/leveldatabase/src/include/leveldb/db.h" 16#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 17 18#define FPL(a) FILE_PATH_LITERAL(a) 19 20namespace sync_file_system { 21namespace drive_backend { 22 23typedef MetadataDatabase::FileSet FileSet; 24typedef MetadataDatabase::FileByFileID FileByFileID; 25typedef MetadataDatabase::FilesByParent FilesByParent; 26typedef MetadataDatabase::FileByParentAndTitle FileByParentAndTitle; 27typedef MetadataDatabase::FileByAppID FileByAppID; 28 29namespace { 30 31const int64 kInitialChangeID = 1234; 32const char kSyncRootFolderID[] = "sync_root_folder_id"; 33 34void ExpectEquivalent(const DriveFileMetadata::Details* left, 35 const DriveFileMetadata::Details* right) { 36 EXPECT_EQ(left->title(), right->title()); 37 EXPECT_EQ(left->kind(), right->kind()); 38 EXPECT_EQ(left->md5(), right->md5()); 39 EXPECT_EQ(left->etag(), right->etag()); 40 EXPECT_EQ(left->creation_time(), right->creation_time()); 41 EXPECT_EQ(left->modification_time(), right->modification_time()); 42 EXPECT_EQ(left->deleted(), right->deleted()); 43 EXPECT_EQ(left->change_id(), right->change_id()); 44} 45 46void ExpectEquivalent(const DriveFileMetadata* left, 47 const DriveFileMetadata* right) { 48 EXPECT_EQ(left->file_id(), right->file_id()); 49 EXPECT_EQ(left->parent_folder_id(), right->parent_folder_id()); 50 EXPECT_EQ(left->app_id(), right->app_id()); 51 EXPECT_EQ(left->is_app_root(), right->is_app_root()); 52 53 { 54 SCOPED_TRACE("Expect equivalent synced_details."); 55 ExpectEquivalent(&left->synced_details(), &right->synced_details()); 56 } 57 58 { 59 SCOPED_TRACE("Expect equivalent remote_details."); 60 ExpectEquivalent(&left->remote_details(), &right->remote_details()); 61 } 62 63 EXPECT_EQ(left->dirty(), right->dirty()); 64 EXPECT_EQ(left->active(), right->active()); 65 EXPECT_EQ(left->needs_folder_listing(), right->needs_folder_listing()); 66} 67 68template <typename Container> 69void ExpectEquivalentMaps(const Container& left, const Container& right); 70template <typename Key, typename Value, typename Compare> 71void ExpectEquivalent(const std::map<Key, Value, Compare>& left, 72 const std::map<Key, Value, Compare>& right) { 73 ExpectEquivalentMaps(left, right); 74} 75 76template <typename Container> 77void ExpectEquivalentSets(const Container& left, const Container& right); 78template <typename Value, typename Compare> 79void ExpectEquivalent(const std::set<Value, Compare>& left, 80 const std::set<Value, Compare>& right) { 81 return ExpectEquivalentSets(left, right); 82} 83 84template <typename Container> 85void ExpectEquivalentMaps(const Container& left, const Container& right) { 86 ASSERT_EQ(left.size(), right.size()); 87 88 typedef typename Container::const_iterator const_iterator; 89 const_iterator left_itr = left.begin(); 90 const_iterator right_itr = right.begin(); 91 while (left_itr != left.end()) { 92 EXPECT_EQ(left_itr->first, right_itr->first); 93 ExpectEquivalent(left_itr->second, right_itr->second); 94 ++left_itr; 95 ++right_itr; 96 } 97} 98 99template <typename Container> 100void ExpectEquivalentSets(const Container& left, const Container& right) { 101 ASSERT_EQ(left.size(), right.size()); 102 103 typedef typename Container::const_iterator const_iterator; 104 const_iterator left_itr = left.begin(); 105 const_iterator right_itr = right.begin(); 106 while (left_itr != left.end()) { 107 ExpectEquivalent(*left_itr, *right_itr); 108 ++left_itr; 109 ++right_itr; 110 } 111} 112 113void SyncStatusResultCallback(SyncStatusCode* status_out, 114 SyncStatusCode status) { 115 EXPECT_EQ(SYNC_STATUS_UNKNOWN, *status_out); 116 *status_out = status; 117} 118 119void DatabaseCreateResultCallback(SyncStatusCode* status_out, 120 scoped_ptr<MetadataDatabase>* database_out, 121 SyncStatusCode status, 122 scoped_ptr<MetadataDatabase> database) { 123 EXPECT_EQ(SYNC_STATUS_UNKNOWN, *status_out); 124 *status_out = status; 125 *database_out = database.Pass(); 126} 127 128} // namespace 129 130class MetadataDatabaseTest : public testing::Test { 131 public: 132 MetadataDatabaseTest() 133 : next_change_id_(kInitialChangeID + 1), 134 next_file_id_number_(1), 135 next_md5_sequence_number_(1) {} 136 137 virtual ~MetadataDatabaseTest() {} 138 139 virtual void SetUp() OVERRIDE { 140 ASSERT_TRUE(database_dir_.CreateUniqueTempDir()); 141 } 142 143 virtual void TearDown() OVERRIDE { DropDatabase(); } 144 145 protected: 146 std::string GenerateFileID() { 147 return "file_id_" + base::Int64ToString(next_file_id_number_++); 148 } 149 150 SyncStatusCode InitializeMetadataDatabase() { 151 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 152 MetadataDatabase::Create(base::MessageLoopProxy::current(), 153 database_dir_.path(), 154 base::Bind(&DatabaseCreateResultCallback, 155 &status, &metadata_database_)); 156 message_loop_.RunUntilIdle(); 157 return status; 158 } 159 160 void DropDatabase() { 161 metadata_database_.reset(); 162 message_loop_.RunUntilIdle(); 163 } 164 165 MetadataDatabase* metadata_database() { return metadata_database_.get(); } 166 167 leveldb::DB* db() { 168 if (!metadata_database_) 169 return NULL; 170 return metadata_database_->db_.get(); 171 } 172 173 scoped_ptr<leveldb::DB> InitializeLevelDB() { 174 leveldb::DB* db = NULL; 175 leveldb::Options options; 176 options.create_if_missing = true; 177 options.max_open_files = 0; // Use minimum. 178 leveldb::Status status = 179 leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db); 180 EXPECT_TRUE(status.ok()); 181 182 db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3)); 183 SetUpServiceMetadata(db); 184 185 return make_scoped_ptr(db); 186 } 187 188 void SetUpServiceMetadata(leveldb::DB* db) { 189 ServiceMetadata service_metadata; 190 service_metadata.set_largest_change_id(kInitialChangeID); 191 service_metadata.set_sync_root_folder_id(kSyncRootFolderID); 192 std::string value; 193 ASSERT_TRUE(service_metadata.SerializeToString(&value)); 194 db->Put(leveldb::WriteOptions(), "SERVICE", value); 195 } 196 197 DriveFileMetadata CreateSyncRootMetadata() { 198 DriveFileMetadata sync_root; 199 sync_root.set_file_id(kSyncRootFolderID); 200 sync_root.set_parent_folder_id(std::string()); 201 sync_root.mutable_synced_details()->set_title("Chrome Syncable FileSystem"); 202 sync_root.mutable_synced_details()->set_kind(KIND_FOLDER); 203 sync_root.set_active(true); 204 sync_root.set_dirty(false); 205 return sync_root; 206 } 207 208 DriveFileMetadata CreateAppRootMetadata(const DriveFileMetadata& sync_root, 209 const std::string& app_id) { 210 DriveFileMetadata app_root( 211 CreateFolderMetadata(sync_root, app_id /* title */)); 212 app_root.set_app_id(app_id); 213 app_root.set_is_app_root(true); 214 return app_root; 215 } 216 217 DriveFileMetadata CreateUnknownFileMetadata(const DriveFileMetadata& parent) { 218 DriveFileMetadata file; 219 file.set_file_id(GenerateFileID()); 220 file.set_parent_folder_id(parent.file_id()); 221 file.set_app_id(parent.app_id()); 222 file.set_is_app_root(false); 223 return file; 224 } 225 226 DriveFileMetadata CreateFileMetadata(const DriveFileMetadata& parent, 227 const std::string& title) { 228 DriveFileMetadata file(CreateUnknownFileMetadata(parent)); 229 file.mutable_synced_details()->add_parent_folder_id(parent.file_id()); 230 file.mutable_synced_details()->set_title(title); 231 file.mutable_synced_details()->set_kind(KIND_FILE); 232 file.mutable_synced_details()->set_md5( 233 "md5_value_" + base::Int64ToString(next_md5_sequence_number_++)); 234 file.set_active(true); 235 file.set_dirty(false); 236 return file; 237 } 238 239 DriveFileMetadata CreateFolderMetadata(const DriveFileMetadata& parent, 240 const std::string& title) { 241 DriveFileMetadata folder(CreateUnknownFileMetadata(parent)); 242 folder.mutable_synced_details()->add_parent_folder_id(parent.file_id()); 243 folder.mutable_synced_details()->set_title(title); 244 folder.mutable_synced_details()->set_kind(KIND_FOLDER); 245 folder.set_active(true); 246 folder.set_dirty(false); 247 return folder; 248 } 249 250 scoped_ptr<google_apis::ChangeResource> CreateChangeResourceFromMetadata( 251 const DriveFileMetadata& file) { 252 scoped_ptr<google_apis::ChangeResource> change( 253 new google_apis::ChangeResource); 254 change->set_change_id(file.remote_details().change_id()); 255 change->set_file_id(file.file_id()); 256 change->set_deleted(file.remote_details().deleted()); 257 if (change->is_deleted()) 258 return change.Pass(); 259 260 scoped_ptr<google_apis::FileResource> file_resource( 261 new google_apis::FileResource); 262 ScopedVector<google_apis::ParentReference> parents; 263 for (int i = 0; i < file.remote_details().parent_folder_id_size(); ++i) { 264 scoped_ptr<google_apis::ParentReference> parent( 265 new google_apis::ParentReference); 266 parent->set_file_id(file.remote_details().parent_folder_id(i)); 267 parents.push_back(parent.release()); 268 } 269 270 file_resource->set_file_id(file.file_id()); 271 file_resource->set_parents(&parents); 272 file_resource->set_title(file.remote_details().title()); 273 if (file.remote_details().kind() == KIND_FOLDER) 274 file_resource->set_mime_type("application/vnd.google-apps.folder"); 275 else if (file.remote_details().kind() == KIND_FILE) 276 file_resource->set_mime_type("text/plain"); 277 else 278 file_resource->set_mime_type("application/vnd.google-apps.document"); 279 file_resource->set_md5_checksum(file.remote_details().md5()); 280 file_resource->set_etag(file.remote_details().etag()); 281 file_resource->set_created_date(base::Time::FromInternalValue( 282 file.remote_details().creation_time())); 283 file_resource->set_modified_date(base::Time::FromInternalValue( 284 file.remote_details().modification_time())); 285 286 change->set_file(file_resource.Pass()); 287 return change.Pass(); 288 } 289 290 void ApplyRenameChangeToMetadata(const std::string& new_title, 291 DriveFileMetadata* file) { 292 DriveFileMetadata::Details* details = file->mutable_remote_details(); 293 *details = file->synced_details(); 294 details->set_title(new_title); 295 details->set_change_id(next_change_id_++); 296 file->set_dirty(true); 297 } 298 299 void ApplyReorganizeChangeToMetadata(const std::string& new_parent, 300 DriveFileMetadata* file) { 301 DriveFileMetadata::Details* details = file->mutable_remote_details(); 302 *details = file->synced_details(); 303 details->clear_parent_folder_id(); 304 details->add_parent_folder_id(new_parent); 305 details->set_change_id(next_change_id_++); 306 file->set_dirty(true); 307 } 308 309 void ApplyContentChangeToMetadata(DriveFileMetadata* file) { 310 DriveFileMetadata::Details* details = file->mutable_remote_details(); 311 *details = file->synced_details(); 312 details->set_md5( 313 "md5_value_" + base::Int64ToString(next_md5_sequence_number_++)); 314 details->set_change_id(next_change_id_++); 315 file->set_dirty(true); 316 } 317 318 void ApplyNoopChangeToMetadata(DriveFileMetadata* file) { 319 *file->mutable_remote_details() = file->synced_details(); 320 file->mutable_remote_details()->set_change_id(next_change_id_++); 321 file->set_dirty(true); 322 } 323 324 void ApplyNewFileChangeToMetadata(DriveFileMetadata* file) { 325 *file->mutable_remote_details() = file->synced_details(); 326 file->clear_synced_details(); 327 file->mutable_remote_details()->set_change_id(next_change_id_++); 328 file->set_active(false); 329 file->set_dirty(true); 330 } 331 332 void PushToChangeList(scoped_ptr<google_apis::ChangeResource> change, 333 ScopedVector<google_apis::ChangeResource>* changes) { 334 changes->push_back(change.release()); 335 } 336 337 leveldb::Status PutFileToDB(leveldb::DB* db, const DriveFileMetadata& file) { 338 std::string key = "FILE: " + file.file_id(); 339 std::string value; 340 file.SerializeToString(&value); 341 return db->Put(leveldb::WriteOptions(), key, value); 342 } 343 344 void VerifyReloadConsistency() { 345 scoped_ptr<MetadataDatabase> metadata_database_2; 346 ASSERT_EQ(SYNC_STATUS_OK, 347 MetadataDatabase::CreateForTesting( 348 metadata_database_->db_.Pass(), 349 &metadata_database_2)); 350 metadata_database_->db_ = metadata_database_2->db_.Pass(); 351 352 { 353 SCOPED_TRACE("Expect equivalent file_by_file_id_ contents."); 354 ExpectEquivalent(metadata_database_->file_by_file_id_, 355 metadata_database_2->file_by_file_id_); 356 } 357 358 { 359 SCOPED_TRACE("Expect equivalent files_by_parent_ contents."); 360 ExpectEquivalent(metadata_database_->files_by_parent_, 361 metadata_database_2->files_by_parent_); 362 } 363 364 { 365 SCOPED_TRACE("Expect equivalent app_root_by_app_id_ contents."); 366 ExpectEquivalent(metadata_database_->app_root_by_app_id_, 367 metadata_database_2->app_root_by_app_id_); 368 } 369 370 { 371 SCOPED_TRACE("Expect equivalent" 372 " active_file_by_parent_and_title_ contents."); 373 ExpectEquivalent(metadata_database_->active_file_by_parent_and_title_, 374 metadata_database_2->active_file_by_parent_and_title_); 375 } 376 377 { 378 SCOPED_TRACE("Expect equivalent dirty_files_ contents."); 379 ExpectEquivalent(metadata_database_->dirty_files_, 380 metadata_database_2->dirty_files_); 381 } 382 } 383 384 void VerifyFile(const DriveFileMetadata& file) { 385 DriveFileMetadata file_in_metadata_db; 386 ASSERT_TRUE(metadata_database()->FindFileByFileID( 387 file.file_id(), &file_in_metadata_db)); 388 389 SCOPED_TRACE("Expect equivalent " + file.file_id()); 390 ExpectEquivalent(&file, &file_in_metadata_db); 391 } 392 393 SyncStatusCode RegisterApp(const std::string& app_id, 394 const std::string& folder_id) { 395 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 396 metadata_database_->RegisterApp( 397 app_id, folder_id, 398 base::Bind(&SyncStatusResultCallback, &status)); 399 message_loop_.RunUntilIdle(); 400 return status; 401 } 402 403 SyncStatusCode DisableApp(const std::string& app_id) { 404 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 405 metadata_database_->DisableApp( 406 app_id, base::Bind(&SyncStatusResultCallback, &status)); 407 message_loop_.RunUntilIdle(); 408 return status; 409 } 410 411 SyncStatusCode EnableApp(const std::string& app_id) { 412 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 413 metadata_database_->EnableApp( 414 app_id, base::Bind(&SyncStatusResultCallback, &status)); 415 message_loop_.RunUntilIdle(); 416 return status; 417 } 418 419 SyncStatusCode UnregisterApp(const std::string& app_id) { 420 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 421 metadata_database_->UnregisterApp( 422 app_id, base::Bind(&SyncStatusResultCallback, &status)); 423 message_loop_.RunUntilIdle(); 424 return status; 425 } 426 427 SyncStatusCode UpdateByChangeList( 428 ScopedVector<google_apis::ChangeResource> changes) { 429 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 430 metadata_database_->UpdateByChangeList( 431 changes.Pass(), base::Bind(&SyncStatusResultCallback, &status)); 432 message_loop_.RunUntilIdle(); 433 return status; 434 } 435 436 private: 437 438 base::ScopedTempDir database_dir_; 439 base::MessageLoop message_loop_; 440 441 scoped_ptr<MetadataDatabase> metadata_database_; 442 443 int64 next_change_id_; 444 int64 next_file_id_number_; 445 int64 next_md5_sequence_number_; 446 447 DISALLOW_COPY_AND_ASSIGN(MetadataDatabaseTest); 448}; 449 450TEST_F(MetadataDatabaseTest, InitializationTest_Empty) { 451 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 452 DropDatabase(); 453 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 454} 455 456TEST_F(MetadataDatabaseTest, InitializationTest_SimpleTree) { 457 std::string app_id = "app_id"; 458 DriveFileMetadata sync_root(CreateSyncRootMetadata()); 459 DriveFileMetadata app_root(CreateAppRootMetadata(sync_root, "app_id")); 460 DriveFileMetadata file(CreateFileMetadata(app_root, "file")); 461 DriveFileMetadata folder(CreateFolderMetadata(app_root, "folder")); 462 DriveFileMetadata file_in_folder( 463 CreateFileMetadata(folder, "file_in_folder")); 464 DriveFileMetadata orphaned(CreateUnknownFileMetadata(sync_root)); 465 orphaned.set_parent_folder_id(std::string()); 466 467 { 468 scoped_ptr<leveldb::DB> db = InitializeLevelDB(); 469 ASSERT_TRUE(db); 470 471 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok()); 472 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok()); 473 EXPECT_TRUE(PutFileToDB(db.get(), file).ok()); 474 EXPECT_TRUE(PutFileToDB(db.get(), folder).ok()); 475 EXPECT_TRUE(PutFileToDB(db.get(), file_in_folder).ok()); 476 EXPECT_TRUE(PutFileToDB(db.get(), orphaned).ok()); 477 } 478 479 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 480 481 VerifyFile(sync_root); 482 VerifyFile(app_root); 483 VerifyFile(file); 484 VerifyFile(folder); 485 VerifyFile(file_in_folder); 486 EXPECT_FALSE(metadata_database()->FindFileByFileID(orphaned.file_id(), NULL)); 487} 488 489TEST_F(MetadataDatabaseTest, AppManagementTest) { 490 DriveFileMetadata sync_root(CreateSyncRootMetadata()); 491 DriveFileMetadata app_root(CreateAppRootMetadata(sync_root, "app_id")); 492 DriveFileMetadata folder(CreateFolderMetadata(sync_root, "folder")); 493 folder.set_active(false); 494 495 { 496 scoped_ptr<leveldb::DB> db = InitializeLevelDB(); 497 ASSERT_TRUE(db); 498 499 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok()); 500 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok()); 501 EXPECT_TRUE(PutFileToDB(db.get(), folder).ok()); 502 } 503 504 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 505 VerifyFile(sync_root); 506 VerifyFile(app_root); 507 VerifyFile(folder); 508 509 folder.set_app_id("foo"); 510 EXPECT_EQ(SYNC_STATUS_OK, RegisterApp(folder.app_id(), folder.file_id())); 511 512 folder.set_is_app_root(true); 513 folder.set_active(true); 514 folder.set_dirty(true); 515 folder.set_needs_folder_listing(true); 516 VerifyFile(folder); 517 VerifyReloadConsistency(); 518 519 EXPECT_EQ(SYNC_STATUS_OK, DisableApp(folder.app_id())); 520 folder.set_active(false); 521 VerifyFile(folder); 522 VerifyReloadConsistency(); 523 524 EXPECT_EQ(SYNC_STATUS_OK, EnableApp(folder.app_id())); 525 folder.set_active(true); 526 VerifyFile(folder); 527 VerifyReloadConsistency(); 528 529 EXPECT_EQ(SYNC_STATUS_OK, UnregisterApp(folder.app_id())); 530 folder.set_app_id(std::string()); 531 folder.set_is_app_root(false); 532 folder.set_active(false); 533 VerifyFile(folder); 534 VerifyReloadConsistency(); 535} 536 537TEST_F(MetadataDatabaseTest, BuildPathTest) { 538 DriveFileMetadata sync_root(CreateSyncRootMetadata()); 539 DriveFileMetadata app_root( 540 CreateAppRootMetadata(sync_root, "app_id")); 541 DriveFileMetadata folder(CreateFolderMetadata(app_root, "folder")); 542 DriveFileMetadata file(CreateFolderMetadata(folder, "file")); 543 DriveFileMetadata inactive_folder(CreateFolderMetadata(app_root, "folder")); 544 545 { 546 scoped_ptr<leveldb::DB> db = InitializeLevelDB(); 547 ASSERT_TRUE(db); 548 549 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok()); 550 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok()); 551 EXPECT_TRUE(PutFileToDB(db.get(), folder).ok()); 552 EXPECT_TRUE(PutFileToDB(db.get(), file).ok()); 553 } 554 555 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 556 557 base::FilePath path; 558 EXPECT_FALSE(metadata_database()->BuildPathForFile(sync_root.file_id(), 559 &path)); 560 EXPECT_TRUE(metadata_database()->BuildPathForFile(app_root.file_id(), &path)); 561 EXPECT_EQ(base::FilePath(FPL("/")).NormalizePathSeparators(), 562 path); 563 EXPECT_TRUE(metadata_database()->BuildPathForFile(file.file_id(), &path)); 564 EXPECT_EQ(base::FilePath(FPL("/folder/file")).NormalizePathSeparators(), 565 path); 566} 567 568TEST_F(MetadataDatabaseTest, UpdateByChangeListTest) { 569 DriveFileMetadata sync_root(CreateSyncRootMetadata()); 570 DriveFileMetadata app_root(CreateAppRootMetadata(sync_root, "app_id")); 571 DriveFileMetadata disabled_app_root( 572 CreateAppRootMetadata(sync_root, "disabled_app")); 573 DriveFileMetadata file(CreateFileMetadata(app_root, "file")); 574 DriveFileMetadata renamed_file(CreateFileMetadata(app_root, "to be renamed")); 575 DriveFileMetadata folder(CreateFolderMetadata(app_root, "folder")); 576 DriveFileMetadata reorganized_file( 577 CreateFileMetadata(app_root, "to be reorganized")); 578 DriveFileMetadata updated_file(CreateFileMetadata(app_root, "to be updated")); 579 DriveFileMetadata noop_file(CreateFileMetadata(app_root, "have noop change")); 580 DriveFileMetadata new_file(CreateFileMetadata(app_root, "to be added later")); 581 582 { 583 scoped_ptr<leveldb::DB> db = InitializeLevelDB(); 584 ASSERT_TRUE(db); 585 586 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok()); 587 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok()); 588 EXPECT_TRUE(PutFileToDB(db.get(), disabled_app_root).ok()); 589 EXPECT_TRUE(PutFileToDB(db.get(), file).ok()); 590 EXPECT_TRUE(PutFileToDB(db.get(), renamed_file).ok()); 591 EXPECT_TRUE(PutFileToDB(db.get(), folder).ok()); 592 EXPECT_TRUE(PutFileToDB(db.get(), reorganized_file).ok()); 593 EXPECT_TRUE(PutFileToDB(db.get(), updated_file).ok()); 594 EXPECT_TRUE(PutFileToDB(db.get(), noop_file).ok()); 595 } 596 597 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 598 599 ApplyRenameChangeToMetadata("renamed", &renamed_file); 600 ApplyReorganizeChangeToMetadata(folder.file_id(), &reorganized_file); 601 ApplyContentChangeToMetadata(&updated_file); 602 ApplyNoopChangeToMetadata(&noop_file); 603 ApplyNewFileChangeToMetadata(&new_file); 604 605 ScopedVector<google_apis::ChangeResource> changes; 606 PushToChangeList(CreateChangeResourceFromMetadata(renamed_file), &changes); 607 PushToChangeList(CreateChangeResourceFromMetadata( 608 reorganized_file), &changes); 609 PushToChangeList(CreateChangeResourceFromMetadata(updated_file), &changes); 610 PushToChangeList(CreateChangeResourceFromMetadata(noop_file), &changes); 611 PushToChangeList(CreateChangeResourceFromMetadata(new_file), &changes); 612 EXPECT_EQ(SYNC_STATUS_OK, UpdateByChangeList(changes.Pass())); 613 614 VerifyFile(sync_root); 615 VerifyFile(app_root); 616 VerifyFile(disabled_app_root); 617 VerifyFile(file); 618 VerifyFile(renamed_file); 619 VerifyFile(folder); 620 VerifyFile(reorganized_file); 621 VerifyFile(updated_file); 622 VerifyFile(noop_file); 623 VerifyFile(new_file); 624 VerifyReloadConsistency(); 625} 626 627} // namespace drive_backend 628} // namespace sync_file_system 629