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