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