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.
5 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
13 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
14 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
15 #include "chrome/browser/sync_file_system/drive_backend/leveldb_wrapper.h"
16 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
17 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index.h"
18 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_interface.h"
19 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.h"
20 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
21 #include "google_apis/drive/drive_api_parser.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
24 #include "third_party/leveldatabase/src/include/leveldb/db.h"
25 #include "third_party/leveldatabase/src/include/leveldb/env.h"
26 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
28 #define FPL(a) FILE_PATH_LITERAL(a)
30 namespace sync_file_system
{
31 namespace drive_backend
{
35 typedef MetadataDatabase::FileIDList FileIDList
;
37 const int64 kInitialChangeID
= 1234;
38 const int64 kSyncRootTrackerID
= 100;
39 const char kSyncRootFolderID
[] = "sync_root_folder_id";
41 // This struct is used to setup initial state of the database in the test and
42 // also used to match to the modified content of the database as the
45 // Holds the latest remote metadata which may be not-yet-synced to |tracker|.
46 FileMetadata metadata
;
49 // Implies the file should not in the database.
50 bool should_be_absent
;
52 // Implies the file should have a tracker in the database but should have no
56 TrackedFile() : should_be_absent(false), tracker_only(false) {}
59 void ExpectEquivalentServiceMetadata(
60 const MetadataDatabaseIndexInterface
* left
,
61 const MetadataDatabaseIndexInterface
* right
) {
62 EXPECT_EQ(left
->GetLargestChangeID(), right
->GetLargestChangeID());
63 EXPECT_EQ(left
->GetSyncRootTrackerID(), right
->GetSyncRootTrackerID());
64 EXPECT_EQ(left
->GetNextTrackerID(), right
->GetNextTrackerID());
67 void ExpectEquivalent(const FileMetadata
* left
, const FileMetadata
* right
) {
73 test_util::ExpectEquivalentMetadata(*left
, *right
);
76 void ExpectEquivalent(const FileTracker
* left
, const FileTracker
* right
) {
82 test_util::ExpectEquivalentTrackers(*left
, *right
);
85 void ExpectEquivalent(int64 left
, int64 right
) {
86 EXPECT_EQ(left
, right
);
89 template <typename Container
>
90 void ExpectEquivalentMaps(const Container
& left
, const Container
& right
);
92 template <typename Key
, typename Value
>
93 void ExpectEquivalent(const std::map
<Key
, Value
>& left
,
94 const std::map
<Key
, Value
>& right
) {
95 ExpectEquivalentMaps(left
, right
);
98 template <typename Key
, typename Value
>
99 void ExpectEquivalent(const base::hash_map
<Key
, Value
>& left
,
100 const base::hash_map
<Key
, Value
>& right
) {
101 ExpectEquivalentMaps(std::map
<Key
, Value
>(left
.begin(), left
.end()),
102 std::map
<Key
, Value
>(right
.begin(), right
.end()));
105 template <typename Key
, typename Value
>
106 void ExpectEquivalent(const base::ScopedPtrHashMap
<Key
, Value
>& left
,
107 const base::ScopedPtrHashMap
<Key
, Value
>& right
) {
108 ExpectEquivalentMaps(std::map
<Key
, Value
*>(left
.begin(), left
.end()),
109 std::map
<Key
, Value
*>(right
.begin(), right
.end()));
112 template <typename Container
>
113 void ExpectEquivalentSets(const Container
& left
, const Container
& right
);
115 template <typename Value
, typename Comparator
>
116 void ExpectEquivalent(const std::set
<Value
, Comparator
>& left
,
117 const std::set
<Value
, Comparator
>& right
) {
118 return ExpectEquivalentSets(left
, right
);
121 template <typename Value
>
122 void ExpectEquivalent(const base::hash_set
<Value
>& left
,
123 const base::hash_set
<Value
>& right
) {
124 return ExpectEquivalentSets(std::set
<Value
>(left
.begin(), left
.end()),
125 std::set
<Value
>(right
.begin(), right
.end()));
128 void ExpectEquivalent(const TrackerIDSet
& left
,
129 const TrackerIDSet
& right
) {
131 SCOPED_TRACE("Expect equivalent active_tracker");
132 EXPECT_EQ(left
.active_tracker(), right
.active_tracker());
134 ExpectEquivalent(left
.tracker_set(), right
.tracker_set());
137 template <typename Container
>
138 void ExpectEquivalentMaps(const Container
& left
, const Container
& right
) {
139 ASSERT_EQ(left
.size(), right
.size());
141 typedef typename
Container::const_iterator const_iterator
;
142 const_iterator left_itr
= left
.begin();
143 const_iterator right_itr
= right
.begin();
144 while (left_itr
!= left
.end()) {
145 EXPECT_EQ(left_itr
->first
, right_itr
->first
);
146 ExpectEquivalent(left_itr
->second
, right_itr
->second
);
152 template <typename Container
>
153 void ExpectEquivalentSets(const Container
& left
, const Container
& right
) {
154 ASSERT_EQ(left
.size(), right
.size());
156 typedef typename
Container::const_iterator const_iterator
;
157 const_iterator left_itr
= left
.begin();
158 const_iterator right_itr
= right
.begin();
159 while (left_itr
!= left
.end()) {
160 ExpectEquivalent(*left_itr
, *right_itr
);
166 base::FilePath
CreateNormalizedPath(const base::FilePath::StringType
& path
) {
167 return base::FilePath(path
).NormalizePathSeparators();
172 class MetadataDatabaseTest
: public testing::TestWithParam
<bool> {
174 MetadataDatabaseTest()
175 : current_change_id_(kInitialChangeID
),
176 next_tracker_id_(kSyncRootTrackerID
+ 1),
177 next_file_id_number_(1),
178 next_md5_sequence_number_(1) {}
180 virtual ~MetadataDatabaseTest() {}
182 void SetUp() override
{
183 ASSERT_TRUE(database_dir_
.CreateUniqueTempDir());
184 in_memory_env_
.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
187 void TearDown() override
{ DropDatabase(); }
190 std::string
GenerateFileID() {
191 return "file_id_" + base::Int64ToString(next_file_id_number_
++);
194 int64
GetTrackerIDByFileID(const std::string
& file_id
) {
195 TrackerIDSet trackers
;
196 if (metadata_database_
->FindTrackersByFileID(file_id
, &trackers
)) {
197 EXPECT_FALSE(trackers
.empty());
198 return *trackers
.begin();
203 SyncStatusCode
InitializeMetadataDatabase() {
204 SyncStatusCode status
= SYNC_STATUS_UNKNOWN
;
205 metadata_database_
= MetadataDatabase::CreateInternal(
206 database_dir_
.path(), in_memory_env_
.get(),
207 GetParam(), &status
);
211 void DropDatabase() {
212 metadata_database_
.reset();
213 message_loop_
.RunUntilIdle();
216 void SetUpDatabaseByTrackedFiles(const TrackedFile
** tracked_files
,
218 scoped_ptr
<LevelDBWrapper
> db
= InitializeLevelDB();
221 for (int i
= 0; i
< size
; ++i
) {
222 const TrackedFile
* file
= tracked_files
[i
];
223 if (file
->should_be_absent
)
225 if (!file
->tracker_only
)
226 EXPECT_TRUE(PutFileToDB(db
.get(), file
->metadata
).ok());
227 EXPECT_TRUE(PutTrackerToDB(db
.get(), file
->tracker
).ok());
231 void VerifyTrackedFile(const TrackedFile
& file
) {
232 if (!file
.should_be_absent
) {
233 if (file
.tracker_only
) {
234 EXPECT_FALSE(metadata_database()->FindFileByFileID(
235 file
.metadata
.file_id(), nullptr));
237 VerifyFile(file
.metadata
);
239 VerifyTracker(file
.tracker
);
243 EXPECT_FALSE(metadata_database()->FindFileByFileID(
244 file
.metadata
.file_id(), nullptr));
245 EXPECT_FALSE(metadata_database()->FindTrackerByTrackerID(
246 file
.tracker
.tracker_id(), nullptr));
249 void VerifyTrackedFiles(const TrackedFile
** tracked_files
, int size
) {
250 for (int i
= 0; i
< size
; ++i
)
251 VerifyTrackedFile(*tracked_files
[i
]);
254 MetadataDatabase
* metadata_database() { return metadata_database_
.get(); }
256 scoped_ptr
<LevelDBWrapper
> InitializeLevelDB() {
257 leveldb::DB
* db
= nullptr;
258 leveldb::Options options
;
259 options
.create_if_missing
= true;
260 options
.max_open_files
= 0; // Use minimum.
261 options
.env
= in_memory_env_
.get();
262 leveldb::Status status
=
263 leveldb::DB::Open(options
, database_dir_
.path().AsUTF8Unsafe(), &db
);
264 EXPECT_TRUE(status
.ok());
266 scoped_ptr
<LevelDBWrapper
> wrapper(new LevelDBWrapper(make_scoped_ptr(db
)));
268 wrapper
->Put(kDatabaseVersionKey
, base::Int64ToString(3));
269 SetUpServiceMetadata(wrapper
.get());
271 return wrapper
.Pass();
274 void SetUpServiceMetadata(LevelDBWrapper
* db
) {
275 ServiceMetadata service_metadata
;
276 service_metadata
.set_largest_change_id(kInitialChangeID
);
277 service_metadata
.set_sync_root_tracker_id(kSyncRootTrackerID
);
278 service_metadata
.set_next_tracker_id(next_tracker_id_
);
279 PutServiceMetadataToDB(service_metadata
, db
);
280 EXPECT_TRUE(db
->Commit().ok());
283 FileMetadata
CreateSyncRootMetadata() {
284 FileMetadata sync_root
;
285 sync_root
.set_file_id(kSyncRootFolderID
);
286 FileDetails
* details
= sync_root
.mutable_details();
287 details
->set_title(kSyncRootFolderTitle
);
288 details
->set_file_kind(FILE_KIND_FOLDER
);
289 details
->set_change_id(current_change_id_
);
293 FileMetadata
CreateFileMetadata(const FileMetadata
& parent
,
294 const std::string
& title
) {
296 file
.set_file_id(GenerateFileID());
297 FileDetails
* details
= file
.mutable_details();
298 details
->add_parent_folder_ids(parent
.file_id());
299 details
->set_title(title
);
300 details
->set_file_kind(FILE_KIND_FILE
);
302 "md5_value_" + base::Int64ToString(next_md5_sequence_number_
++));
303 details
->set_change_id(current_change_id_
);
307 FileMetadata
CreateFolderMetadata(const FileMetadata
& parent
,
308 const std::string
& title
) {
310 folder
.set_file_id(GenerateFileID());
311 FileDetails
* details
= folder
.mutable_details();
312 details
->add_parent_folder_ids(parent
.file_id());
313 details
->set_title(title
);
314 details
->set_file_kind(FILE_KIND_FOLDER
);
315 details
->set_change_id(current_change_id_
);
319 FileTracker
CreateSyncRootTracker(const FileMetadata
& sync_root
) {
320 FileTracker sync_root_tracker
;
321 sync_root_tracker
.set_tracker_id(kSyncRootTrackerID
);
322 sync_root_tracker
.set_parent_tracker_id(0);
323 sync_root_tracker
.set_file_id(sync_root
.file_id());
324 sync_root_tracker
.set_dirty(false);
325 sync_root_tracker
.set_active(true);
326 sync_root_tracker
.set_needs_folder_listing(false);
327 *sync_root_tracker
.mutable_synced_details() = sync_root
.details();
328 return sync_root_tracker
;
331 FileTracker
CreateTracker(const FileTracker
& parent_tracker
,
332 const FileMetadata
& file
) {
334 tracker
.set_tracker_id(next_tracker_id_
++);
335 tracker
.set_parent_tracker_id(parent_tracker
.tracker_id());
336 tracker
.set_file_id(file
.file_id());
337 tracker
.set_app_id(parent_tracker
.app_id());
338 tracker
.set_tracker_kind(TRACKER_KIND_REGULAR
);
339 tracker
.set_dirty(false);
340 tracker
.set_active(true);
341 tracker
.set_needs_folder_listing(false);
342 *tracker
.mutable_synced_details() = file
.details();
346 TrackedFile
CreateTrackedSyncRoot() {
347 TrackedFile sync_root
;
348 sync_root
.metadata
= CreateSyncRootMetadata();
349 sync_root
.tracker
= CreateSyncRootTracker(sync_root
.metadata
);
353 TrackedFile
CreateTrackedAppRoot(const TrackedFile
& sync_root
,
354 const std::string
& app_id
) {
355 TrackedFile
app_root(CreateTrackedFolder(sync_root
, app_id
));
356 app_root
.tracker
.set_app_id(app_id
);
357 app_root
.tracker
.set_tracker_kind(TRACKER_KIND_APP_ROOT
);
361 TrackedFile
CreateTrackedFile(const TrackedFile
& parent
,
362 const std::string
& title
) {
364 file
.metadata
= CreateFileMetadata(parent
.metadata
, title
);
365 file
.tracker
= CreateTracker(parent
.tracker
, file
.metadata
);
369 TrackedFile
CreateTrackedFolder(const TrackedFile
& parent
,
370 const std::string
& title
) {
372 folder
.metadata
= CreateFolderMetadata(parent
.metadata
, title
);
373 folder
.tracker
= CreateTracker(parent
.tracker
, folder
.metadata
);
377 scoped_ptr
<google_apis::FileResource
> CreateFileResourceFromMetadata(
378 const FileMetadata
& file
) {
379 scoped_ptr
<google_apis::FileResource
> file_resource(
380 new google_apis::FileResource
);
381 for (int i
= 0; i
< file
.details().parent_folder_ids_size(); ++i
) {
382 google_apis::ParentReference parent
;
383 parent
.set_file_id(file
.details().parent_folder_ids(i
));
384 file_resource
->mutable_parents()->push_back(parent
);
387 file_resource
->set_file_id(file
.file_id());
388 file_resource
->set_title(file
.details().title());
389 if (file
.details().file_kind() == FILE_KIND_FOLDER
) {
390 file_resource
->set_mime_type("application/vnd.google-apps.folder");
391 } else if (file
.details().file_kind() == FILE_KIND_FILE
) {
392 file_resource
->set_mime_type("text/plain");
393 file_resource
->set_file_size(0);
395 file_resource
->set_mime_type("application/vnd.google-apps.document");
397 file_resource
->set_md5_checksum(file
.details().md5());
398 file_resource
->set_etag(file
.details().etag());
399 file_resource
->set_created_date(base::Time::FromInternalValue(
400 file
.details().creation_time()));
401 file_resource
->set_modified_date(base::Time::FromInternalValue(
402 file
.details().modification_time()));
404 return file_resource
.Pass();
407 scoped_ptr
<google_apis::ChangeResource
> CreateChangeResourceFromMetadata(
408 const FileMetadata
& file
) {
409 scoped_ptr
<google_apis::ChangeResource
> change(
410 new google_apis::ChangeResource
);
411 change
->set_change_id(file
.details().change_id());
412 change
->set_file_id(file
.file_id());
413 change
->set_deleted(file
.details().missing());
414 if (change
->is_deleted())
415 return change
.Pass();
417 change
->set_file(CreateFileResourceFromMetadata(file
));
418 return change
.Pass();
421 void ApplyRenameChangeToMetadata(const std::string
& new_title
,
422 FileMetadata
* file
) {
423 FileDetails
* details
= file
->mutable_details();
424 details
->set_title(new_title
);
425 details
->set_change_id(++current_change_id_
);
428 void ApplyReorganizeChangeToMetadata(const std::string
& new_parent
,
429 FileMetadata
* file
) {
430 FileDetails
* details
= file
->mutable_details();
431 details
->clear_parent_folder_ids();
432 details
->add_parent_folder_ids(new_parent
);
433 details
->set_change_id(++current_change_id_
);
436 void ApplyContentChangeToMetadata(FileMetadata
* file
) {
437 FileDetails
* details
= file
->mutable_details();
439 "md5_value_" + base::Int64ToString(next_md5_sequence_number_
++));
440 details
->set_change_id(++current_change_id_
);
443 void ApplyNoopChangeToMetadata(FileMetadata
* file
) {
444 file
->mutable_details()->set_change_id(++current_change_id_
);
447 void PushToChangeList(scoped_ptr
<google_apis::ChangeResource
> change
,
448 ScopedVector
<google_apis::ChangeResource
>* changes
) {
449 changes
->push_back(change
.release());
452 leveldb::Status
PutFileToDB(LevelDBWrapper
* db
, const FileMetadata
& file
) {
453 PutFileMetadataToDB(file
, db
);
457 leveldb::Status
PutTrackerToDB(LevelDBWrapper
* db
,
458 const FileTracker
& tracker
) {
459 PutFileTrackerToDB(tracker
, db
);
463 void VerifyReloadConsistencyForOnMemory(MetadataDatabaseIndex
* index1
,
464 MetadataDatabaseIndex
* index2
) {
465 ExpectEquivalentServiceMetadata(index1
, index2
);
467 SCOPED_TRACE("Expect equivalent metadata_by_id_ contents.");
468 ExpectEquivalent(index1
->metadata_by_id_
, index2
->metadata_by_id_
);
471 SCOPED_TRACE("Expect equivalent tracker_by_id_ contents.");
472 ExpectEquivalent(index1
->tracker_by_id_
, index2
->tracker_by_id_
);
475 SCOPED_TRACE("Expect equivalent trackers_by_file_id_ contents.");
476 ExpectEquivalent(index1
->trackers_by_file_id_
,
477 index2
->trackers_by_file_id_
);
480 SCOPED_TRACE("Expect equivalent app_root_by_app_id_ contents.");
481 ExpectEquivalent(index1
->app_root_by_app_id_
,
482 index2
->app_root_by_app_id_
);
485 SCOPED_TRACE("Expect equivalent trackers_by_parent_and_title_ contents.");
486 ExpectEquivalent(index1
->trackers_by_parent_and_title_
,
487 index2
->trackers_by_parent_and_title_
);
490 SCOPED_TRACE("Expect equivalent dirty_trackers_ contents.");
491 ExpectEquivalent(index1
->dirty_trackers_
, index2
->dirty_trackers_
);
495 void VerifyReloadConsistencyForOnDisk(
496 MetadataDatabaseIndexOnDisk
* index1
,
497 MetadataDatabaseIndexOnDisk
* index2
) {
498 ExpectEquivalentServiceMetadata(index1
, index2
);
499 scoped_ptr
<LevelDBWrapper::Iterator
> itr1
=
500 index1
->GetDBForTesting()->NewIterator();
501 scoped_ptr
<LevelDBWrapper::Iterator
> itr2
=
502 index2
->GetDBForTesting()->NewIterator();
503 for (itr1
->SeekToFirst(), itr2
->SeekToFirst();
504 itr1
->Valid() && itr2
->Valid();
505 itr1
->Next(), itr2
->Next()) {
506 EXPECT_EQ(itr1
->key().ToString(), itr2
->key().ToString());
507 EXPECT_EQ(itr1
->value().ToString(), itr2
->value().ToString());
509 EXPECT_TRUE(!itr1
->Valid());
510 EXPECT_TRUE(!itr2
->Valid());
513 void VerifyReloadConsistency() {
514 scoped_ptr
<MetadataDatabase
> metadata_database_2
;
515 ASSERT_EQ(SYNC_STATUS_OK
,
516 MetadataDatabase::CreateForTesting(
517 metadata_database_
->db_
.Pass(),
518 metadata_database_
->enable_on_disk_index_
,
519 &metadata_database_2
));
520 metadata_database_
->db_
= metadata_database_2
->db_
.Pass();
522 MetadataDatabaseIndexInterface
* index1
= metadata_database_
->index_
.get();
523 MetadataDatabaseIndexInterface
* index2
= metadata_database_2
->index_
.get();
525 VerifyReloadConsistencyForOnDisk(
526 static_cast<MetadataDatabaseIndexOnDisk
*>(index1
),
527 static_cast<MetadataDatabaseIndexOnDisk
*>(index2
));
529 VerifyReloadConsistencyForOnMemory(
530 static_cast<MetadataDatabaseIndex
*>(index1
),
531 static_cast<MetadataDatabaseIndex
*>(index2
));
535 void VerifyFile(const FileMetadata
& file
) {
536 FileMetadata file_in_metadata_database
;
537 ASSERT_TRUE(metadata_database()->FindFileByFileID(
538 file
.file_id(), &file_in_metadata_database
));
540 SCOPED_TRACE("Expect equivalent " + file
.file_id());
541 ExpectEquivalent(&file
, &file_in_metadata_database
);
544 void VerifyTracker(const FileTracker
& tracker
) {
545 FileTracker tracker_in_metadata_database
;
546 ASSERT_TRUE(metadata_database()->FindTrackerByTrackerID(
547 tracker
.tracker_id(), &tracker_in_metadata_database
));
549 SCOPED_TRACE("Expect equivalent tracker[" +
550 base::Int64ToString(tracker
.tracker_id()) + "]");
551 ExpectEquivalent(&tracker
, &tracker_in_metadata_database
);
554 SyncStatusCode
RegisterApp(const std::string
& app_id
,
555 const std::string
& folder_id
) {
556 return metadata_database_
->RegisterApp(app_id
, folder_id
);
559 SyncStatusCode
DisableApp(const std::string
& app_id
) {
560 return metadata_database_
->DisableApp(app_id
);
563 SyncStatusCode
EnableApp(const std::string
& app_id
) {
564 return metadata_database_
->EnableApp(app_id
);
567 SyncStatusCode
UnregisterApp(const std::string
& app_id
) {
568 return metadata_database_
->UnregisterApp(app_id
);
571 SyncStatusCode
UpdateByChangeList(
572 ScopedVector
<google_apis::ChangeResource
> changes
) {
573 return metadata_database_
->UpdateByChangeList(
574 current_change_id_
, changes
.Pass());
577 SyncStatusCode
PopulateFolder(const std::string
& folder_id
,
578 const FileIDList
& listed_children
) {
579 return metadata_database_
->PopulateFolderByChildList(
580 folder_id
, listed_children
);
583 SyncStatusCode
UpdateTracker(const FileTracker
& tracker
) {
584 return metadata_database_
->UpdateTracker(
585 tracker
.tracker_id(), tracker
.synced_details());
588 SyncStatusCode
PopulateInitialData(
589 int64 largest_change_id
,
590 const google_apis::FileResource
& sync_root_folder
,
591 const ScopedVector
<google_apis::FileResource
>& app_root_folders
) {
592 return metadata_database_
->PopulateInitialData(
593 largest_change_id
, sync_root_folder
, app_root_folders
);
596 void ResetTrackerID(FileTracker
* tracker
) {
597 tracker
->set_tracker_id(GetTrackerIDByFileID(tracker
->file_id()));
600 int64
current_change_id() const {
601 return current_change_id_
;
605 base::ScopedTempDir database_dir_
;
606 base::MessageLoop message_loop_
;
608 scoped_ptr
<leveldb::Env
> in_memory_env_
;
609 scoped_ptr
<MetadataDatabase
> metadata_database_
;
611 int64 current_change_id_
;
612 int64 next_tracker_id_
;
613 int64 next_file_id_number_
;
614 int64 next_md5_sequence_number_
;
616 DISALLOW_COPY_AND_ASSIGN(MetadataDatabaseTest
);
619 INSTANTIATE_TEST_CASE_P(MetadataDatabaseTestWithIndexesOnDisk
,
620 MetadataDatabaseTest
,
621 ::testing::Values(true, false));
623 TEST_P(MetadataDatabaseTest
, InitializationTest_Empty
) {
624 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
626 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
630 scoped_ptr
<LevelDBWrapper
> db
= InitializeLevelDB();
631 db
->Put(kServiceMetadataKey
, "Unparsable string");
632 EXPECT_TRUE(db
->Commit().ok());
635 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
638 TEST_P(MetadataDatabaseTest
, InitializationTest_SimpleTree
) {
639 TrackedFile
sync_root(CreateTrackedSyncRoot());
640 TrackedFile
app_root(CreateTrackedFolder(sync_root
, "app_id"));
641 app_root
.tracker
.set_app_id(app_root
.metadata
.details().title());
642 app_root
.tracker
.set_tracker_kind(TRACKER_KIND_APP_ROOT
);
644 TrackedFile
file(CreateTrackedFile(app_root
, "file"));
645 TrackedFile
folder(CreateTrackedFolder(app_root
, "folder"));
646 TrackedFile
file_in_folder(CreateTrackedFile(folder
, "file_in_folder"));
647 TrackedFile
orphaned_file(CreateTrackedFile(sync_root
, "orphaned_file"));
648 orphaned_file
.metadata
.mutable_details()->clear_parent_folder_ids();
649 orphaned_file
.tracker
.set_parent_tracker_id(0);
651 const TrackedFile
* tracked_files
[] = {
652 &sync_root
, &app_root
, &file
, &folder
, &file_in_folder
, &orphaned_file
655 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
656 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
658 orphaned_file
.should_be_absent
= true;
659 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
662 TEST_P(MetadataDatabaseTest
, AppManagementTest
) {
663 TrackedFile
sync_root(CreateTrackedSyncRoot());
664 TrackedFile
app_root(CreateTrackedFolder(sync_root
, "app_id"));
665 app_root
.tracker
.set_app_id(app_root
.metadata
.details().title());
666 app_root
.tracker
.set_tracker_kind(TRACKER_KIND_APP_ROOT
);
668 TrackedFile
file(CreateTrackedFile(app_root
, "file"));
669 TrackedFile
folder(CreateTrackedFolder(sync_root
, "folder"));
670 folder
.tracker
.set_active(false);
672 const TrackedFile
* tracked_files
[] = {
673 &sync_root
, &app_root
, &file
, &folder
,
675 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
676 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
677 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
679 folder
.tracker
.set_app_id("foo");
680 EXPECT_EQ(SYNC_STATUS_OK
, RegisterApp(
681 folder
.tracker
.app_id(), folder
.metadata
.file_id()));
682 folder
.tracker
.set_tracker_kind(TRACKER_KIND_APP_ROOT
);
683 folder
.tracker
.set_active(true);
684 folder
.tracker
.set_dirty(true);
685 folder
.tracker
.set_needs_folder_listing(true);
686 VerifyTrackedFile(folder
);
687 VerifyReloadConsistency();
689 EXPECT_EQ(SYNC_STATUS_OK
, DisableApp(folder
.tracker
.app_id()));
690 folder
.tracker
.set_tracker_kind(TRACKER_KIND_DISABLED_APP_ROOT
);
691 VerifyTrackedFile(folder
);
692 VerifyReloadConsistency();
694 EXPECT_EQ(SYNC_STATUS_OK
, EnableApp(folder
.tracker
.app_id()));
695 folder
.tracker
.set_tracker_kind(TRACKER_KIND_APP_ROOT
);
696 VerifyTrackedFile(folder
);
697 VerifyReloadConsistency();
699 EXPECT_EQ(SYNC_STATUS_OK
, UnregisterApp(folder
.tracker
.app_id()));
700 folder
.tracker
.set_app_id(std::string());
701 folder
.tracker
.set_tracker_kind(TRACKER_KIND_REGULAR
);
702 folder
.tracker
.set_active(false);
703 VerifyTrackedFile(folder
);
704 VerifyReloadConsistency();
706 EXPECT_EQ(SYNC_STATUS_OK
, UnregisterApp(app_root
.tracker
.app_id()));
707 app_root
.tracker
.set_app_id(std::string());
708 app_root
.tracker
.set_tracker_kind(TRACKER_KIND_REGULAR
);
709 app_root
.tracker
.set_active(false);
710 app_root
.tracker
.set_dirty(true);
711 file
.should_be_absent
= true;
712 VerifyTrackedFile(app_root
);
713 VerifyTrackedFile(file
);
714 VerifyReloadConsistency();
717 TEST_P(MetadataDatabaseTest
, BuildPathTest
) {
718 FileMetadata
sync_root(CreateSyncRootMetadata());
719 FileTracker
sync_root_tracker(CreateSyncRootTracker(sync_root
));
721 FileMetadata
app_root(CreateFolderMetadata(sync_root
, "app_id"));
722 FileTracker
app_root_tracker(
723 CreateTracker(sync_root_tracker
, app_root
));
724 app_root_tracker
.set_app_id(app_root
.details().title());
725 app_root_tracker
.set_tracker_kind(TRACKER_KIND_APP_ROOT
);
727 FileMetadata
folder(CreateFolderMetadata(app_root
, "folder"));
728 FileTracker
folder_tracker(CreateTracker(app_root_tracker
, folder
));
730 FileMetadata
file(CreateFileMetadata(folder
, "file"));
731 FileTracker
file_tracker(CreateTracker(folder_tracker
, file
));
733 FileMetadata
inactive_folder(CreateFolderMetadata(app_root
, "folder"));
734 FileTracker
inactive_folder_tracker(CreateTracker(app_root_tracker
,
736 inactive_folder_tracker
.set_active(false);
739 scoped_ptr
<LevelDBWrapper
> db
= InitializeLevelDB();
742 EXPECT_TRUE(PutFileToDB(db
.get(), sync_root
).ok());
743 EXPECT_TRUE(PutTrackerToDB(db
.get(), sync_root_tracker
).ok());
744 EXPECT_TRUE(PutFileToDB(db
.get(), app_root
).ok());
745 EXPECT_TRUE(PutTrackerToDB(db
.get(), app_root_tracker
).ok());
746 EXPECT_TRUE(PutFileToDB(db
.get(), folder
).ok());
747 EXPECT_TRUE(PutTrackerToDB(db
.get(), folder_tracker
).ok());
748 EXPECT_TRUE(PutFileToDB(db
.get(), file
).ok());
749 EXPECT_TRUE(PutTrackerToDB(db
.get(), file_tracker
).ok());
752 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
755 EXPECT_FALSE(metadata_database()->BuildPathForTracker(
756 sync_root_tracker
.tracker_id(), &path
));
757 EXPECT_TRUE(metadata_database()->BuildPathForTracker(
758 app_root_tracker
.tracker_id(), &path
));
759 EXPECT_EQ(base::FilePath(FPL("/")).NormalizePathSeparators(), path
);
760 EXPECT_TRUE(metadata_database()->BuildPathForTracker(
761 file_tracker
.tracker_id(), &path
));
762 EXPECT_EQ(base::FilePath(FPL("/folder/file")).NormalizePathSeparators(),
766 TEST_P(MetadataDatabaseTest
, FindNearestActiveAncestorTest
) {
767 const std::string kAppID
= "app_id";
769 FileMetadata
sync_root(CreateSyncRootMetadata());
770 FileTracker
sync_root_tracker(CreateSyncRootTracker(sync_root
));
772 FileMetadata
app_root(CreateFolderMetadata(sync_root
, kAppID
));
773 FileTracker
app_root_tracker(
774 CreateTracker(sync_root_tracker
, app_root
));
775 app_root_tracker
.set_app_id(app_root
.details().title());
776 app_root_tracker
.set_tracker_kind(TRACKER_KIND_APP_ROOT
);
778 // Create directory structure like this: "/folder1/folder2/file"
779 FileMetadata
folder1(CreateFolderMetadata(app_root
, "folder1"));
780 FileTracker
folder_tracker1(CreateTracker(app_root_tracker
, folder1
));
781 FileMetadata
folder2(CreateFolderMetadata(folder1
, "folder2"));
782 FileTracker
folder_tracker2(CreateTracker(folder_tracker1
, folder2
));
783 FileMetadata
file(CreateFileMetadata(folder2
, "file"));
784 FileTracker
file_tracker(CreateTracker(folder_tracker2
, file
));
786 FileMetadata
inactive_folder(CreateFolderMetadata(app_root
, "folder1"));
787 FileTracker
inactive_folder_tracker(CreateTracker(app_root_tracker
,
789 inactive_folder_tracker
.set_active(false);
792 scoped_ptr
<LevelDBWrapper
> db
= InitializeLevelDB();
795 EXPECT_TRUE(PutFileToDB(db
.get(), sync_root
).ok());
796 EXPECT_TRUE(PutTrackerToDB(db
.get(), sync_root_tracker
).ok());
797 EXPECT_TRUE(PutFileToDB(db
.get(), app_root
).ok());
798 EXPECT_TRUE(PutTrackerToDB(db
.get(), app_root_tracker
).ok());
799 EXPECT_TRUE(PutFileToDB(db
.get(), folder1
).ok());
800 EXPECT_TRUE(PutTrackerToDB(db
.get(), folder_tracker1
).ok());
801 EXPECT_TRUE(PutFileToDB(db
.get(), folder2
).ok());
802 EXPECT_TRUE(PutTrackerToDB(db
.get(), folder_tracker2
).ok());
803 EXPECT_TRUE(PutFileToDB(db
.get(), file
).ok());
804 EXPECT_TRUE(PutTrackerToDB(db
.get(), file_tracker
).ok());
805 EXPECT_TRUE(PutFileToDB(db
.get(), inactive_folder
).ok());
806 EXPECT_TRUE(PutTrackerToDB(db
.get(), inactive_folder_tracker
).ok());
809 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
814 EXPECT_FALSE(metadata_database()->FindNearestActiveAncestor(
815 "non_registered_app_id",
816 CreateNormalizedPath(FPL("folder1/folder2/file")),
823 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor(
824 kAppID
, CreateNormalizedPath(FPL("")), &tracker
, &path
));
825 EXPECT_EQ(app_root_tracker
.tracker_id(), tracker
.tracker_id());
826 EXPECT_EQ(CreateNormalizedPath(FPL("")), path
);
832 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor(
833 kAppID
, CreateNormalizedPath(FPL("folder1/folder2")),
835 EXPECT_EQ(folder_tracker2
.tracker_id(), tracker
.tracker_id());
836 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2")), path
);
842 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor(
843 kAppID
, CreateNormalizedPath(FPL("folder1/folder2/file")),
845 EXPECT_EQ(file_tracker
.tracker_id(), tracker
.tracker_id());
846 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2/file")), path
);
852 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor(
854 CreateNormalizedPath(FPL("folder1/folder2/folder3/folder4/file")),
856 EXPECT_EQ(folder_tracker2
.tracker_id(), tracker
.tracker_id());
857 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2")), path
);
863 EXPECT_TRUE(metadata_database()->FindNearestActiveAncestor(
864 kAppID
, CreateNormalizedPath(FPL("folder1/folder2/file/folder4/file")),
866 EXPECT_EQ(folder_tracker2
.tracker_id(), tracker
.tracker_id());
867 EXPECT_EQ(CreateNormalizedPath(FPL("folder1/folder2")), path
);
871 TEST_P(MetadataDatabaseTest
, UpdateByChangeListTest
) {
872 TrackedFile
sync_root(CreateTrackedSyncRoot());
873 TrackedFile
app_root(CreateTrackedFolder(sync_root
, "app_id"));
874 TrackedFile
disabled_app_root(CreateTrackedFolder(sync_root
, "disabled_app"));
875 TrackedFile
file(CreateTrackedFile(app_root
, "file"));
876 TrackedFile
renamed_file(CreateTrackedFile(app_root
, "to be renamed"));
877 TrackedFile
folder(CreateTrackedFolder(app_root
, "folder"));
878 TrackedFile
reorganized_file(
879 CreateTrackedFile(app_root
, "to be reorganized"));
880 TrackedFile
updated_file(
881 CreateTrackedFile(app_root
, "to be updated"));
882 TrackedFile
noop_file(CreateTrackedFile(app_root
, "has noop change"));
883 TrackedFile
new_file(CreateTrackedFile(app_root
, "to be added later"));
884 new_file
.should_be_absent
= true;
886 const TrackedFile
* tracked_files
[] = {
887 &sync_root
, &app_root
, &disabled_app_root
,
888 &file
, &renamed_file
, &folder
, &reorganized_file
, &updated_file
, &noop_file
,
892 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
893 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
895 ApplyRenameChangeToMetadata("renamed", &renamed_file
.metadata
);
896 ApplyReorganizeChangeToMetadata(folder
.metadata
.file_id(),
897 &reorganized_file
.metadata
);
898 ApplyContentChangeToMetadata(&updated_file
.metadata
);
901 ApplyNoopChangeToMetadata(&noop_file
.metadata
);
903 ScopedVector
<google_apis::ChangeResource
> changes
;
905 CreateChangeResourceFromMetadata(renamed_file
.metadata
), &changes
);
907 CreateChangeResourceFromMetadata(reorganized_file
.metadata
), &changes
);
909 CreateChangeResourceFromMetadata(updated_file
.metadata
), &changes
);
911 CreateChangeResourceFromMetadata(noop_file
.metadata
), &changes
);
913 CreateChangeResourceFromMetadata(new_file
.metadata
), &changes
);
914 EXPECT_EQ(SYNC_STATUS_OK
, UpdateByChangeList(changes
.Pass()));
916 renamed_file
.tracker
.set_dirty(true);
917 reorganized_file
.tracker
.set_dirty(true);
918 updated_file
.tracker
.set_dirty(true);
919 noop_file
.tracker
.set_dirty(true);
920 new_file
.tracker
.mutable_synced_details()->set_missing(true);
921 new_file
.tracker
.mutable_synced_details()->clear_md5();
922 new_file
.tracker
.set_active(false);
923 new_file
.tracker
.set_dirty(true);
924 ResetTrackerID(&new_file
.tracker
);
925 EXPECT_NE(0, new_file
.tracker
.tracker_id());
927 new_file
.should_be_absent
= false;
929 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
930 VerifyReloadConsistency();
933 TEST_P(MetadataDatabaseTest
, PopulateFolderTest_RegularFolder
) {
934 TrackedFile
sync_root(CreateTrackedSyncRoot());
935 TrackedFile
app_root(CreateTrackedAppRoot(sync_root
, "app_id"));
936 app_root
.tracker
.set_app_id(app_root
.metadata
.details().title());
938 TrackedFile
folder_to_populate(
939 CreateTrackedFolder(app_root
, "folder_to_populate"));
940 folder_to_populate
.tracker
.set_needs_folder_listing(true);
941 folder_to_populate
.tracker
.set_dirty(true);
943 TrackedFile
known_file(CreateTrackedFile(folder_to_populate
, "known_file"));
944 TrackedFile
new_file(CreateTrackedFile(folder_to_populate
, "new_file"));
945 new_file
.should_be_absent
= true;
947 const TrackedFile
* tracked_files
[] = {
948 &sync_root
, &app_root
, &folder_to_populate
, &known_file
, &new_file
951 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
952 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
953 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
955 FileIDList listed_children
;
956 listed_children
.push_back(known_file
.metadata
.file_id());
957 listed_children
.push_back(new_file
.metadata
.file_id());
959 EXPECT_EQ(SYNC_STATUS_OK
,
960 PopulateFolder(folder_to_populate
.metadata
.file_id(),
963 folder_to_populate
.tracker
.set_dirty(false);
964 folder_to_populate
.tracker
.set_needs_folder_listing(false);
965 ResetTrackerID(&new_file
.tracker
);
966 new_file
.tracker
.set_dirty(true);
967 new_file
.tracker
.set_active(false);
968 new_file
.tracker
.clear_synced_details();
969 new_file
.should_be_absent
= false;
970 new_file
.tracker_only
= true;
971 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
972 VerifyReloadConsistency();
975 TEST_P(MetadataDatabaseTest
, PopulateFolderTest_InactiveFolder
) {
976 TrackedFile
sync_root(CreateTrackedSyncRoot());
977 TrackedFile
app_root(CreateTrackedAppRoot(sync_root
, "app_id"));
979 TrackedFile
inactive_folder(CreateTrackedFolder(app_root
, "inactive_folder"));
980 inactive_folder
.tracker
.set_active(false);
981 inactive_folder
.tracker
.set_dirty(true);
983 TrackedFile
new_file(
984 CreateTrackedFile(inactive_folder
, "file_in_inactive_folder"));
985 new_file
.should_be_absent
= true;
987 const TrackedFile
* tracked_files
[] = {
988 &sync_root
, &app_root
, &inactive_folder
, &new_file
,
991 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
992 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
993 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
995 FileIDList listed_children
;
996 listed_children
.push_back(new_file
.metadata
.file_id());
998 EXPECT_EQ(SYNC_STATUS_OK
,
999 PopulateFolder(inactive_folder
.metadata
.file_id(),
1001 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1002 VerifyReloadConsistency();
1005 TEST_P(MetadataDatabaseTest
, PopulateFolderTest_DisabledAppRoot
) {
1006 TrackedFile
sync_root(CreateTrackedSyncRoot());
1007 TrackedFile
disabled_app_root(
1008 CreateTrackedAppRoot(sync_root
, "disabled_app"));
1009 disabled_app_root
.tracker
.set_dirty(true);
1010 disabled_app_root
.tracker
.set_needs_folder_listing(true);
1012 TrackedFile
known_file(CreateTrackedFile(disabled_app_root
, "known_file"));
1013 TrackedFile
file(CreateTrackedFile(disabled_app_root
, "file"));
1014 file
.should_be_absent
= true;
1016 const TrackedFile
* tracked_files
[] = {
1017 &sync_root
, &disabled_app_root
, &disabled_app_root
, &known_file
, &file
,
1020 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
1021 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
1022 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1024 FileIDList disabled_app_children
;
1025 disabled_app_children
.push_back(file
.metadata
.file_id());
1026 EXPECT_EQ(SYNC_STATUS_OK
, PopulateFolder(
1027 disabled_app_root
.metadata
.file_id(), disabled_app_children
));
1028 ResetTrackerID(&file
.tracker
);
1029 file
.tracker
.clear_synced_details();
1030 file
.tracker
.set_dirty(true);
1031 file
.tracker
.set_active(false);
1032 file
.should_be_absent
= false;
1033 file
.tracker_only
= true;
1035 disabled_app_root
.tracker
.set_dirty(false);
1036 disabled_app_root
.tracker
.set_needs_folder_listing(false);
1037 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1038 VerifyReloadConsistency();
1041 // TODO(tzik): Fix expectation and re-enable this test.
1042 TEST_P(MetadataDatabaseTest
, DISABLED_UpdateTrackerTest
) {
1043 TrackedFile
sync_root(CreateTrackedSyncRoot());
1044 TrackedFile
app_root(CreateTrackedAppRoot(sync_root
, "app_root"));
1045 TrackedFile
file(CreateTrackedFile(app_root
, "file"));
1046 file
.tracker
.set_dirty(true);
1047 file
.metadata
.mutable_details()->set_title("renamed file");
1049 TrackedFile
inactive_file(CreateTrackedFile(app_root
, "inactive_file"));
1050 inactive_file
.tracker
.set_active(false);
1051 inactive_file
.tracker
.set_dirty(true);
1052 inactive_file
.metadata
.mutable_details()->set_title("renamed inactive file");
1053 inactive_file
.metadata
.mutable_details()->set_md5("modified_md5");
1055 TrackedFile
new_conflict(CreateTrackedFile(app_root
, "new conflict file"));
1056 new_conflict
.tracker
.set_dirty(true);
1057 new_conflict
.metadata
.mutable_details()->set_title("renamed file");
1059 const TrackedFile
* tracked_files
[] = {
1060 &sync_root
, &app_root
, &file
, &inactive_file
, &new_conflict
1063 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
1064 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
1065 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1066 VerifyReloadConsistency();
1068 *file
.tracker
.mutable_synced_details() = file
.metadata
.details();
1069 file
.tracker
.set_dirty(false);
1070 EXPECT_EQ(SYNC_STATUS_OK
, UpdateTracker(file
.tracker
));
1071 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1072 VerifyReloadConsistency();
1074 *inactive_file
.tracker
.mutable_synced_details() =
1075 inactive_file
.metadata
.details();
1076 inactive_file
.tracker
.set_dirty(false);
1077 inactive_file
.tracker
.set_active(true);
1078 EXPECT_EQ(SYNC_STATUS_OK
, UpdateTracker(inactive_file
.tracker
));
1079 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1080 VerifyReloadConsistency();
1082 *new_conflict
.tracker
.mutable_synced_details() =
1083 new_conflict
.metadata
.details();
1084 new_conflict
.tracker
.set_dirty(false);
1085 new_conflict
.tracker
.set_active(true);
1086 file
.tracker
.set_dirty(true);
1087 file
.tracker
.set_active(false);
1088 EXPECT_EQ(SYNC_STATUS_OK
, UpdateTracker(new_conflict
.tracker
));
1089 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1090 VerifyReloadConsistency();
1093 TEST_P(MetadataDatabaseTest
, PopulateInitialDataTest
) {
1094 TrackedFile
sync_root(CreateTrackedSyncRoot());
1095 TrackedFile
app_root(CreateTrackedFolder(sync_root
, "app_root"));
1096 app_root
.tracker
.set_active(false);
1098 const TrackedFile
* tracked_files
[] = {
1099 &sync_root
, &app_root
1102 scoped_ptr
<google_apis::FileResource
> sync_root_folder(
1103 CreateFileResourceFromMetadata(sync_root
.metadata
));
1104 scoped_ptr
<google_apis::FileResource
> app_root_folder(
1105 CreateFileResourceFromMetadata(app_root
.metadata
));
1107 ScopedVector
<google_apis::FileResource
> app_root_folders
;
1108 app_root_folders
.push_back(app_root_folder
.release());
1110 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
1111 EXPECT_EQ(SYNC_STATUS_OK
, PopulateInitialData(
1112 current_change_id(),
1116 ResetTrackerID(&sync_root
.tracker
);
1117 ResetTrackerID(&app_root
.tracker
);
1118 app_root
.tracker
.set_parent_tracker_id(sync_root
.tracker
.tracker_id());
1120 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1121 VerifyReloadConsistency();
1124 TEST_P(MetadataDatabaseTest
, DumpFiles
) {
1125 TrackedFile
sync_root(CreateTrackedSyncRoot());
1126 TrackedFile
app_root(CreateTrackedAppRoot(sync_root
, "app_id"));
1127 app_root
.tracker
.set_app_id(app_root
.metadata
.details().title());
1129 TrackedFile
folder_0(CreateTrackedFolder(app_root
, "folder_0"));
1130 TrackedFile
file_0(CreateTrackedFile(folder_0
, "file_0"));
1132 const TrackedFile
* tracked_files
[] = {
1133 &sync_root
, &app_root
, &folder_0
, &file_0
1136 SetUpDatabaseByTrackedFiles(tracked_files
, arraysize(tracked_files
));
1137 EXPECT_EQ(SYNC_STATUS_OK
, InitializeMetadataDatabase());
1138 VerifyTrackedFiles(tracked_files
, arraysize(tracked_files
));
1140 scoped_ptr
<base::ListValue
> files
=
1141 metadata_database()->DumpFiles(app_root
.tracker
.app_id());
1142 ASSERT_EQ(2u, files
->GetSize());
1144 base::DictionaryValue
* file
= nullptr;
1147 ASSERT_TRUE(files
->GetDictionary(0, &file
));
1148 EXPECT_TRUE(file
->GetString("title", &str
) && str
== "folder_0");
1149 EXPECT_TRUE(file
->GetString("type", &str
) && str
== "folder");
1150 EXPECT_TRUE(file
->HasKey("details"));
1152 ASSERT_TRUE(files
->GetDictionary(1, &file
));
1153 EXPECT_TRUE(file
->GetString("title", &str
) && str
== "file_0");
1154 EXPECT_TRUE(file
->GetString("type", &str
) && str
== "file");
1155 EXPECT_TRUE(file
->HasKey("details"));
1158 } // namespace drive_backend
1159 } // namespace sync_file_system