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