metadata_database_index_on_disk_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
9#include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
10#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
11#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
14#include "third_party/leveldatabase/src/include/leveldb/db.h"
15#include "third_party/leveldatabase/src/include/leveldb/env.h"
16#include "third_party/leveldatabase/src/include/leveldb/status.h"
17#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
18
19namespace sync_file_system {
20namespace drive_backend {
21
22namespace {
23
24const int64 kSyncRootTrackerID = 1;
25const int64 kAppRootTrackerID = 2;
26const int64 kFileTrackerID = 3;
27const int64 kPlaceholderTrackerID = 4;
28
29}  // namespace
30
31class MetadataDatabaseIndexOnDiskTest : public testing::Test {
32 public:
33  virtual ~MetadataDatabaseIndexOnDiskTest() {}
34
35  virtual void SetUp() OVERRIDE {
36    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
37    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
38    InitializeLevelDB();
39    index_ = MetadataDatabaseIndexOnDisk::Create(db_.get(), NULL);
40  }
41
42  virtual void TearDown() OVERRIDE {
43    index_.reset();
44    db_.reset();
45    in_memory_env_.reset();
46  }
47
48  bool WriteToDB(scoped_ptr<leveldb::WriteBatch> batch) {
49    leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch.get());
50    return status.ok();
51  }
52
53  void CreateTestDatabase(bool build_index) {
54    scoped_ptr<FileMetadata> sync_root_metadata =
55        test_util::CreateFolderMetadata("sync_root_folder_id",
56                                        "Chrome Syncable FileSystem");
57    scoped_ptr<FileTracker> sync_root_tracker =
58        test_util::CreateTracker(*sync_root_metadata, kSyncRootTrackerID, NULL);
59
60    scoped_ptr<FileMetadata> app_root_metadata =
61        test_util::CreateFolderMetadata("app_root_folder_id", "app_title");
62    scoped_ptr<FileTracker> app_root_tracker =
63        test_util::CreateTracker(*app_root_metadata, kAppRootTrackerID,
64                                 sync_root_tracker.get());
65    app_root_tracker->set_app_id("app_id");
66    app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
67
68    scoped_ptr<FileMetadata> file_metadata =
69        test_util::CreateFileMetadata("file_id", "file", "file_md5");
70    scoped_ptr<FileTracker> file_tracker =
71        test_util::CreateTracker(*file_metadata,
72                                 kFileTrackerID,
73                                 app_root_tracker.get());
74
75    scoped_ptr<FileTracker> placeholder_tracker =
76        test_util::CreatePlaceholderTracker("unsynced_file_id",
77                                            kPlaceholderTrackerID,
78                                            app_root_tracker.get());
79
80    leveldb::WriteBatch batch;
81    if (build_index) {
82      DCHECK(index());
83      index()->StoreFileMetadata(sync_root_metadata.Pass(), &batch);
84      index()->StoreFileTracker(sync_root_tracker.Pass(), &batch);
85      index()->StoreFileMetadata(app_root_metadata.Pass(), &batch);
86      index()->StoreFileTracker(app_root_tracker.Pass(), &batch);
87      index()->StoreFileMetadata(file_metadata.Pass(), &batch);
88      index()->StoreFileTracker(file_tracker.Pass(), &batch);
89      index()->StoreFileTracker(placeholder_tracker.Pass(), &batch);
90    } else {
91      PutFileMetadataToBatch(*sync_root_metadata, &batch);
92      PutFileTrackerToBatch(*sync_root_tracker, &batch);
93      PutFileMetadataToBatch(*app_root_metadata, &batch);
94      PutFileTrackerToBatch(*app_root_tracker, &batch);
95      PutFileMetadataToBatch(*file_metadata, &batch);
96      PutFileTrackerToBatch(*file_tracker, &batch);
97      PutFileTrackerToBatch(*placeholder_tracker, &batch);
98    }
99
100    leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
101    ASSERT_TRUE(status.ok());
102  }
103
104  MetadataDatabaseIndexOnDisk* index() { return index_.get(); }
105
106 private:
107  void InitializeLevelDB() {
108    leveldb::DB* db = NULL;
109    leveldb::Options options;
110    options.create_if_missing = true;
111    options.max_open_files = 0;  // Use minimum.
112    options.env = in_memory_env_.get();
113    leveldb::Status status =
114        leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db);
115    ASSERT_TRUE(status.ok());
116    db_.reset(db);
117  }
118
119  scoped_ptr<MetadataDatabaseIndexOnDisk> index_;
120
121  base::ScopedTempDir database_dir_;
122  scoped_ptr<leveldb::Env> in_memory_env_;
123  scoped_ptr<leveldb::DB> db_;
124};
125
126TEST_F(MetadataDatabaseIndexOnDiskTest, GetEntryTest) {
127  CreateTestDatabase(false);
128
129  FileTracker tracker;
130  EXPECT_FALSE(index()->GetFileTracker(kInvalidTrackerID, NULL));
131  ASSERT_TRUE(index()->GetFileTracker(kFileTrackerID, &tracker));
132  EXPECT_EQ(kFileTrackerID, tracker.tracker_id());
133  EXPECT_EQ("file_id", tracker.file_id());
134
135  FileMetadata metadata;
136  EXPECT_FALSE(index()->GetFileMetadata(std::string(), NULL));
137  ASSERT_TRUE(index()->GetFileMetadata("file_id", &metadata));
138  EXPECT_EQ("file_id", metadata.file_id());
139}
140
141TEST_F(MetadataDatabaseIndexOnDiskTest, SetEntryTest) {
142  // This test does not check updates of indexes.
143  CreateTestDatabase(false);
144
145  const int64 tracker_id = 10;
146  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
147  scoped_ptr<FileMetadata> metadata =
148      test_util::CreateFileMetadata("test_file_id", "test_title", "test_md5");
149  FileTracker root_tracker;
150  EXPECT_TRUE(index()->GetFileTracker(kSyncRootTrackerID, &root_tracker));
151  scoped_ptr<FileTracker> tracker =
152      test_util::CreateTracker(*metadata, tracker_id, &root_tracker);
153
154  index()->StoreFileMetadata(metadata.Pass(), batch.get());
155  index()->StoreFileTracker(tracker.Pass(), batch.get());
156
157  EXPECT_FALSE(index()->GetFileMetadata("test_file_id", NULL));
158  EXPECT_FALSE(index()->GetFileTracker(tracker_id, NULL));
159
160  WriteToDB(batch.Pass());
161
162  metadata.reset(new FileMetadata);
163  ASSERT_TRUE(index()->GetFileMetadata("test_file_id", metadata.get()));
164  EXPECT_TRUE(metadata->has_details());
165  EXPECT_EQ("test_title", metadata->details().title());
166
167  tracker.reset(new FileTracker);
168  ASSERT_TRUE(index()->GetFileTracker(tracker_id, tracker.get()));
169  EXPECT_EQ("test_file_id", tracker->file_id());
170
171  // Test if removers work.
172  batch.reset(new leveldb::WriteBatch);
173
174  index()->RemoveFileMetadata("test_file_id", batch.get());
175  index()->RemoveFileTracker(tracker_id, batch.get());
176
177  EXPECT_TRUE(index()->GetFileMetadata("test_file_id", NULL));
178  EXPECT_TRUE(index()->GetFileTracker(tracker_id, NULL));
179
180  WriteToDB(batch.Pass());
181
182  EXPECT_FALSE(index()->GetFileMetadata("test_file_id", NULL));
183  EXPECT_FALSE(index()->GetFileTracker(tracker_id, NULL));
184}
185
186TEST_F(MetadataDatabaseIndexOnDiskTest, BuildIndexTest) {
187  CreateTestDatabase(false);
188
189  TrackerIDSet tracker_ids;
190  // Before building indexes, no references exist.
191  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id"));
192  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
193  EXPECT_TRUE(tracker_ids.empty());
194  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
195      kAppRootTrackerID, "file");
196  EXPECT_TRUE(tracker_ids.empty());
197  EXPECT_EQ(0U, index()->CountDirtyTracker());
198
199  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
200  index()->BuildTrackerIndexes(batch.get());
201  WriteToDB(batch.Pass());
202
203  // After building indexes, we should have correct indexes.
204  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
205  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
206  EXPECT_EQ(1U, tracker_ids.size());
207  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
208  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
209      kAppRootTrackerID, "file");
210  EXPECT_EQ(1U, tracker_ids.size());
211  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
212  EXPECT_EQ(1U, index()->CountDirtyTracker());
213}
214
215TEST_F(MetadataDatabaseIndexOnDiskTest, AllEntriesTest) {
216  CreateTestDatabase(true);
217
218  EXPECT_EQ(3U, index()->CountFileMetadata());
219  std::vector<std::string> file_ids(index()->GetAllMetadataIDs());
220  ASSERT_EQ(3U, file_ids.size());
221  std::sort(file_ids.begin(), file_ids.end());
222  EXPECT_EQ("app_root_folder_id", file_ids[0]);
223  EXPECT_EQ("file_id", file_ids[1]);
224  EXPECT_EQ("sync_root_folder_id", file_ids[2]);
225
226  EXPECT_EQ(4U, index()->CountFileTracker());
227  std::vector<int64> tracker_ids = index()->GetAllTrackerIDs();
228  ASSERT_EQ(4U, tracker_ids.size());
229  std::sort(tracker_ids.begin(), tracker_ids.end());
230  EXPECT_EQ(kSyncRootTrackerID, tracker_ids[0]);
231  EXPECT_EQ(kAppRootTrackerID, tracker_ids[1]);
232  EXPECT_EQ(kFileTrackerID, tracker_ids[2]);
233  EXPECT_EQ(kPlaceholderTrackerID, tracker_ids[3]);
234}
235
236TEST_F(MetadataDatabaseIndexOnDiskTest, IndexAppRootIDByAppIDTest) {
237  CreateTestDatabase(true);
238
239  std::vector<std::string> app_ids = index()->GetRegisteredAppIDs();
240  ASSERT_EQ(1U, app_ids.size());
241  EXPECT_EQ("app_id", app_ids[0]);
242
243  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker(""));
244  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
245
246  const int64 kAppRootTrackerID2 = 12;
247  FileTracker sync_root_tracker;
248  index()->GetFileTracker(kSyncRootTrackerID, &sync_root_tracker);
249  scoped_ptr<FileMetadata> app_root_metadata =
250      test_util::CreateFolderMetadata("app_root_folder_id_2", "app_title_2");
251
252  // Testing AddToAppIDIndex
253  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
254  scoped_ptr<FileTracker> app_root_tracker =
255      test_util::CreateTracker(*app_root_metadata, kAppRootTrackerID2,
256                               &sync_root_tracker);
257  app_root_tracker->set_app_id("app_id_2");
258  app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
259
260  index()->StoreFileTracker(app_root_tracker.Pass(), batch.get());
261  WriteToDB(batch.Pass());
262  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
263  EXPECT_EQ(kAppRootTrackerID2, index()->GetAppRootTracker("app_id_2"));
264
265  // Testing UpdateInAppIDIndex
266  batch.reset(new leveldb::WriteBatch);
267  app_root_tracker = test_util::CreateTracker(*app_root_metadata,
268                                              kAppRootTrackerID2,
269                                              &sync_root_tracker);
270  app_root_tracker->set_app_id("app_id_3");
271  app_root_tracker->set_active(false);
272
273  index()->StoreFileTracker(app_root_tracker.Pass(), batch.get());
274  WriteToDB(batch.Pass());
275  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
276  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_2"));
277  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_3"));
278
279  batch.reset(new leveldb::WriteBatch);
280  app_root_tracker = test_util::CreateTracker(*app_root_metadata,
281                                              kAppRootTrackerID2,
282                                              &sync_root_tracker);
283  app_root_tracker->set_app_id("app_id_3");
284  app_root_tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
285
286  index()->StoreFileTracker(app_root_tracker.Pass(), batch.get());
287  WriteToDB(batch.Pass());
288  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
289  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_2"));
290  EXPECT_EQ(kAppRootTrackerID2, index()->GetAppRootTracker("app_id_3"));
291
292  // Testing RemoveFromAppIDIndex
293  batch.reset(new leveldb::WriteBatch);
294  index()->RemoveFileTracker(kAppRootTrackerID2, batch.get());
295  WriteToDB(batch.Pass());
296  EXPECT_EQ(kAppRootTrackerID, index()->GetAppRootTracker("app_id"));
297  EXPECT_EQ(kInvalidTrackerID, index()->GetAppRootTracker("app_id_3"));
298}
299
300TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetByFileIDTest) {
301  CreateTestDatabase(true);
302
303  FileTracker app_root_tracker;
304  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root_tracker));
305  FileMetadata metadata;
306  EXPECT_TRUE(index()->GetFileMetadata("file_id", &metadata));
307
308  // Testing GetFileTrackerIDsByFileID
309  TrackerIDSet tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
310  EXPECT_EQ(1U, tracker_ids.size());
311  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
312
313  const int64 tracker_id = 21;
314  // Testing AddToFileIDIndexes
315  scoped_ptr<FileTracker> file_tracker =
316      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
317
318  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
319  index()->StoreFileTracker(file_tracker.Pass(), batch.get());
320  WriteToDB(batch.Pass());
321  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
322  EXPECT_EQ(2U, tracker_ids.size());
323  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
324
325  std::string multi_file_id = index()->PickMultiTrackerFileID();
326  EXPECT_EQ("file_id", multi_file_id);
327
328  // Testing UpdateInFileIDIndexes
329  batch.reset(new leveldb::WriteBatch);
330  file_tracker =
331      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
332  file_tracker->set_active(false);
333
334  index()->StoreFileTracker(file_tracker.Pass(), batch.get());
335  WriteToDB(batch.Pass());
336  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
337  EXPECT_EQ(2U, tracker_ids.size());
338  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
339
340  multi_file_id = index()->PickMultiTrackerFileID();
341  EXPECT_EQ("file_id", multi_file_id);
342
343  batch.reset(new leveldb::WriteBatch);
344  file_tracker =
345      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
346
347  index()->StoreFileTracker(file_tracker.Pass(), batch.get());
348  WriteToDB(batch.Pass());
349  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
350  EXPECT_EQ(2U, tracker_ids.size());
351  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
352
353  multi_file_id = index()->PickMultiTrackerFileID();
354  EXPECT_EQ("file_id", multi_file_id);
355
356  // Testing RemoveFromFileIDIndexes
357  batch.reset(new leveldb::WriteBatch);
358  index()->RemoveFileTracker(tracker_id, batch.get());
359  WriteToDB(batch.Pass());
360  tracker_ids = index()->GetFileTrackerIDsByFileID("file_id");
361  EXPECT_EQ(1U, tracker_ids.size());
362  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
363
364  multi_file_id = index()->PickMultiTrackerFileID();
365  EXPECT_TRUE(multi_file_id.empty()) << multi_file_id;
366}
367
368TEST_F(MetadataDatabaseIndexOnDiskTest, TrackerIDSetByParentIDAndTitleTest) {
369  CreateTestDatabase(true);
370
371  FileTracker app_root_tracker;
372  EXPECT_TRUE(index()->GetFileTracker(kAppRootTrackerID, &app_root_tracker));
373  FileMetadata metadata;
374  EXPECT_TRUE(index()->GetFileMetadata("file_id", &metadata));
375
376  // Testing GetFileTrackerIDsByFileID
377  TrackerIDSet tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
378      kAppRootTrackerID, "file");
379  EXPECT_EQ(1U, tracker_ids.size());
380  EXPECT_EQ(kFileTrackerID, tracker_ids.active_tracker());
381
382  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
383      kAppRootTrackerID, "file2");
384  EXPECT_TRUE(tracker_ids.empty());
385
386  const int64 tracker_id = 72;
387  // Testing AddToFileIDIndexes
388  scoped_ptr<FileTracker> file_tracker =
389      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
390
391  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
392  index()->StoreFileTracker(file_tracker.Pass(), batch.get());
393  WriteToDB(batch.Pass());
394  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
395      kAppRootTrackerID, "file");
396  EXPECT_EQ(2U, tracker_ids.size());
397  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
398
399  ParentIDAndTitle multi_backing = index()->PickMultiBackingFilePath();
400  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
401  EXPECT_EQ("file", multi_backing.title);
402
403  // Testing UpdateInFileIDIndexes
404  batch.reset(new leveldb::WriteBatch);
405  file_tracker =
406      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
407  file_tracker->set_active(false);
408
409  index()->StoreFileTracker(file_tracker.Pass(), batch.get());
410  WriteToDB(batch.Pass());
411  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
412      kAppRootTrackerID, "file");
413  EXPECT_EQ(2U, tracker_ids.size());
414  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
415
416  multi_backing = index()->PickMultiBackingFilePath();
417  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
418  EXPECT_EQ("file", multi_backing.title);
419
420  batch.reset(new leveldb::WriteBatch);
421  file_tracker =
422      test_util::CreateTracker(metadata, tracker_id, &app_root_tracker);
423
424  index()->StoreFileTracker(file_tracker.Pass(), batch.get());
425  WriteToDB(batch.Pass());
426  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
427      kAppRootTrackerID, "file");
428  EXPECT_EQ(2U, tracker_ids.size());
429  EXPECT_EQ(tracker_id, tracker_ids.active_tracker());
430
431  multi_backing = index()->PickMultiBackingFilePath();
432  EXPECT_EQ(kAppRootTrackerID, multi_backing.parent_id);
433  EXPECT_EQ("file", multi_backing.title);
434
435  // Testing RemoveFromFileIDIndexes
436  batch.reset(new leveldb::WriteBatch);
437  index()->RemoveFileTracker(tracker_id, batch.get());
438  WriteToDB(batch.Pass());
439  tracker_ids = index()->GetFileTrackerIDsByParentAndTitle(
440      kAppRootTrackerID, "file");
441  EXPECT_EQ(1U, tracker_ids.size());
442  EXPECT_EQ(kInvalidTrackerID, tracker_ids.active_tracker());
443
444  multi_backing = index()->PickMultiBackingFilePath();
445  EXPECT_EQ(kInvalidTrackerID, multi_backing.parent_id);
446  EXPECT_TRUE(multi_backing.title.empty()) << multi_backing.title;
447}
448
449TEST_F(MetadataDatabaseIndexOnDiskTest, DirtyTrackersTest) {
450  CreateTestDatabase(true);
451
452  scoped_ptr<leveldb::WriteBatch> batch;
453  // Testing public methods
454  EXPECT_EQ(1U, index()->CountDirtyTracker());
455  EXPECT_FALSE(index()->HasDemotedDirtyTracker());
456  EXPECT_EQ(kPlaceholderTrackerID, index()->PickDirtyTracker());
457  batch.reset(new leveldb::WriteBatch);
458  index()->DemoteDirtyTracker(kPlaceholderTrackerID, batch.get());
459  WriteToDB(batch.Pass());
460  EXPECT_TRUE(index()->HasDemotedDirtyTracker());
461  EXPECT_EQ(1U, index()->CountDirtyTracker());
462
463  const int64 tracker_id = 13;
464  scoped_ptr<FileTracker> app_root_tracker(new FileTracker);
465  index()->GetFileTracker(kAppRootTrackerID, app_root_tracker.get());
466
467  // Testing AddDirtyTrackerIndexes
468  scoped_ptr<FileTracker> tracker =
469      test_util::CreatePlaceholderTracker("placeholder",
470                                          tracker_id,
471                                          app_root_tracker.get());
472  batch.reset(new leveldb::WriteBatch);
473  index()->StoreFileTracker(tracker.Pass(), batch.get());
474  WriteToDB(batch.Pass());
475  EXPECT_EQ(2U, index()->CountDirtyTracker());
476  EXPECT_EQ(tracker_id, index()->PickDirtyTracker());
477
478  // Testing UpdateDirtyTrackerIndexes
479  tracker = test_util::CreatePlaceholderTracker("placeholder",
480                                                tracker_id,
481                                                app_root_tracker.get());
482  tracker->set_dirty(false);
483  batch.reset(new leveldb::WriteBatch);
484  index()->StoreFileTracker(tracker.Pass(), batch.get());
485  WriteToDB(batch.Pass());
486  EXPECT_EQ(1U, index()->CountDirtyTracker());
487  EXPECT_EQ(kInvalidTrackerID, index()->PickDirtyTracker());
488
489  tracker = test_util::CreatePlaceholderTracker("placeholder",
490                                                tracker_id,
491                                                app_root_tracker.get());
492  batch.reset(new leveldb::WriteBatch);
493  index()->StoreFileTracker(tracker.Pass(), batch.get());
494  WriteToDB(batch.Pass());
495  EXPECT_EQ(2U, index()->CountDirtyTracker());
496  EXPECT_EQ(tracker_id, index()->PickDirtyTracker());
497
498  // Testing RemoveFromDirtyTrackerIndexes
499  batch.reset(new leveldb::WriteBatch);
500  index()->RemoveFileTracker(tracker_id, batch.get());
501  WriteToDB(batch.Pass());
502  EXPECT_EQ(1U, index()->CountDirtyTracker());
503  EXPECT_EQ(kInvalidTrackerID, index()->PickDirtyTracker());
504}
505
506}  // namespace drive_backend
507}  // namespace sync_file_system
508