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/sync_file_system/drive_backend/drive_backend_constants.h" 13 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h" 14 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 15 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 16 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index.h" 17 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_interface.h" 18 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h" 19 #include "google_apis/drive/drive_api_parser.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" 22 #include "third_party/leveldatabase/src/include/leveldb/db.h" 23 #include "third_party/leveldatabase/src/include/leveldb/env.h" 24 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 25 26 #define FPL(a) FILE_PATH_LITERAL(a) 27 28 namespace sync_file_system { 29 namespace drive_backend { 30 31 namespace { 32 33 typedef MetadataDatabase::FileIDList FileIDList; 34 35 const int64 kInitialChangeID = 1234; 36 const int64 kSyncRootTrackerID = 100; 37 const char kSyncRootFolderID[] = "sync_root_folder_id"; 38 39 // This struct is used to setup initial state of the database in the test and 40 // also used to match to the modified content of the database as the 41 // expectation. 42 struct TrackedFile { 43 // Holds the latest remote metadata which may be not-yet-synced to |tracker|. 44 FileMetadata metadata; 45 FileTracker tracker; 46 47 // Implies the file should not in the database. 48 bool should_be_absent; 49 50 // Implies the file should have a tracker in the database but should have no 51 // metadata. 52 bool tracker_only; 53 54 TrackedFile() : should_be_absent(false), tracker_only(false) {} 55 }; 56 57 void ExpectEquivalent(const ServiceMetadata* left, 58 const ServiceMetadata* right) { 59 test_util::ExpectEquivalentServiceMetadata(*left, *right); 60 } 61 62 void ExpectEquivalent(const FileMetadata* left, const FileMetadata* right) { 63 if (!left) { 64 ASSERT_FALSE(right); 65 return; 66 } 67 ASSERT_TRUE(right); 68 test_util::ExpectEquivalentMetadata(*left, *right); 69 } 70 71 void ExpectEquivalent(const FileTracker* left, const FileTracker* right) { 72 if (!left) { 73 ASSERT_FALSE(right); 74 return; 75 } 76 ASSERT_TRUE(right); 77 test_util::ExpectEquivalentTrackers(*left, *right); 78 } 79 80 void ExpectEquivalent(int64 left, int64 right) { 81 EXPECT_EQ(left, right); 82 } 83 84 template <typename Container> 85 void ExpectEquivalentMaps(const Container& left, const Container& right); 86 87 template <typename Key, typename Value> 88 void ExpectEquivalent(const std::map<Key, Value>& left, 89 const std::map<Key, Value>& right) { 90 ExpectEquivalentMaps(left, right); 91 } 92 93 template <typename Key, typename Value> 94 void ExpectEquivalent(const base::hash_map<Key, Value>& left, 95 const base::hash_map<Key, Value>& right) { 96 ExpectEquivalentMaps(std::map<Key, Value>(left.begin(), left.end()), 97 std::map<Key, Value>(right.begin(), right.end())); 98 } 99 100 template <typename Key, typename Value> 101 void ExpectEquivalent(const base::ScopedPtrHashMap<Key, Value>& left, 102 const base::ScopedPtrHashMap<Key, Value>& right) { 103 ExpectEquivalentMaps(std::map<Key, Value*>(left.begin(), left.end()), 104 std::map<Key, Value*>(right.begin(), right.end())); 105 } 106 107 template <typename Container> 108 void ExpectEquivalentSets(const Container& left, const Container& right); 109 110 template <typename Value, typename Comparator> 111 void ExpectEquivalent(const std::set<Value, Comparator>& left, 112 const std::set<Value, Comparator>& right) { 113 return ExpectEquivalentSets(left, right); 114 } 115 116 template <typename Value> 117 void ExpectEquivalent(const base::hash_set<Value>& left, 118 const base::hash_set<Value>& right) { 119 return ExpectEquivalentSets(std::set<Value>(left.begin(), left.end()), 120 std::set<Value>(right.begin(), right.end())); 121 } 122 123 void ExpectEquivalent(const TrackerIDSet& left, 124 const TrackerIDSet& right) { 125 { 126 SCOPED_TRACE("Expect equivalent active_tracker"); 127 EXPECT_EQ(left.active_tracker(), right.active_tracker()); 128 } 129 ExpectEquivalent(left.tracker_set(), right.tracker_set()); 130 } 131 132 template <typename Container> 133 void ExpectEquivalentMaps(const Container& left, const Container& right) { 134 ASSERT_EQ(left.size(), right.size()); 135 136 typedef typename Container::const_iterator const_iterator; 137 const_iterator left_itr = left.begin(); 138 const_iterator right_itr = right.begin(); 139 while (left_itr != left.end()) { 140 EXPECT_EQ(left_itr->first, right_itr->first); 141 ExpectEquivalent(left_itr->second, right_itr->second); 142 ++left_itr; 143 ++right_itr; 144 } 145 } 146 147 template <typename Container> 148 void ExpectEquivalentSets(const Container& left, const Container& right) { 149 ASSERT_EQ(left.size(), right.size()); 150 151 typedef typename Container::const_iterator const_iterator; 152 const_iterator left_itr = left.begin(); 153 const_iterator right_itr = right.begin(); 154 while (left_itr != left.end()) { 155 ExpectEquivalent(*left_itr, *right_itr); 156 ++left_itr; 157 ++right_itr; 158 } 159 } 160 161 base::FilePath CreateNormalizedPath(const base::FilePath::StringType& path) { 162 return base::FilePath(path).NormalizePathSeparators(); 163 } 164 165 } // namespace 166 167 class MetadataDatabaseTest : public testing::Test { 168 public: 169 MetadataDatabaseTest() 170 : current_change_id_(kInitialChangeID), 171 next_tracker_id_(kSyncRootTrackerID + 1), 172 next_file_id_number_(1), 173 next_md5_sequence_number_(1) {} 174 175 virtual ~MetadataDatabaseTest() {} 176 177 virtual void SetUp() OVERRIDE { 178 ASSERT_TRUE(database_dir_.CreateUniqueTempDir()); 179 in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default())); 180 } 181 182 virtual void TearDown() OVERRIDE { DropDatabase(); } 183 184 protected: 185 std::string GenerateFileID() { 186 return "file_id_" + base::Int64ToString(next_file_id_number_++); 187 } 188 189 int64 GetTrackerIDByFileID(const std::string& file_id) { 190 TrackerIDSet trackers; 191 if (metadata_database_->FindTrackersByFileID(file_id, &trackers)) { 192 EXPECT_FALSE(trackers.empty()); 193 return *trackers.begin(); 194 } 195 return 0; 196 } 197 198 SyncStatusCode InitializeMetadataDatabase() { 199 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 200 MetadataDatabase::Create(base::MessageLoopProxy::current(), 201 base::MessageLoopProxy::current(), 202 database_dir_.path(), 203 in_memory_env_.get(), 204 CreateResultReceiver(&status, 205 &metadata_database_)); 206 message_loop_.RunUntilIdle(); 207 return status; 208 } 209 210 void DropDatabase() { 211 metadata_database_.reset(); 212 message_loop_.RunUntilIdle(); 213 } 214 215 void SetUpDatabaseByTrackedFiles(const TrackedFile** tracked_files, 216 int size) { 217 scoped_ptr<leveldb::DB> db = InitializeLevelDB(); 218 ASSERT_TRUE(db); 219 220 for (int i = 0; i < size; ++i) { 221 const TrackedFile* file = tracked_files[i]; 222 if (file->should_be_absent) 223 continue; 224 if (!file->tracker_only) 225 EXPECT_TRUE(PutFileToDB(db.get(), file->metadata).ok()); 226 EXPECT_TRUE(PutTrackerToDB(db.get(), file->tracker).ok()); 227 } 228 } 229 230 void VerifyTrackedFile(const TrackedFile& file) { 231 if (!file.should_be_absent) { 232 if (file.tracker_only) { 233 EXPECT_FALSE(metadata_database()->FindFileByFileID( 234 file.metadata.file_id(), NULL)); 235 } else { 236 VerifyFile(file.metadata); 237 } 238 VerifyTracker(file.tracker); 239 return; 240 } 241 242 EXPECT_FALSE(metadata_database()->FindFileByFileID( 243 file.metadata.file_id(), NULL)); 244 EXPECT_FALSE(metadata_database()->FindTrackerByTrackerID( 245 file.tracker.tracker_id(), NULL)); 246 } 247 248 void VerifyTrackedFiles(const TrackedFile** tracked_files, int size) { 249 for (int i = 0; i < size; ++i) 250 VerifyTrackedFile(*tracked_files[i]); 251 } 252 253 MetadataDatabase* metadata_database() { return metadata_database_.get(); } 254 255 scoped_ptr<leveldb::DB> InitializeLevelDB() { 256 leveldb::DB* db = NULL; 257 leveldb::Options options; 258 options.create_if_missing = true; 259 options.max_open_files = 0; // Use minimum. 260 options.env = in_memory_env_.get(); 261 leveldb::Status status = 262 leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db); 263 EXPECT_TRUE(status.ok()); 264 265 db->Put(leveldb::WriteOptions(), 266 kDatabaseVersionKey, 267 base::Int64ToString(3)); 268 SetUpServiceMetadata(db); 269 270 return make_scoped_ptr(db); 271 } 272 273 void SetUpServiceMetadata(leveldb::DB* db) { 274 ServiceMetadata service_metadata; 275 service_metadata.set_largest_change_id(kInitialChangeID); 276 service_metadata.set_sync_root_tracker_id(kSyncRootTrackerID); 277 service_metadata.set_next_tracker_id(next_tracker_id_); 278 leveldb::WriteBatch batch; 279 PutServiceMetadataToBatch(service_metadata, &batch); 280 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok()); 281 } 282 283 FileMetadata CreateSyncRootMetadata() { 284 FileMetadata sync_root; 285 sync_root.set_file_id(kSyncRootFolderID); 286 FileDetails* details = sync_root.mutable_details(); 287 details->set_title(kSyncRootFolderTitle); 288 details->set_file_kind(FILE_KIND_FOLDER); 289 details->set_change_id(current_change_id_); 290 return sync_root; 291 } 292 293 FileMetadata CreateFileMetadata(const FileMetadata& parent, 294 const std::string& title) { 295 FileMetadata file; 296 file.set_file_id(GenerateFileID()); 297 FileDetails* details = file.mutable_details(); 298 details->add_parent_folder_ids(parent.file_id()); 299 details->set_title(title); 300 details->set_file_kind(FILE_KIND_FILE); 301 details->set_md5( 302 "md5_value_" + base::Int64ToString(next_md5_sequence_number_++)); 303 details->set_change_id(current_change_id_); 304 return file; 305 } 306 307 FileMetadata CreateFolderMetadata(const FileMetadata& parent, 308 const std::string& title) { 309 FileMetadata folder; 310 folder.set_file_id(GenerateFileID()); 311 FileDetails* details = folder.mutable_details(); 312 details->add_parent_folder_ids(parent.file_id()); 313 details->set_title(title); 314 details->set_file_kind(FILE_KIND_FOLDER); 315 details->set_change_id(current_change_id_); 316 return folder; 317 } 318 319 FileTracker CreateSyncRootTracker(const FileMetadata& sync_root) { 320 FileTracker sync_root_tracker; 321 sync_root_tracker.set_tracker_id(kSyncRootTrackerID); 322 sync_root_tracker.set_parent_tracker_id(0); 323 sync_root_tracker.set_file_id(sync_root.file_id()); 324 sync_root_tracker.set_dirty(false); 325 sync_root_tracker.set_active(true); 326 sync_root_tracker.set_needs_folder_listing(false); 327 *sync_root_tracker.mutable_synced_details() = sync_root.details(); 328 return sync_root_tracker; 329 } 330 331 FileTracker CreateTracker(const FileTracker& parent_tracker, 332 const FileMetadata& file) { 333 FileTracker tracker; 334 tracker.set_tracker_id(next_tracker_id_++); 335 tracker.set_parent_tracker_id(parent_tracker.tracker_id()); 336 tracker.set_file_id(file.file_id()); 337 tracker.set_app_id(parent_tracker.app_id()); 338 tracker.set_tracker_kind(TRACKER_KIND_REGULAR); 339 tracker.set_dirty(false); 340 tracker.set_active(true); 341 tracker.set_needs_folder_listing(false); 342 *tracker.mutable_synced_details() = file.details(); 343 return tracker; 344 } 345 346 TrackedFile CreateTrackedSyncRoot() { 347 TrackedFile sync_root; 348 sync_root.metadata = CreateSyncRootMetadata(); 349 sync_root.tracker = CreateSyncRootTracker(sync_root.metadata); 350 return sync_root; 351 } 352 353 TrackedFile CreateTrackedAppRoot(const TrackedFile& sync_root, 354 const std::string& app_id) { 355 TrackedFile app_root(CreateTrackedFolder(sync_root, app_id)); 356 app_root.tracker.set_app_id(app_id); 357 app_root.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 358 return app_root; 359 } 360 361 TrackedFile CreateTrackedFile(const TrackedFile& parent, 362 const std::string& title) { 363 TrackedFile file; 364 file.metadata = CreateFileMetadata(parent.metadata, title); 365 file.tracker = CreateTracker(parent.tracker, file.metadata); 366 return file; 367 } 368 369 TrackedFile CreateTrackedFolder(const TrackedFile& parent, 370 const std::string& title) { 371 TrackedFile folder; 372 folder.metadata = CreateFolderMetadata(parent.metadata, title); 373 folder.tracker = CreateTracker(parent.tracker, folder.metadata); 374 return folder; 375 } 376 377 scoped_ptr<google_apis::FileResource> CreateFileResourceFromMetadata( 378 const FileMetadata& file) { 379 scoped_ptr<google_apis::FileResource> file_resource( 380 new google_apis::FileResource); 381 for (int i = 0; i < file.details().parent_folder_ids_size(); ++i) { 382 google_apis::ParentReference parent; 383 parent.set_file_id(file.details().parent_folder_ids(i)); 384 file_resource->mutable_parents()->push_back(parent); 385 } 386 387 file_resource->set_file_id(file.file_id()); 388 file_resource->set_title(file.details().title()); 389 if (file.details().file_kind() == FILE_KIND_FOLDER) 390 file_resource->set_mime_type("application/vnd.google-apps.folder"); 391 else if (file.details().file_kind() == FILE_KIND_FILE) 392 file_resource->set_mime_type("text/plain"); 393 else 394 file_resource->set_mime_type("application/vnd.google-apps.document"); 395 file_resource->set_md5_checksum(file.details().md5()); 396 file_resource->set_etag(file.details().etag()); 397 file_resource->set_created_date(base::Time::FromInternalValue( 398 file.details().creation_time())); 399 file_resource->set_modified_date(base::Time::FromInternalValue( 400 file.details().modification_time())); 401 402 return file_resource.Pass(); 403 } 404 405 scoped_ptr<google_apis::ChangeResource> CreateChangeResourceFromMetadata( 406 const FileMetadata& file) { 407 scoped_ptr<google_apis::ChangeResource> change( 408 new google_apis::ChangeResource); 409 change->set_change_id(file.details().change_id()); 410 change->set_file_id(file.file_id()); 411 change->set_deleted(file.details().missing()); 412 if (change->is_deleted()) 413 return change.Pass(); 414 415 change->set_file(CreateFileResourceFromMetadata(file)); 416 return change.Pass(); 417 } 418 419 void ApplyRenameChangeToMetadata(const std::string& new_title, 420 FileMetadata* file) { 421 FileDetails* details = file->mutable_details(); 422 details->set_title(new_title); 423 details->set_change_id(++current_change_id_); 424 } 425 426 void ApplyReorganizeChangeToMetadata(const std::string& new_parent, 427 FileMetadata* file) { 428 FileDetails* details = file->mutable_details(); 429 details->clear_parent_folder_ids(); 430 details->add_parent_folder_ids(new_parent); 431 details->set_change_id(++current_change_id_); 432 } 433 434 void ApplyContentChangeToMetadata(FileMetadata* file) { 435 FileDetails* details = file->mutable_details(); 436 details->set_md5( 437 "md5_value_" + base::Int64ToString(next_md5_sequence_number_++)); 438 details->set_change_id(++current_change_id_); 439 } 440 441 void ApplyNoopChangeToMetadata(FileMetadata* file) { 442 file->mutable_details()->set_change_id(++current_change_id_); 443 } 444 445 void PushToChangeList(scoped_ptr<google_apis::ChangeResource> change, 446 ScopedVector<google_apis::ChangeResource>* changes) { 447 changes->push_back(change.release()); 448 } 449 450 leveldb::Status PutFileToDB(leveldb::DB* db, const FileMetadata& file) { 451 leveldb::WriteBatch batch; 452 PutFileMetadataToBatch(file, &batch); 453 return db->Write(leveldb::WriteOptions(), &batch); 454 } 455 456 leveldb::Status PutTrackerToDB(leveldb::DB* db, 457 const FileTracker& tracker) { 458 leveldb::WriteBatch batch; 459 PutFileTrackerToBatch(tracker, &batch); 460 return db->Write(leveldb::WriteOptions(), &batch); 461 } 462 463 void VerifyReloadConsistency() { 464 scoped_ptr<MetadataDatabase> metadata_database_2; 465 ASSERT_EQ(SYNC_STATUS_OK, 466 MetadataDatabase::CreateForTesting( 467 metadata_database_->db_.Pass(), 468 &metadata_database_2)); 469 metadata_database_->db_ = metadata_database_2->db_.Pass(); 470 471 const MetadataDatabaseIndex* on_memory = 472 static_cast<MetadataDatabaseIndex*>(metadata_database_->index_.get()); 473 const MetadataDatabaseIndex* reloaded = 474 static_cast<MetadataDatabaseIndex*>(metadata_database_2->index_.get()); 475 476 { 477 SCOPED_TRACE("Expect equivalent service_metadata"); 478 ExpectEquivalent(metadata_database_->service_metadata_.get(), 479 metadata_database_2->service_metadata_.get()); 480 } 481 482 { 483 SCOPED_TRACE("Expect equivalent metadata_by_id_ contents."); 484 ExpectEquivalent(on_memory->metadata_by_id_, 485 reloaded->metadata_by_id_); 486 } 487 488 { 489 SCOPED_TRACE("Expect equivalent tracker_by_id_ contents."); 490 ExpectEquivalent(on_memory->tracker_by_id_, 491 reloaded->tracker_by_id_); 492 } 493 494 { 495 SCOPED_TRACE("Expect equivalent trackers_by_file_id_ contents."); 496 ExpectEquivalent(on_memory->trackers_by_file_id_, 497 reloaded->trackers_by_file_id_); 498 } 499 500 { 501 SCOPED_TRACE("Expect equivalent app_root_by_app_id_ contents."); 502 ExpectEquivalent(on_memory->app_root_by_app_id_, 503 reloaded->app_root_by_app_id_); 504 } 505 506 { 507 SCOPED_TRACE("Expect equivalent trackers_by_parent_and_title_ contents."); 508 ExpectEquivalent(on_memory->trackers_by_parent_and_title_, 509 reloaded->trackers_by_parent_and_title_); 510 } 511 512 { 513 SCOPED_TRACE("Expect equivalent dirty_trackers_ contents."); 514 ExpectEquivalent(on_memory->dirty_trackers_, 515 reloaded->dirty_trackers_); 516 } 517 } 518 519 void VerifyFile(const FileMetadata& file) { 520 FileMetadata file_in_metadata_database; 521 ASSERT_TRUE(metadata_database()->FindFileByFileID( 522 file.file_id(), &file_in_metadata_database)); 523 524 SCOPED_TRACE("Expect equivalent " + file.file_id()); 525 ExpectEquivalent(&file, &file_in_metadata_database); 526 } 527 528 void VerifyTracker(const FileTracker& tracker) { 529 FileTracker tracker_in_metadata_database; 530 ASSERT_TRUE(metadata_database()->FindTrackerByTrackerID( 531 tracker.tracker_id(), &tracker_in_metadata_database)); 532 533 SCOPED_TRACE("Expect equivalent tracker[" + 534 base::Int64ToString(tracker.tracker_id()) + "]"); 535 ExpectEquivalent(&tracker, &tracker_in_metadata_database); 536 } 537 538 SyncStatusCode RegisterApp(const std::string& app_id, 539 const std::string& folder_id) { 540 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 541 metadata_database_->RegisterApp( 542 app_id, folder_id, 543 CreateResultReceiver(&status)); 544 message_loop_.RunUntilIdle(); 545 return status; 546 } 547 548 SyncStatusCode DisableApp(const std::string& app_id) { 549 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 550 metadata_database_->DisableApp( 551 app_id, CreateResultReceiver(&status)); 552 message_loop_.RunUntilIdle(); 553 return status; 554 } 555 556 SyncStatusCode EnableApp(const std::string& app_id) { 557 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 558 metadata_database_->EnableApp( 559 app_id, CreateResultReceiver(&status)); 560 message_loop_.RunUntilIdle(); 561 return status; 562 } 563 564 SyncStatusCode UnregisterApp(const std::string& app_id) { 565 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 566 metadata_database_->UnregisterApp( 567 app_id, CreateResultReceiver(&status)); 568 message_loop_.RunUntilIdle(); 569 return status; 570 } 571 572 SyncStatusCode UpdateByChangeList( 573 ScopedVector<google_apis::ChangeResource> changes) { 574 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 575 metadata_database_->UpdateByChangeList( 576 current_change_id_, 577 changes.Pass(), CreateResultReceiver(&status)); 578 message_loop_.RunUntilIdle(); 579 return status; 580 } 581 582 SyncStatusCode PopulateFolder(const std::string& folder_id, 583 const FileIDList& listed_children) { 584 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 585 metadata_database_->PopulateFolderByChildList( 586 folder_id, listed_children, 587 CreateResultReceiver(&status)); 588 message_loop_.RunUntilIdle(); 589 return status; 590 } 591 592 SyncStatusCode UpdateTracker(const FileTracker& tracker) { 593 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 594 metadata_database_->UpdateTracker( 595 tracker.tracker_id(), tracker.synced_details(), 596 CreateResultReceiver(&status)); 597 message_loop_.RunUntilIdle(); 598 return status; 599 } 600 601 SyncStatusCode PopulateInitialData( 602 int64 largest_change_id, 603 const google_apis::FileResource& sync_root_folder, 604 const ScopedVector<google_apis::FileResource>& app_root_folders) { 605 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 606 metadata_database_->PopulateInitialData( 607 largest_change_id, 608 sync_root_folder, 609 app_root_folders, 610 CreateResultReceiver(&status)); 611 message_loop_.RunUntilIdle(); 612 return status; 613 } 614 615 void ResetTrackerID(FileTracker* tracker) { 616 tracker->set_tracker_id(GetTrackerIDByFileID(tracker->file_id())); 617 } 618 619 int64 current_change_id() const { 620 return current_change_id_; 621 } 622 623 private: 624 base::ScopedTempDir database_dir_; 625 base::MessageLoop message_loop_; 626 627 scoped_ptr<leveldb::Env> in_memory_env_; 628 scoped_ptr<MetadataDatabase> metadata_database_; 629 630 int64 current_change_id_; 631 int64 next_tracker_id_; 632 int64 next_file_id_number_; 633 int64 next_md5_sequence_number_; 634 635 DISALLOW_COPY_AND_ASSIGN(MetadataDatabaseTest); 636 }; 637 638 TEST_F(MetadataDatabaseTest, InitializationTest_Empty) { 639 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 640 DropDatabase(); 641 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 642 } 643 644 TEST_F(MetadataDatabaseTest, InitializationTest_SimpleTree) { 645 TrackedFile sync_root(CreateTrackedSyncRoot()); 646 TrackedFile app_root(CreateTrackedFolder(sync_root, "app_id")); 647 app_root.tracker.set_app_id(app_root.metadata.details().title()); 648 app_root.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 649 650 TrackedFile file(CreateTrackedFile(app_root, "file")); 651 TrackedFile folder(CreateTrackedFolder(app_root, "folder")); 652 TrackedFile file_in_folder(CreateTrackedFile(folder, "file_in_folder")); 653 TrackedFile orphaned_file(CreateTrackedFile(sync_root, "orphaned_file")); 654 orphaned_file.metadata.mutable_details()->clear_parent_folder_ids(); 655 orphaned_file.tracker.set_parent_tracker_id(0); 656 657 const TrackedFile* tracked_files[] = { 658 &sync_root, &app_root, &file, &folder, &file_in_folder, &orphaned_file 659 }; 660 661 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 662 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 663 664 orphaned_file.should_be_absent = true; 665 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 666 } 667 668 TEST_F(MetadataDatabaseTest, AppManagementTest) { 669 TrackedFile sync_root(CreateTrackedSyncRoot()); 670 TrackedFile app_root(CreateTrackedFolder(sync_root, "app_id")); 671 app_root.tracker.set_app_id(app_root.metadata.details().title()); 672 app_root.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 673 674 TrackedFile file(CreateTrackedFile(app_root, "file")); 675 TrackedFile folder(CreateTrackedFolder(sync_root, "folder")); 676 folder.tracker.set_active(false); 677 678 const TrackedFile* tracked_files[] = { 679 &sync_root, &app_root, &file, &folder, 680 }; 681 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 682 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 683 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 684 685 folder.tracker.set_app_id("foo"); 686 EXPECT_EQ(SYNC_STATUS_OK, RegisterApp( 687 folder.tracker.app_id(), folder.metadata.file_id())); 688 folder.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 689 folder.tracker.set_active(true); 690 folder.tracker.set_dirty(true); 691 folder.tracker.set_needs_folder_listing(true); 692 VerifyTrackedFile(folder); 693 VerifyReloadConsistency(); 694 695 EXPECT_EQ(SYNC_STATUS_OK, DisableApp(folder.tracker.app_id())); 696 folder.tracker.set_tracker_kind(TRACKER_KIND_DISABLED_APP_ROOT); 697 VerifyTrackedFile(folder); 698 VerifyReloadConsistency(); 699 700 EXPECT_EQ(SYNC_STATUS_OK, EnableApp(folder.tracker.app_id())); 701 folder.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 702 VerifyTrackedFile(folder); 703 VerifyReloadConsistency(); 704 705 EXPECT_EQ(SYNC_STATUS_OK, UnregisterApp(folder.tracker.app_id())); 706 folder.tracker.set_app_id(std::string()); 707 folder.tracker.set_tracker_kind(TRACKER_KIND_REGULAR); 708 folder.tracker.set_active(false); 709 VerifyTrackedFile(folder); 710 VerifyReloadConsistency(); 711 712 EXPECT_EQ(SYNC_STATUS_OK, UnregisterApp(app_root.tracker.app_id())); 713 app_root.tracker.set_app_id(std::string()); 714 app_root.tracker.set_tracker_kind(TRACKER_KIND_REGULAR); 715 app_root.tracker.set_active(false); 716 app_root.tracker.set_dirty(true); 717 file.should_be_absent = true; 718 VerifyTrackedFile(app_root); 719 VerifyTrackedFile(file); 720 VerifyReloadConsistency(); 721 } 722 723 TEST_F(MetadataDatabaseTest, BuildPathTest) { 724 FileMetadata sync_root(CreateSyncRootMetadata()); 725 FileTracker sync_root_tracker(CreateSyncRootTracker(sync_root)); 726 727 FileMetadata app_root(CreateFolderMetadata(sync_root, "app_id")); 728 FileTracker app_root_tracker( 729 CreateTracker(sync_root_tracker, app_root)); 730 app_root_tracker.set_app_id(app_root.details().title()); 731 app_root_tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 732 733 FileMetadata folder(CreateFolderMetadata(app_root, "folder")); 734 FileTracker folder_tracker(CreateTracker(app_root_tracker, folder)); 735 736 FileMetadata file(CreateFileMetadata(folder, "file")); 737 FileTracker file_tracker(CreateTracker(folder_tracker, file)); 738 739 FileMetadata inactive_folder(CreateFolderMetadata(app_root, "folder")); 740 FileTracker inactive_folder_tracker(CreateTracker(app_root_tracker, 741 inactive_folder)); 742 inactive_folder_tracker.set_active(false); 743 744 { 745 scoped_ptr<leveldb::DB> db = InitializeLevelDB(); 746 ASSERT_TRUE(db); 747 748 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok()); 749 EXPECT_TRUE(PutTrackerToDB(db.get(), sync_root_tracker).ok()); 750 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok()); 751 EXPECT_TRUE(PutTrackerToDB(db.get(), app_root_tracker).ok()); 752 EXPECT_TRUE(PutFileToDB(db.get(), folder).ok()); 753 EXPECT_TRUE(PutTrackerToDB(db.get(), folder_tracker).ok()); 754 EXPECT_TRUE(PutFileToDB(db.get(), file).ok()); 755 EXPECT_TRUE(PutTrackerToDB(db.get(), file_tracker).ok()); 756 } 757 758 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 759 760 base::FilePath path; 761 EXPECT_FALSE(metadata_database()->BuildPathForTracker( 762 sync_root_tracker.tracker_id(), &path)); 763 EXPECT_TRUE(metadata_database()->BuildPathForTracker( 764 app_root_tracker.tracker_id(), &path)); 765 EXPECT_EQ(base::FilePath(FPL("/")).NormalizePathSeparators(), path); 766 EXPECT_TRUE(metadata_database()->BuildPathForTracker( 767 file_tracker.tracker_id(), &path)); 768 EXPECT_EQ(base::FilePath(FPL("/folder/file")).NormalizePathSeparators(), 769 path); 770 } 771 772 TEST_F(MetadataDatabaseTest, FindNearestActiveAncestorTest) { 773 const std::string kAppID = "app_id"; 774 775 FileMetadata sync_root(CreateSyncRootMetadata()); 776 FileTracker sync_root_tracker(CreateSyncRootTracker(sync_root)); 777 778 FileMetadata app_root(CreateFolderMetadata(sync_root, kAppID)); 779 FileTracker app_root_tracker( 780 CreateTracker(sync_root_tracker, app_root)); 781 app_root_tracker.set_app_id(app_root.details().title()); 782 app_root_tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT); 783 784 // Create directory structure like this: "/folder1/folder2/file" 785 FileMetadata folder1(CreateFolderMetadata(app_root, "folder1")); 786 FileTracker folder_tracker1(CreateTracker(app_root_tracker, folder1)); 787 FileMetadata folder2(CreateFolderMetadata(folder1, "folder2")); 788 FileTracker folder_tracker2(CreateTracker(folder_tracker1, folder2)); 789 FileMetadata file(CreateFileMetadata(folder2, "file")); 790 FileTracker file_tracker(CreateTracker(folder_tracker2, file)); 791 792 FileMetadata inactive_folder(CreateFolderMetadata(app_root, "folder1")); 793 FileTracker inactive_folder_tracker(CreateTracker(app_root_tracker, 794 inactive_folder)); 795 inactive_folder_tracker.set_active(false); 796 797 { 798 scoped_ptr<leveldb::DB> db = InitializeLevelDB(); 799 ASSERT_TRUE(db); 800 801 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok()); 802 EXPECT_TRUE(PutTrackerToDB(db.get(), sync_root_tracker).ok()); 803 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok()); 804 EXPECT_TRUE(PutTrackerToDB(db.get(), app_root_tracker).ok()); 805 EXPECT_TRUE(PutFileToDB(db.get(), folder1).ok()); 806 EXPECT_TRUE(PutTrackerToDB(db.get(), folder_tracker1).ok()); 807 EXPECT_TRUE(PutFileToDB(db.get(), folder2).ok()); 808 EXPECT_TRUE(PutTrackerToDB(db.get(), folder_tracker2).ok()); 809 EXPECT_TRUE(PutFileToDB(db.get(), file).ok()); 810 EXPECT_TRUE(PutTrackerToDB(db.get(), file_tracker).ok()); 811 EXPECT_TRUE(PutFileToDB(db.get(), inactive_folder).ok()); 812 EXPECT_TRUE(PutTrackerToDB(db.get(), inactive_folder_tracker).ok()); 813 } 814 815 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 816 817 { 818 base::FilePath path; 819 FileTracker tracker; 820 EXPECT_FALSE(metadata_database()->FindNearestActiveAncestor( 821 "non_registered_app_id", 822 CreateNormalizedPath(FPL("folder1/folder2/file")), 823 &tracker, &path)); 824 } 825 826 { 827 base::FilePath path; 828 FileTracker tracker; 829 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor( 830 kAppID, CreateNormalizedPath(FPL("")), &tracker, &path)); 831 EXPECT_EQ(app_root_tracker.tracker_id(), tracker.tracker_id()); 832 EXPECT_EQ(CreateNormalizedPath(FPL("")), path); 833 } 834 835 { 836 base::FilePath path; 837 FileTracker tracker; 838 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor( 839 kAppID, CreateNormalizedPath(FPL("folder1/folder2")), 840 &tracker, &path)); 841 EXPECT_EQ(folder_tracker2.tracker_id(), tracker.tracker_id()); 842 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2")), path); 843 } 844 845 { 846 base::FilePath path; 847 FileTracker tracker; 848 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor( 849 kAppID, CreateNormalizedPath(FPL("folder1/folder2/file")), 850 &tracker, &path)); 851 EXPECT_EQ(file_tracker.tracker_id(), tracker.tracker_id()); 852 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2/file")), path); 853 } 854 855 { 856 base::FilePath path; 857 FileTracker tracker; 858 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor( 859 kAppID, 860 CreateNormalizedPath(FPL("folder1/folder2/folder3/folder4/file")), 861 &tracker, &path)); 862 EXPECT_EQ(folder_tracker2.tracker_id(), tracker.tracker_id()); 863 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2")), path); 864 } 865 866 { 867 base::FilePath path; 868 FileTracker tracker; 869 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor( 870 kAppID, CreateNormalizedPath(FPL("folder1/folder2/file/folder4/file")), 871 &tracker, &path)); 872 EXPECT_EQ(folder_tracker2.tracker_id(), tracker.tracker_id()); 873 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2")), path); 874 } 875 } 876 877 TEST_F(MetadataDatabaseTest, UpdateByChangeListTest) { 878 TrackedFile sync_root(CreateTrackedSyncRoot()); 879 TrackedFile app_root(CreateTrackedFolder(sync_root, "app_id")); 880 TrackedFile disabled_app_root(CreateTrackedFolder(sync_root, "disabled_app")); 881 TrackedFile file(CreateTrackedFile(app_root, "file")); 882 TrackedFile renamed_file(CreateTrackedFile(app_root, "to be renamed")); 883 TrackedFile folder(CreateTrackedFolder(app_root, "folder")); 884 TrackedFile reorganized_file( 885 CreateTrackedFile(app_root, "to be reorganized")); 886 TrackedFile updated_file( 887 CreateTrackedFile(app_root, "to be updated")); 888 TrackedFile noop_file(CreateTrackedFile(app_root, "has noop change")); 889 TrackedFile new_file(CreateTrackedFile(app_root, "to be added later")); 890 new_file.should_be_absent = true; 891 892 const TrackedFile* tracked_files[] = { 893 &sync_root, &app_root, &disabled_app_root, 894 &file, &renamed_file, &folder, &reorganized_file, &updated_file, &noop_file, 895 &new_file, 896 }; 897 898 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 899 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 900 901 ApplyRenameChangeToMetadata("renamed", &renamed_file.metadata); 902 ApplyReorganizeChangeToMetadata(folder.metadata.file_id(), 903 &reorganized_file.metadata); 904 ApplyContentChangeToMetadata(&updated_file.metadata); 905 906 // Update change ID. 907 ApplyNoopChangeToMetadata(&noop_file.metadata); 908 909 ScopedVector<google_apis::ChangeResource> changes; 910 PushToChangeList( 911 CreateChangeResourceFromMetadata(renamed_file.metadata), &changes); 912 PushToChangeList( 913 CreateChangeResourceFromMetadata(reorganized_file.metadata), &changes); 914 PushToChangeList( 915 CreateChangeResourceFromMetadata(updated_file.metadata), &changes); 916 PushToChangeList( 917 CreateChangeResourceFromMetadata(noop_file.metadata), &changes); 918 PushToChangeList( 919 CreateChangeResourceFromMetadata(new_file.metadata), &changes); 920 EXPECT_EQ(SYNC_STATUS_OK, UpdateByChangeList(changes.Pass())); 921 922 renamed_file.tracker.set_dirty(true); 923 reorganized_file.tracker.set_dirty(true); 924 updated_file.tracker.set_dirty(true); 925 noop_file.tracker.set_dirty(true); 926 new_file.tracker.mutable_synced_details()->set_missing(true); 927 new_file.tracker.mutable_synced_details()->clear_md5(); 928 new_file.tracker.set_active(false); 929 new_file.tracker.set_dirty(true); 930 ResetTrackerID(&new_file.tracker); 931 EXPECT_NE(0, new_file.tracker.tracker_id()); 932 933 new_file.should_be_absent = false; 934 935 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 936 VerifyReloadConsistency(); 937 } 938 939 TEST_F(MetadataDatabaseTest, PopulateFolderTest_RegularFolder) { 940 TrackedFile sync_root(CreateTrackedSyncRoot()); 941 TrackedFile app_root(CreateTrackedAppRoot(sync_root, "app_id")); 942 app_root.tracker.set_app_id(app_root.metadata.details().title()); 943 944 TrackedFile folder_to_populate( 945 CreateTrackedFolder(app_root, "folder_to_populate")); 946 folder_to_populate.tracker.set_needs_folder_listing(true); 947 folder_to_populate.tracker.set_dirty(true); 948 949 TrackedFile known_file(CreateTrackedFile(folder_to_populate, "known_file")); 950 TrackedFile new_file(CreateTrackedFile(folder_to_populate, "new_file")); 951 new_file.should_be_absent = true; 952 953 const TrackedFile* tracked_files[] = { 954 &sync_root, &app_root, &folder_to_populate, &known_file, &new_file 955 }; 956 957 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 958 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 959 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 960 961 FileIDList listed_children; 962 listed_children.push_back(known_file.metadata.file_id()); 963 listed_children.push_back(new_file.metadata.file_id()); 964 965 EXPECT_EQ(SYNC_STATUS_OK, 966 PopulateFolder(folder_to_populate.metadata.file_id(), 967 listed_children)); 968 969 folder_to_populate.tracker.set_dirty(false); 970 folder_to_populate.tracker.set_needs_folder_listing(false); 971 ResetTrackerID(&new_file.tracker); 972 new_file.tracker.set_dirty(true); 973 new_file.tracker.set_active(false); 974 new_file.tracker.clear_synced_details(); 975 new_file.should_be_absent = false; 976 new_file.tracker_only = true; 977 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 978 VerifyReloadConsistency(); 979 } 980 981 TEST_F(MetadataDatabaseTest, PopulateFolderTest_InactiveFolder) { 982 TrackedFile sync_root(CreateTrackedSyncRoot()); 983 TrackedFile app_root(CreateTrackedAppRoot(sync_root, "app_id")); 984 985 TrackedFile inactive_folder(CreateTrackedFolder(app_root, "inactive_folder")); 986 inactive_folder.tracker.set_active(false); 987 inactive_folder.tracker.set_dirty(true); 988 989 TrackedFile new_file( 990 CreateTrackedFile(inactive_folder, "file_in_inactive_folder")); 991 new_file.should_be_absent = true; 992 993 const TrackedFile* tracked_files[] = { 994 &sync_root, &app_root, &inactive_folder, &new_file, 995 }; 996 997 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 998 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 999 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1000 1001 FileIDList listed_children; 1002 listed_children.push_back(new_file.metadata.file_id()); 1003 1004 EXPECT_EQ(SYNC_STATUS_OK, 1005 PopulateFolder(inactive_folder.metadata.file_id(), 1006 listed_children)); 1007 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1008 VerifyReloadConsistency(); 1009 } 1010 1011 TEST_F(MetadataDatabaseTest, PopulateFolderTest_DisabledAppRoot) { 1012 TrackedFile sync_root(CreateTrackedSyncRoot()); 1013 TrackedFile disabled_app_root( 1014 CreateTrackedAppRoot(sync_root, "disabled_app")); 1015 disabled_app_root.tracker.set_dirty(true); 1016 disabled_app_root.tracker.set_needs_folder_listing(true); 1017 1018 TrackedFile known_file(CreateTrackedFile(disabled_app_root, "known_file")); 1019 TrackedFile file(CreateTrackedFile(disabled_app_root, "file")); 1020 file.should_be_absent = true; 1021 1022 const TrackedFile* tracked_files[] = { 1023 &sync_root, &disabled_app_root, &disabled_app_root, &known_file, &file, 1024 }; 1025 1026 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 1027 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 1028 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1029 1030 FileIDList disabled_app_children; 1031 disabled_app_children.push_back(file.metadata.file_id()); 1032 EXPECT_EQ(SYNC_STATUS_OK, PopulateFolder( 1033 disabled_app_root.metadata.file_id(), disabled_app_children)); 1034 ResetTrackerID(&file.tracker); 1035 file.tracker.clear_synced_details(); 1036 file.tracker.set_dirty(true); 1037 file.tracker.set_active(false); 1038 file.should_be_absent = false; 1039 file.tracker_only = true; 1040 1041 disabled_app_root.tracker.set_dirty(false); 1042 disabled_app_root.tracker.set_needs_folder_listing(false); 1043 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1044 VerifyReloadConsistency(); 1045 } 1046 1047 // TODO(tzik): Fix expectation and re-enable this test. 1048 TEST_F(MetadataDatabaseTest, DISABLED_UpdateTrackerTest) { 1049 TrackedFile sync_root(CreateTrackedSyncRoot()); 1050 TrackedFile app_root(CreateTrackedAppRoot(sync_root, "app_root")); 1051 TrackedFile file(CreateTrackedFile(app_root, "file")); 1052 file.tracker.set_dirty(true); 1053 file.metadata.mutable_details()->set_title("renamed file"); 1054 1055 TrackedFile inactive_file(CreateTrackedFile(app_root, "inactive_file")); 1056 inactive_file.tracker.set_active(false); 1057 inactive_file.tracker.set_dirty(true); 1058 inactive_file.metadata.mutable_details()->set_title("renamed inactive file"); 1059 inactive_file.metadata.mutable_details()->set_md5("modified_md5"); 1060 1061 TrackedFile new_conflict(CreateTrackedFile(app_root, "new conflict file")); 1062 new_conflict.tracker.set_dirty(true); 1063 new_conflict.metadata.mutable_details()->set_title("renamed file"); 1064 1065 const TrackedFile* tracked_files[] = { 1066 &sync_root, &app_root, &file, &inactive_file, &new_conflict 1067 }; 1068 1069 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 1070 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 1071 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1072 VerifyReloadConsistency(); 1073 1074 *file.tracker.mutable_synced_details() = file.metadata.details(); 1075 file.tracker.set_dirty(false); 1076 EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(file.tracker)); 1077 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1078 VerifyReloadConsistency(); 1079 1080 *inactive_file.tracker.mutable_synced_details() = 1081 inactive_file.metadata.details(); 1082 inactive_file.tracker.set_dirty(false); 1083 inactive_file.tracker.set_active(true); 1084 EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(inactive_file.tracker)); 1085 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1086 VerifyReloadConsistency(); 1087 1088 *new_conflict.tracker.mutable_synced_details() = 1089 new_conflict.metadata.details(); 1090 new_conflict.tracker.set_dirty(false); 1091 new_conflict.tracker.set_active(true); 1092 file.tracker.set_dirty(true); 1093 file.tracker.set_active(false); 1094 EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(new_conflict.tracker)); 1095 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1096 VerifyReloadConsistency(); 1097 } 1098 1099 TEST_F(MetadataDatabaseTest, PopulateInitialDataTest) { 1100 TrackedFile sync_root(CreateTrackedSyncRoot()); 1101 TrackedFile app_root(CreateTrackedFolder(sync_root, "app_root")); 1102 app_root.tracker.set_active(false); 1103 1104 const TrackedFile* tracked_files[] = { 1105 &sync_root, &app_root 1106 }; 1107 1108 scoped_ptr<google_apis::FileResource> sync_root_folder( 1109 CreateFileResourceFromMetadata(sync_root.metadata)); 1110 scoped_ptr<google_apis::FileResource> app_root_folder( 1111 CreateFileResourceFromMetadata(app_root.metadata)); 1112 1113 ScopedVector<google_apis::FileResource> app_root_folders; 1114 app_root_folders.push_back(app_root_folder.release()); 1115 1116 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 1117 EXPECT_EQ(SYNC_STATUS_OK, PopulateInitialData( 1118 current_change_id(), 1119 *sync_root_folder, 1120 app_root_folders)); 1121 1122 ResetTrackerID(&sync_root.tracker); 1123 ResetTrackerID(&app_root.tracker); 1124 app_root.tracker.set_parent_tracker_id(sync_root.tracker.tracker_id()); 1125 1126 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1127 VerifyReloadConsistency(); 1128 } 1129 1130 TEST_F(MetadataDatabaseTest, DumpFiles) { 1131 TrackedFile sync_root(CreateTrackedSyncRoot()); 1132 TrackedFile app_root(CreateTrackedAppRoot(sync_root, "app_id")); 1133 app_root.tracker.set_app_id(app_root.metadata.details().title()); 1134 1135 TrackedFile folder_0(CreateTrackedFolder(app_root, "folder_0")); 1136 TrackedFile file_0(CreateTrackedFile(folder_0, "file_0")); 1137 1138 const TrackedFile* tracked_files[] = { 1139 &sync_root, &app_root, &folder_0, &file_0 1140 }; 1141 1142 SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files)); 1143 EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase()); 1144 VerifyTrackedFiles(tracked_files, arraysize(tracked_files)); 1145 1146 scoped_ptr<base::ListValue> files = 1147 metadata_database()->DumpFiles(app_root.tracker.app_id()); 1148 ASSERT_EQ(2u, files->GetSize()); 1149 1150 base::DictionaryValue* file = NULL; 1151 std::string str; 1152 1153 ASSERT_TRUE(files->GetDictionary(0, &file)); 1154 EXPECT_TRUE(file->GetString("title", &str) && str == "folder_0"); 1155 EXPECT_TRUE(file->GetString("type", &str) && str == "folder"); 1156 EXPECT_TRUE(file->HasKey("details")); 1157 1158 ASSERT_TRUE(files->GetDictionary(1, &file)); 1159 EXPECT_TRUE(file->GetString("title", &str) && str == "file_0"); 1160 EXPECT_TRUE(file->GetString("type", &str) && str == "file"); 1161 EXPECT_TRUE(file->HasKey("details")); 1162 } 1163 1164 } // namespace drive_backend 1165 } // namespace sync_file_system 1166