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