metadata_database_index_on_disk_unittest.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright 2014 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_index_on_disk.h"
6
7#include "base/files/scoped_temp_dir.h"
8#include "base/strings/string_number_conversions.h"
9#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
10#include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
11#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
12#include "chrome/browser/sync_file_system/drive_backend/leveldb_wrapper.h"
13#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
14#include "testing/gtest/include/gtest/gtest.h"
15#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
16#include "third_party/leveldatabase/src/include/leveldb/db.h"
17#include "third_party/leveldatabase/src/include/leveldb/env.h"
18#include "third_party/leveldatabase/src/include/leveldb/status.h"
19
20namespace sync_file_system {
21namespace drive_backend {
22
23namespace {
24
25const int64 kSyncRootTrackerID = 1;
26const int64 kAppRootTrackerID = 2;
27const int64 kFileTrackerID = 3;
28const int64 kPlaceholderTrackerID = 4;
29
30}  // namespace
31
32class MetadataDatabaseIndexOnDiskTest : public testing::Test {
33 public:
34  virtual ~MetadataDatabaseIndexOnDiskTest() {}
35
36  virtual void SetUp() OVERRIDE {
37    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
38    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
39    db_ = InitializeLevelDB();
40    index_ = MetadataDatabaseIndexOnDisk::Create(db_.get());
41  }
42
43  virtual void TearDown() OVERRIDE {
44    index_.reset();
45    db_.reset();
46    in_memory_env_.reset();
47  }
48
49  void CreateTestDatabase(bool build_index, LevelDBWrapper* db) {
50    if (!db) {
51      DCHECK(index());
52      db = index()->GetDBForTesting();
53    }
54    DCHECK(db);
55
56    scoped_ptr<FileMetadata> sync_root_metadata =
57        test_util::CreateFolderMetadata("sync_root_folder_id",
58                                        "Chrome Syncable FileSystem");
59    scoped_ptr<FileTracker> sync_root_tracker =
60        test_util::CreateTracker(*sync_root_metadata, kSyncRootTrackerID, NULL);
61
62    scoped_ptr<FileMetadata> app_root_metadata =
63        test_util::CreateFolderMetadata("app_root_folder_id", "app_title");
64    scoped_ptr<FileTracker> app_root_tracker =
65        test_util::CreateTracker(*app_root_metadata, kAppRootTrackerID,
66                                 sync_root_tracker.get());
67    app_root_tracker->set_app_id("app_id");
68    app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
69
70    scoped_ptr<FileMetadata> file_metadata =
71        test_util::CreateFileMetadata("file_id", "file", "file_md5");
72    scoped_ptr<FileTracker> file_tracker =
73        test_util::CreateTracker(*file_metadata,
74                                 kFileTrackerID,
75                                 app_root_tracker.get());
76
77    scoped_ptr<FileTracker> placeholder_tracker =
78        test_util::CreatePlaceholderTracker("unsynced_file_id",
79                                            kPlaceholderTrackerID,
80                                            app_root_tracker.get());
81
82    scoped_ptr<ServiceMetadata> service_metadata =
83        InitializeServiceMetadata(db);
84    service_metadata->set_sync_root_tracker_id(kSyncRootTrackerID);
85    PutServiceMetadataToDB(*service_metadata, db);
86
87    if (build_index) {
88      DCHECK(index());
89
90      index()->StoreFileMetadata(sync_root_metadata.Pass());
91      index()->StoreFileTracker(sync_root_tracker.Pass());
92      index()->StoreFileMetadata(app_root_metadata.Pass());
93      index()->StoreFileTracker(app_root_tracker.Pass());
94      index()->StoreFileMetadata(file_metadata.Pass());
95      index()->StoreFileTracker(file_tracker.Pass());
96      index()->StoreFileTracker(placeholder_tracker.Pass());
97    } else {
98      PutFileMetadataToDB(*sync_root_metadata, db);
99      PutFileTrackerToDB(*sync_root_tracker, db);
100      PutFileMetadataToDB(*app_root_metadata, db);
101      PutFileTrackerToDB(*app_root_tracker, db);
102      PutFileMetadataToDB(*file_metadata, db);
103      PutFileTrackerToDB(*file_tracker, db);
104      PutFileTrackerToDB(*placeholder_tracker, db);
105    }
106
107    ASSERT_TRUE(db->Commit().ok());
108  }
109
110  MetadataDatabaseIndexOnDisk* index() { return index_.get(); }
111
112  void WriteToDB() {
113    ASSERT_TRUE(db_->Commit().ok());
114  }
115
116  scoped_ptr<LevelDBWrapper> InitializeLevelDB() {
117    leveldb::DB* db = NULL;
118    leveldb::Options options;
119    options.create_if_missing = true;
120    options.max_open_files = 0;  // Use minimum.
121    options.env = in_memory_env_.get();
122    leveldb::Status status =
123        leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db);
124    EXPECT_TRUE(status.ok());
125    return make_scoped_ptr(new LevelDBWrapper(make_scoped_ptr(db)));
126  }
127
128 private:
129  scoped_ptr<MetadataDatabaseIndexOnDisk> index_;
130
131  base::ScopedTempDir database_dir_;
132  scoped_ptr<leveldb::Env> in_memory_env_;
133  scoped_ptr<LevelDBWrapper> db_;
134};
135
136TEST_F(MetadataDatabaseIndexOnDiskTest, GetEntryTest) {
137  CreateTestDatabase(false, NULL);
138
139  FileTracker tracker;
140  EXPECT_FALSE(index()->GetFileTracker(kInvalidTrackerID, NULL));
141  ASSERT_TRUE(index()->GetFileTracker(kFileTrackerID, &tracker));
142  EXPECT_EQ(kFileTrackerID, tracker.tracker_id());
143  EXPECT_EQ("file_id", tracker.file_id());
144
145  FileMetadata metadata;
146  EXPECT_FALSE(index()->GetFileMetadata(std::string(), NULL));
147  ASSERT_TRUE(index()->GetFileMetadata("file_id", &metadata));
148  EXPECT_EQ("file_id", metadata.file_id());
149}
150
151TEST_F(MetadataDatabaseIndexOnDiskTest, SetEntryTest) {
152  CreateTestDatabase(false, NULL);
153
154  const int64 tracker_id = 10;
155  scoped_ptr<FileMetadata> metadata =
156      test_util::CreateFileMetadata("test_file_id", "test_title", "test_md5");
157  FileTracker root_tracker;
158  EXPECT_TRUE(index()->GetFileTracker(kSyncRootTrackerID, &root_tracker));
159  scoped_ptr<FileTracker> tracker =
160      test_util::CreateTracker(*metadata, tracker_id, &root_tracker);
161
162  index()->StoreFileMetadata(metadata.Pass());
163  index()->StoreFileTracker(tracker.Pass());
164
165  EXPECT_TRUE(index()->GetFileMetadata("test_file_id", NULL));
166  EXPECT_TRUE(index()->GetFileTracker(tracker_id, NULL));
167
168  WriteToDB();
169
170  metadata.reset(new FileMetadata);
171  ASSERT_TRUE(index()->GetFileMetadata("test_file_id", metadata.get()));
172  EXPECT_TRUE(metadata->has_details());
173  EXPECT_EQ("test_title", metadata->details().title());
174
175  tracker.reset(new FileTracker);
176  ASSERT_TRUE(index()->GetFileTracker(tracker_id, tracker.get()));
177  EXPECT_EQ("test_file_id", tracker->file_id());
178
179  // Test if removers work.
180  index()->RemoveFileMetadata("test_file_id");
181  index()->RemoveFileTracker(tracker_id);
182
183  EXPECT_FALSE(index()->GetFileMetadata("test_file_id", NULL));
184  EXPECT_FALSE(index()->GetFileTracker(tracker_id, NULL));
185
186  WriteToDB();
187
188  EXPECT_FALSE(index()->GetFileMetadata("test_file_id", NULL));
189  EXPECT_FALSE(index()->GetFileTracker(tracker_id, NULL));
190}
191
192TEST_F(MetadataDatabaseIndexOnDiskTest, RemoveUnreachableItemsTest) {
193  scoped_ptr<LevelDBWrapper> db = InitializeLevelDB();
194  CreateTestDatabase(false, db.get());
195
196  const int kOrphanedFileTrackerID = 13;
197  scoped_ptr<FileMetadata> orphaned_metadata =
198      test_util::CreateFileMetadata("orphaned_id", "orphaned", "md5");
199  scoped_ptr<FileTracker> orphaned_tracker =
200      test_util::CreateTracker(*orphaned_metadata,
201                               kOrphanedFileTrackerID,
202                               NULL);
203
204  PutFileMetadataToDB(*orphaned_metadata, db.get());
205  PutFileTrackerToDB(*orphaned_tracker, db.get());
206  EXPECT_TRUE(db->Commit().ok());
207
208  const std::string key =
209      kFileTrackerKeyPrefix + base::Int64ToString(kOrphanedFileTrackerID);
210  std::string value;
211  EXPECT_TRUE(db->Get(key, &value).ok());
212
213  // RemoveUnreachableItems() is expected to run on index creation.
214  scoped_ptr<MetadataDatabaseIndexOnDisk> index_on_disk =
215      MetadataDatabaseIndexOnDisk::Create(db.get());
216  EXPECT_TRUE(db->Commit().ok());
217
218  EXPECT_TRUE(db->Get(key, &value).IsNotFound());
219  EXPECT_FALSE(index_on_disk->GetFileTracker(kOrphanedFileTrackerID, NULL));
220
221  EXPECT_TRUE(index_on_disk->GetFileTracker(kSyncRootTrackerID, NULL));
222  EXPECT_TRUE(index_on_disk->GetFileTracker(kAppRootTrackerID, NULL));
223  EXPECT_TRUE(index_on_disk->GetFileTracker(kFileTrackerID, NULL));
224}
225
226
227TEST_F(MetadataDatabaseIndexOnDiskTest, BuildIndexTest) {
228  CreateTestDatabase(false, NULL);
229
230  TrackerIDSet tracker_ids;
231  // Before building indexes, no references exist.
232  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id"));
233  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
234  EXPECT_TRUE(tracker_ids.empty());
235  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
236      kAppRootTrackerID, "file");
237  EXPECT_TRUE(tracker_ids.empty());
238  EXPECT_EQ(0U, index()->CountDirtyTracker());
239
240  EXPECT_EQ(16, index()->BuildTrackerIndexes());
241  WriteToDB();
242
243  // After building indexes, we should have correct indexes.
244  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
245  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
246  EXPECT_EQ(1U, tracker_ids.size());
247  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
248  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
249      kAppRootTrackerID, "file");
250  EXPECT_EQ(1U, tracker_ids.size());
251  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
252  EXPECT_EQ(1U, index()->CountDirtyTracker());
253}
254
255TEST_F(MetadataDatabaseIndexOnDiskTest, BuildAndDeleteIndexTest) {
256  CreateTestDatabase(false, NULL);
257  int64 answer = index()->BuildTrackerIndexes();
258  WriteToDB();
259  ASSERT_EQ(16, answer);
260  EXPECT_EQ(answer, index()->DeleteTrackerIndexes());
261  WriteToDB();
262  EXPECT_EQ(answer, index()->BuildTrackerIndexes());
263  WriteToDB();
264}
265
266TEST_F(MetadataDatabaseIndexOnDiskTest, AllEntriesTest) {
267  CreateTestDatabase(true, NULL);
268
269  EXPECT_EQ(3U, index()->CountFileMetadata());
270  std::vector<std::string> file_ids(index()->GetAllMetadataIDs());
271  ASSERT_EQ(3U, file_ids.size());
272  std::sort(file_ids.begin(), file_ids.end());
273  EXPECT_EQ("app_root_folder_id", file_ids[0]);
274  EXPECT_EQ("file_id", file_ids[1]);
275  EXPECT_EQ("sync_root_folder_id", file_ids[2]);
276
277  EXPECT_EQ(4U, index()->CountFileTracker());
278  std::vector<int64> tracker_ids = index()->GetAllTrackerIDs();
279  ASSERT_EQ(4U, tracker_ids.size());
280  std::sort(tracker_ids.begin(), tracker_ids.end());
281  EXPECT_EQ(kSyncRootTrackerID, tracker_ids[0]);
282  EXPECT_EQ(kAppRootTrackerID, tracker_ids[1]);
283  EXPECT_EQ(kFileTrackerID, tracker_ids[2]);
284  EXPECT_EQ(kPlaceholderTrackerID, tracker_ids[3]);
285}
286
287TEST_F(MetadataDatabaseIndexOnDiskTest, IndexAppRootIDByAppIDTest) {
288  CreateTestDatabase(true, NULL);
289
290  std::vector<std::string> app_ids = index()->GetRegisteredAppIDs();
291  ASSERT_EQ(1U, app_ids.size());
292  EXPECT_EQ("app_id", app_ids[0]);
293
294  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker(""));
295  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
296
297  const int64 kAppRootTrackerID2 = 12;
298  FileTracker sync_root_tracker;
299  index()->GetFileTracker(kSyncRootTrackerID, &sync_root_tracker);
300  scoped_ptr<FileMetadata> app_root_metadata =
301      test_util::CreateFolderMetadata("app_root_folder_id_2", "app_title_2");
302
303  // Testing AddToAppIDIndex
304  scoped_ptr<FileTracker> app_root_tracker =
305      test_util::CreateTracker(*app_root_metadata, kAppRootTrackerID2,
306                               &sync_root_tracker);
307  app_root_tracker->set_app_id("app_id_2");
308  app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
309
310  index()->StoreFileTracker(app_root_tracker.Pass());
311  WriteToDB();
312  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
313  EXPECT_EQ(kAppRootTrackerID2, index()->GetAppRootTracker("app_id_2"));
314
315  // Testing UpdateInAppIDIndex
316  app_root_tracker = test_util::CreateTracker(*app_root_metadata,
317                                              kAppRootTrackerID2,
318                                              &sync_root_tracker);
319  app_root_tracker->set_app_id("app_id_3");
320  app_root_tracker->set_active(false);
321
322  index()->StoreFileTracker(app_root_tracker.Pass());
323  WriteToDB();
324  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
325  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_2"));
326  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_3"));
327
328  app_root_tracker = test_util::CreateTracker(*app_root_metadata,
329                                              kAppRootTrackerID2,
330                                              &sync_root_tracker);
331  app_root_tracker->set_app_id("app_id_3");
332  app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
333
334  index()->StoreFileTracker(app_root_tracker.Pass());
335  WriteToDB();
336  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
337  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_2"));
338  EXPECT_EQ(kAppRootTrackerID2, index()->GetAppRootTracker("app_id_3"));
339
340  // Testing RemoveFromAppIDIndex
341  index()->RemoveFileTracker(kAppRootTrackerID2);
342  WriteToDB();
343  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
344  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_3"));
345}
346
347TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetByFileIDTest) {
348  CreateTestDatabase(true, NULL);
349
350  FileTracker app_root_tracker;
351  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root_tracker));
352  FileMetadata metadata;
353  EXPECT_TRUE(index()->GetFileMetadata("file_id", &metadata));
354
355  // Testing GetFileTrackerIDsByFileID
356  TrackerIDSet tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
357  EXPECT_EQ(1U, tracker_ids.size());
358  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
359
360  const int64 tracker_id = 21;
361  // Testing AddToFileIDIndexes
362  scoped_ptr<FileTracker> file_tracker =
363      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
364
365  index()->StoreFileTracker(file_tracker.Pass());
366  WriteToDB();
367  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
368  EXPECT_EQ(2U, tracker_ids.size());
369  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
370
371  std::string multi_file_id = index()->PickMultiTrackerFileID();
372  EXPECT_EQ("file_id", multi_file_id);
373
374  // Testing UpdateInFileIDIndexes
375  file_tracker =
376      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
377  file_tracker->set_active(false);
378
379  index()->StoreFileTracker(file_tracker.Pass());
380  WriteToDB();
381  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
382  EXPECT_EQ(2U, tracker_ids.size());
383  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
384
385  multi_file_id = index()->PickMultiTrackerFileID();
386  EXPECT_EQ("file_id", multi_file_id);
387
388  file_tracker =
389      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
390
391  index()->StoreFileTracker(file_tracker.Pass());
392  WriteToDB();
393  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
394  EXPECT_EQ(2U, tracker_ids.size());
395  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
396
397  multi_file_id = index()->PickMultiTrackerFileID();
398  EXPECT_EQ("file_id", multi_file_id);
399
400  // Testing RemoveFromFileIDIndexes
401  index()->RemoveFileTracker(tracker_id);
402  WriteToDB();
403  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
404  EXPECT_EQ(1U, tracker_ids.size());
405  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
406
407  multi_file_id = index()->PickMultiTrackerFileID();
408  EXPECT_TRUE(multi_file_id.empty()) << multi_file_id;
409}
410
411TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetByParentIDAndTitleTest) {
412  CreateTestDatabase(true, NULL);
413
414  FileTracker app_root_tracker;
415  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root_tracker));
416  FileMetadata metadata;
417  EXPECT_TRUE(index()->GetFileMetadata("file_id", &metadata));
418
419  // Testing GetFileTrackerIDsByFileID
420  TrackerIDSet tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
421      kAppRootTrackerID, "file");
422  EXPECT_EQ(1U, tracker_ids.size());
423  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
424
425  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
426      kAppRootTrackerID, "file2");
427  EXPECT_TRUE(tracker_ids.empty());
428
429  const int64 tracker_id = 72;
430  // Testing AddToFileIDIndexes
431  scoped_ptr<FileTracker> file_tracker =
432      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
433
434  index()->StoreFileTracker(file_tracker.Pass());
435  WriteToDB();
436  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
437      kAppRootTrackerID, "file");
438  EXPECT_EQ(2U, tracker_ids.size());
439  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
440
441  ParentIDAndTitle multi_backing = index()->PickMultiBackingFilePath();
442  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
443  EXPECT_EQ("file", multi_backing.title);
444
445  // Testing UpdateInFileIDIndexes
446  file_tracker =
447      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
448  file_tracker->set_active(false);
449
450  index()->StoreFileTracker(file_tracker.Pass());
451  WriteToDB();
452  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
453      kAppRootTrackerID, "file");
454  EXPECT_EQ(2U, tracker_ids.size());
455  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
456
457  multi_backing = index()->PickMultiBackingFilePath();
458  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
459  EXPECT_EQ("file", multi_backing.title);
460
461  file_tracker =
462      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
463
464  index()->StoreFileTracker(file_tracker.Pass());
465  WriteToDB();
466  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
467      kAppRootTrackerID, "file");
468  EXPECT_EQ(2U, tracker_ids.size());
469  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
470
471  multi_backing = index()->PickMultiBackingFilePath();
472  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
473  EXPECT_EQ("file", multi_backing.title);
474
475  // Testing RemoveFromFileIDIndexes
476  index()->RemoveFileTracker(tracker_id);
477  WriteToDB();
478  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
479      kAppRootTrackerID, "file");
480  EXPECT_EQ(1U, tracker_ids.size());
481  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
482
483  multi_backing = index()->PickMultiBackingFilePath();
484  EXPECT_EQ(kInvalidTrackerID, multi_backing.parent_id);
485  EXPECT_TRUE(multi_backing.title.empty()) << multi_backing.title;
486}
487
488TEST_F(MetadataDatabaseIndexOnDiskTest,
489       TrackerIDSetByParentIDAndTitleTest_EmptyTitle) {
490  CreateTestDatabase(true, NULL);
491
492  const int64 kFolderTrackerID = 23;
493  const int64 kNewFileTrackerID = 42;
494  {
495    FileTracker app_root_tracker;
496    EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root_tracker));
497    scoped_ptr<FileMetadata> folder_metadata =
498        test_util::CreateFolderMetadata("folder_id", "folder_name");
499    scoped_ptr<FileTracker> folder_tracker =
500        test_util::CreateTracker(*folder_metadata, kFolderTrackerID,
501                                 &app_root_tracker);
502    index()->StoreFileMetadata(folder_metadata.Pass());
503    index()->StoreFileTracker(folder_tracker.Pass());
504    WriteToDB();
505  }
506
507  FileTracker folder_tracker;
508  EXPECT_TRUE(index()->GetFileTracker(kFolderTrackerID, &folder_tracker));
509  scoped_ptr<FileMetadata> metadata =
510      test_util::CreateFileMetadata("file_id2", std::string(), "md5_2");
511
512  // Testing GetFileTrackerIDsByFileID
513  TrackerIDSet tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
514      kFolderTrackerID, std::string());
515  EXPECT_TRUE(tracker_ids.empty());
516
517  // Testing AddToFileIDIndexes
518  scoped_ptr<FileTracker> file_tracker =
519      test_util::CreateTracker(*metadata, kNewFileTrackerID, &folder_tracker);
520
521  index()->StoreFileTracker(file_tracker.Pass());
522  WriteToDB();
523  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
524      kFolderTrackerID, std::string());
525  EXPECT_EQ(1U, tracker_ids.size());
526  EXPECT_EQ(kNewFileTrackerID, tracker_ids.active_tracker());
527
528  ParentIDAndTitle multi_backing = index()->PickMultiBackingFilePath();
529  EXPECT_EQ(kInvalidTrackerID, multi_backing.parent_id);
530
531  // Testing UpdateInFileIDIndexes
532  file_tracker =
533      test_util::CreateTracker(*metadata, kNewFileTrackerID, &folder_tracker);
534
535  index()->StoreFileTracker(file_tracker.Pass());
536  WriteToDB();
537  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
538      kFolderTrackerID, std::string());
539  EXPECT_EQ(1U, tracker_ids.size());
540  EXPECT_EQ(kNewFileTrackerID, tracker_ids.active_tracker());
541
542  multi_backing = index()->PickMultiBackingFilePath();
543  EXPECT_EQ(kInvalidTrackerID, multi_backing.parent_id);
544}
545
546TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetDetailsTest) {
547  CreateTestDatabase(true, NULL);
548
549  FileTracker app_root;
550  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root));
551
552  const int64 kFileTrackerID2 = 123;
553  const int64 kFileTrackerID3 = 124;
554  scoped_ptr<FileMetadata> file_metadata =
555      test_util::CreateFileMetadata("file_id2", "file_2", "file_md5_2");
556  scoped_ptr<FileTracker> file_tracker =
557      test_util::CreateTracker(*file_metadata, kFileTrackerID2, &app_root);
558  file_tracker->set_active(false);
559  scoped_ptr<FileTracker> file_tracker2 =
560      test_util::CreateTracker(*file_metadata, kFileTrackerID3, &app_root);
561  file_tracker2->set_active(false);
562
563  // Add 2 trackers related to one file metadata.
564  index()->StoreFileMetadata(file_metadata.Pass());
565  index()->StoreFileTracker(file_tracker.Pass());
566  index()->StoreFileTracker(file_tracker2.Pass());
567
568  TrackerIDSet idset = index()->GetFileTrackerIDsByFileID("file_id2");
569  EXPECT_EQ(2U, idset.size());
570  EXPECT_FALSE(idset.has_active());
571
572  // Activate one file tracker.
573  file_tracker.reset(new FileTracker);
574  index()->GetFileTracker(kFileTrackerID2, file_tracker.get());
575  file_tracker->set_active(true);
576  index()->StoreFileTracker(file_tracker.Pass());
577
578  idset = index()->GetFileTrackerIDsByFileID("file_id2");
579  EXPECT_EQ(2U, idset.size());
580  EXPECT_TRUE(idset.has_active());
581  EXPECT_EQ(kFileTrackerID2, idset.active_tracker());
582}
583
584TEST_F(MetadataDatabaseIndexOnDiskTest, DirtyTrackersTest) {
585  CreateTestDatabase(true, NULL);
586
587  // Testing public methods
588  EXPECT_EQ(1U, index()->CountDirtyTracker());
589  EXPECT_FALSE(index()->HasDemotedDirtyTracker());
590  EXPECT_EQ(kPlaceholderTrackerID, index()->PickDirtyTracker());
591  index()->DemoteDirtyTracker(kPlaceholderTrackerID);
592  WriteToDB();
593  EXPECT_TRUE(index()->HasDemotedDirtyTracker());
594  EXPECT_EQ(1U, index()->CountDirtyTracker());
595
596  const int64 tracker_id = 13;
597  scoped_ptr<FileTracker> app_root_tracker(new FileTracker);
598  index()->GetFileTracker(kAppRootTrackerID, app_root_tracker.get());
599
600  // Testing AddDirtyTrackerIndexes
601  scoped_ptr<FileTracker> tracker =
602      test_util::CreatePlaceholderTracker("placeholder",
603                                          tracker_id,
604                                          app_root_tracker.get());
605  index()->StoreFileTracker(tracker.Pass());
606  WriteToDB();
607  EXPECT_EQ(2U, index()->CountDirtyTracker());
608  EXPECT_EQ(tracker_id, index()->PickDirtyTracker());
609
610  // Testing UpdateDirtyTrackerIndexes
611  tracker = test_util::CreatePlaceholderTracker("placeholder",
612                                                tracker_id,
613                                                app_root_tracker.get());
614  tracker->set_dirty(false);
615  index()->StoreFileTracker(tracker.Pass());
616  WriteToDB();
617  EXPECT_EQ(1U, index()->CountDirtyTracker());
618  EXPECT_EQ(kInvalidTrackerID, index()->PickDirtyTracker());
619
620  tracker = test_util::CreatePlaceholderTracker("placeholder",
621                                                tracker_id,
622                                                app_root_tracker.get());
623  index()->StoreFileTracker(tracker.Pass());
624  WriteToDB();
625  EXPECT_EQ(2U, index()->CountDirtyTracker());
626  EXPECT_EQ(tracker_id, index()->PickDirtyTracker());
627
628  // Testing RemoveFromDirtyTrackerIndexes
629  index()->RemoveFileTracker(tracker_id);
630  WriteToDB();
631  EXPECT_EQ(1U, index()->CountDirtyTracker());
632  EXPECT_EQ(kInvalidTrackerID, index()->PickDirtyTracker());
633}
634
635}  // namespace drive_backend
636}  // namespace sync_file_system
637