metadata_database_index_on_disk_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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  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, AllEntriesTest) {
256  CreateTestDatabase(true, NULL);
257
258  EXPECT_EQ(3U, index()->CountFileMetadata());
259  std::vector<std::string> file_ids(index()->GetAllMetadataIDs());
260  ASSERT_EQ(3U, file_ids.size());
261  std::sort(file_ids.begin(), file_ids.end());
262  EXPECT_EQ("app_root_folder_id", file_ids[0]);
263  EXPECT_EQ("file_id", file_ids[1]);
264  EXPECT_EQ("sync_root_folder_id", file_ids[2]);
265
266  EXPECT_EQ(4U, index()->CountFileTracker());
267  std::vector<int64> tracker_ids = index()->GetAllTrackerIDs();
268  ASSERT_EQ(4U, tracker_ids.size());
269  std::sort(tracker_ids.begin(), tracker_ids.end());
270  EXPECT_EQ(kSyncRootTrackerID, tracker_ids[0]);
271  EXPECT_EQ(kAppRootTrackerID, tracker_ids[1]);
272  EXPECT_EQ(kFileTrackerID, tracker_ids[2]);
273  EXPECT_EQ(kPlaceholderTrackerID, tracker_ids[3]);
274}
275
276TEST_F(MetadataDatabaseIndexOnDiskTest, IndexAppRootIDByAppIDTest) {
277  CreateTestDatabase(true, NULL);
278
279  std::vector<std::string> app_ids = index()->GetRegisteredAppIDs();
280  ASSERT_EQ(1U, app_ids.size());
281  EXPECT_EQ("app_id", app_ids[0]);
282
283  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker(""));
284  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
285
286  const int64 kAppRootTrackerID2 = 12;
287  FileTracker sync_root_tracker;
288  index()->GetFileTracker(kSyncRootTrackerID, &sync_root_tracker);
289  scoped_ptr<FileMetadata> app_root_metadata =
290      test_util::CreateFolderMetadata("app_root_folder_id_2", "app_title_2");
291
292  // Testing AddToAppIDIndex
293  scoped_ptr<FileTracker> app_root_tracker =
294      test_util::CreateTracker(*app_root_metadata, kAppRootTrackerID2,
295                               &sync_root_tracker);
296  app_root_tracker->set_app_id("app_id_2");
297  app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
298
299  index()->StoreFileTracker(app_root_tracker.Pass());
300  WriteToDB();
301  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
302  EXPECT_EQ(kAppRootTrackerID2, index()->GetAppRootTracker("app_id_2"));
303
304  // Testing UpdateInAppIDIndex
305  app_root_tracker = test_util::CreateTracker(*app_root_metadata,
306                                              kAppRootTrackerID2,
307                                              &sync_root_tracker);
308  app_root_tracker->set_app_id("app_id_3");
309  app_root_tracker->set_active(false);
310
311  index()->StoreFileTracker(app_root_tracker.Pass());
312  WriteToDB();
313  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
314  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_2"));
315  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_3"));
316
317  app_root_tracker = test_util::CreateTracker(*app_root_metadata,
318                                              kAppRootTrackerID2,
319                                              &sync_root_tracker);
320  app_root_tracker->set_app_id("app_id_3");
321  app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
322
323  index()->StoreFileTracker(app_root_tracker.Pass());
324  WriteToDB();
325  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
326  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_2"));
327  EXPECT_EQ(kAppRootTrackerID2, index()->GetAppRootTracker("app_id_3"));
328
329  // Testing RemoveFromAppIDIndex
330  index()->RemoveFileTracker(kAppRootTrackerID2);
331  WriteToDB();
332  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
333  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_3"));
334}
335
336TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetByFileIDTest) {
337  CreateTestDatabase(true, NULL);
338
339  FileTracker app_root_tracker;
340  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root_tracker));
341  FileMetadata metadata;
342  EXPECT_TRUE(index()->GetFileMetadata("file_id", &metadata));
343
344  // Testing GetFileTrackerIDsByFileID
345  TrackerIDSet tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
346  EXPECT_EQ(1U, tracker_ids.size());
347  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
348
349  const int64 tracker_id = 21;
350  // Testing AddToFileIDIndexes
351  scoped_ptr<FileTracker> file_tracker =
352      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
353
354  index()->StoreFileTracker(file_tracker.Pass());
355  WriteToDB();
356  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
357  EXPECT_EQ(2U, tracker_ids.size());
358  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
359
360  std::string multi_file_id = index()->PickMultiTrackerFileID();
361  EXPECT_EQ("file_id", multi_file_id);
362
363  // Testing UpdateInFileIDIndexes
364  file_tracker =
365      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
366  file_tracker->set_active(false);
367
368  index()->StoreFileTracker(file_tracker.Pass());
369  WriteToDB();
370  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
371  EXPECT_EQ(2U, tracker_ids.size());
372  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
373
374  multi_file_id = index()->PickMultiTrackerFileID();
375  EXPECT_EQ("file_id", multi_file_id);
376
377  file_tracker =
378      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
379
380  index()->StoreFileTracker(file_tracker.Pass());
381  WriteToDB();
382  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
383  EXPECT_EQ(2U, tracker_ids.size());
384  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
385
386  multi_file_id = index()->PickMultiTrackerFileID();
387  EXPECT_EQ("file_id", multi_file_id);
388
389  // Testing RemoveFromFileIDIndexes
390  index()->RemoveFileTracker(tracker_id);
391  WriteToDB();
392  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
393  EXPECT_EQ(1U, tracker_ids.size());
394  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
395
396  multi_file_id = index()->PickMultiTrackerFileID();
397  EXPECT_TRUE(multi_file_id.empty()) << multi_file_id;
398}
399
400TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetByParentIDAndTitleTest) {
401  CreateTestDatabase(true, NULL);
402
403  FileTracker app_root_tracker;
404  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root_tracker));
405  FileMetadata metadata;
406  EXPECT_TRUE(index()->GetFileMetadata("file_id", &metadata));
407
408  // Testing GetFileTrackerIDsByFileID
409  TrackerIDSet tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
410      kAppRootTrackerID, "file");
411  EXPECT_EQ(1U, tracker_ids.size());
412  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
413
414  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
415      kAppRootTrackerID, "file2");
416  EXPECT_TRUE(tracker_ids.empty());
417
418  const int64 tracker_id = 72;
419  // Testing AddToFileIDIndexes
420  scoped_ptr<FileTracker> file_tracker =
421      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
422
423  index()->StoreFileTracker(file_tracker.Pass());
424  WriteToDB();
425  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
426      kAppRootTrackerID, "file");
427  EXPECT_EQ(2U, tracker_ids.size());
428  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
429
430  ParentIDAndTitle multi_backing = index()->PickMultiBackingFilePath();
431  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
432  EXPECT_EQ("file", multi_backing.title);
433
434  // Testing UpdateInFileIDIndexes
435  file_tracker =
436      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
437  file_tracker->set_active(false);
438
439  index()->StoreFileTracker(file_tracker.Pass());
440  WriteToDB();
441  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
442      kAppRootTrackerID, "file");
443  EXPECT_EQ(2U, tracker_ids.size());
444  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
445
446  multi_backing = index()->PickMultiBackingFilePath();
447  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
448  EXPECT_EQ("file", multi_backing.title);
449
450  file_tracker =
451      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
452
453  index()->StoreFileTracker(file_tracker.Pass());
454  WriteToDB();
455  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
456      kAppRootTrackerID, "file");
457  EXPECT_EQ(2U, tracker_ids.size());
458  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
459
460  multi_backing = index()->PickMultiBackingFilePath();
461  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
462  EXPECT_EQ("file", multi_backing.title);
463
464  // Testing RemoveFromFileIDIndexes
465  index()->RemoveFileTracker(tracker_id);
466  WriteToDB();
467  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
468      kAppRootTrackerID, "file");
469  EXPECT_EQ(1U, tracker_ids.size());
470  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
471
472  multi_backing = index()->PickMultiBackingFilePath();
473  EXPECT_EQ(kInvalidTrackerID, multi_backing.parent_id);
474  EXPECT_TRUE(multi_backing.title.empty()) << multi_backing.title;
475}
476
477TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetDetailsTest) {
478  CreateTestDatabase(true, NULL);
479
480  FileTracker app_root;
481  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root));
482
483  const int64 kFileTrackerID2 = 123;
484  const int64 kFileTrackerID3 = 124;
485  scoped_ptr<FileMetadata> file_metadata =
486      test_util::CreateFileMetadata("file_id2", "file_2", "file_md5_2");
487  scoped_ptr<FileTracker> file_tracker =
488      test_util::CreateTracker(*file_metadata, kFileTrackerID2, &app_root);
489  file_tracker->set_active(false);
490  scoped_ptr<FileTracker> file_tracker2 =
491      test_util::CreateTracker(*file_metadata, kFileTrackerID3, &app_root);
492  file_tracker2->set_active(false);
493
494  // Add 2 trackers related to one file metadata.
495  index()->StoreFileMetadata(file_metadata.Pass());
496  index()->StoreFileTracker(file_tracker.Pass());
497  index()->StoreFileTracker(file_tracker2.Pass());
498
499  TrackerIDSet idset = index()->GetFileTrackerIDsByFileID("file_id2");
500  EXPECT_EQ(2U, idset.size());
501  EXPECT_FALSE(idset.has_active());
502
503  // Activate one file tracker.
504  file_tracker.reset(new FileTracker);
505  index()->GetFileTracker(kFileTrackerID2, file_tracker.get());
506  file_tracker->set_active(true);
507  index()->StoreFileTracker(file_tracker.Pass());
508
509  idset = index()->GetFileTrackerIDsByFileID("file_id2");
510  EXPECT_EQ(2U, idset.size());
511  EXPECT_TRUE(idset.has_active());
512  EXPECT_EQ(kFileTrackerID2, idset.active_tracker());
513}
514
515TEST_F(MetadataDatabaseIndexOnDiskTest, DirtyTrackersTest) {
516  CreateTestDatabase(true, NULL);
517
518  // Testing public methods
519  EXPECT_EQ(1U, index()->CountDirtyTracker());
520  EXPECT_FALSE(index()->HasDemotedDirtyTracker());
521  EXPECT_EQ(kPlaceholderTrackerID, index()->PickDirtyTracker());
522  index()->DemoteDirtyTracker(kPlaceholderTrackerID);
523  WriteToDB();
524  EXPECT_TRUE(index()->HasDemotedDirtyTracker());
525  EXPECT_EQ(1U, index()->CountDirtyTracker());
526
527  const int64 tracker_id = 13;
528  scoped_ptr<FileTracker> app_root_tracker(new FileTracker);
529  index()->GetFileTracker(kAppRootTrackerID, app_root_tracker.get());
530
531  // Testing AddDirtyTrackerIndexes
532  scoped_ptr<FileTracker> tracker =
533      test_util::CreatePlaceholderTracker("placeholder",
534                                          tracker_id,
535                                          app_root_tracker.get());
536  index()->StoreFileTracker(tracker.Pass());
537  WriteToDB();
538  EXPECT_EQ(2U, index()->CountDirtyTracker());
539  EXPECT_EQ(tracker_id, index()->PickDirtyTracker());
540
541  // Testing UpdateDirtyTrackerIndexes
542  tracker = test_util::CreatePlaceholderTracker("placeholder",
543                                                tracker_id,
544                                                app_root_tracker.get());
545  tracker->set_dirty(false);
546  index()->StoreFileTracker(tracker.Pass());
547  WriteToDB();
548  EXPECT_EQ(1U, index()->CountDirtyTracker());
549  EXPECT_EQ(kInvalidTrackerID, index()->PickDirtyTracker());
550
551  tracker = test_util::CreatePlaceholderTracker("placeholder",
552                                                tracker_id,
553                                                app_root_tracker.get());
554  index()->StoreFileTracker(tracker.Pass());
555  WriteToDB();
556  EXPECT_EQ(2U, index()->CountDirtyTracker());
557  EXPECT_EQ(tracker_id, index()->PickDirtyTracker());
558
559  // Testing RemoveFromDirtyTrackerIndexes
560  index()->RemoveFileTracker(tracker_id);
561  WriteToDB();
562  EXPECT_EQ(1U, index()->CountDirtyTracker());
563  EXPECT_EQ(kInvalidTrackerID, index()->PickDirtyTracker());
564}
565
566}  // namespace drive_backend
567}  // namespace sync_file_system
568