Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / resource_metadata_storage_unittest.cc
blobae80e464c22b0b26f02a1f98724182c7d71ec2e1
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/chromeos/drive/resource_metadata_storage.h"
7 #include <algorithm>
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/strings/string_split.h"
12 #include "chrome/browser/chromeos/drive/drive.pb.h"
13 #include "chrome/browser/chromeos/drive/test_util.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/leveldatabase/src/include/leveldb/db.h"
17 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
19 namespace drive {
20 namespace internal {
22 class ResourceMetadataStorageTest : public testing::Test {
23 protected:
24 void SetUp() override {
25 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
27 storage_.reset(new ResourceMetadataStorage(
28 temp_dir_.path(), base::MessageLoopProxy::current().get()));
29 ASSERT_TRUE(storage_->Initialize());
32 // Overwrites |storage_|'s version.
33 void SetDBVersion(int version) {
34 ResourceMetadataHeader header;
35 ASSERT_EQ(FILE_ERROR_OK, storage_->GetHeader(&header));
36 header.set_version(version);
37 EXPECT_EQ(FILE_ERROR_OK, storage_->PutHeader(header));
40 bool CheckValidity() {
41 return storage_->CheckValidity();
44 leveldb::DB* resource_map() { return storage_->resource_map_.get(); }
46 // Puts a child entry.
47 void PutChild(const std::string& parent_id,
48 const std::string& child_base_name,
49 const std::string& child_id) {
50 storage_->resource_map_->Put(
51 leveldb::WriteOptions(),
52 ResourceMetadataStorage::GetChildEntryKey(parent_id, child_base_name),
53 child_id);
56 // Removes a child entry.
57 void RemoveChild(const std::string& parent_id,
58 const std::string& child_base_name) {
59 storage_->resource_map_->Delete(
60 leveldb::WriteOptions(),
61 ResourceMetadataStorage::GetChildEntryKey(parent_id, child_base_name));
64 content::TestBrowserThreadBundle thread_bundle_;
65 base::ScopedTempDir temp_dir_;
66 scoped_ptr<ResourceMetadataStorage,
67 test_util::DestroyHelperForTests> storage_;
70 TEST_F(ResourceMetadataStorageTest, LargestChangestamp) {
71 const int64 kLargestChangestamp = 1234567890;
72 EXPECT_EQ(FILE_ERROR_OK,
73 storage_->SetLargestChangestamp(kLargestChangestamp));
74 int64 value = 0;
75 EXPECT_EQ(FILE_ERROR_OK, storage_->GetLargestChangestamp(&value));
76 EXPECT_EQ(kLargestChangestamp, value);
79 TEST_F(ResourceMetadataStorageTest, PutEntry) {
80 const std::string key1 = "abcdefg";
81 const std::string key2 = "abcd";
82 const std::string key3 = "efgh";
83 const std::string name2 = "ABCD";
84 const std::string name3 = "EFGH";
86 // key1 not found.
87 ResourceEntry result;
88 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &result));
90 // Put entry1.
91 ResourceEntry entry1;
92 entry1.set_local_id(key1);
93 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1));
95 // key1 found.
96 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(key1, &result));
98 // key2 not found.
99 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key2, &result));
101 // Put entry2 as a child of entry1.
102 ResourceEntry entry2;
103 entry2.set_local_id(key2);
104 entry2.set_parent_local_id(key1);
105 entry2.set_base_name(name2);
106 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2));
108 // key2 found.
109 std::string child_id;
110 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(key2, &result));
111 EXPECT_EQ(FILE_ERROR_OK, storage_->GetChild(key1, name2, &child_id));
112 EXPECT_EQ(key2, child_id);
114 // Put entry3 as a child of entry2.
115 ResourceEntry entry3;
116 entry3.set_local_id(key3);
117 entry3.set_parent_local_id(key2);
118 entry3.set_base_name(name3);
119 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry3));
121 // key3 found.
122 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(key3, &result));
123 EXPECT_EQ(FILE_ERROR_OK, storage_->GetChild(key2, name3, &child_id));
124 EXPECT_EQ(key3, child_id);
126 // Change entry3's parent to entry1.
127 entry3.set_parent_local_id(key1);
128 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry3));
130 // entry3 is a child of entry1 now.
131 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetChild(key2, name3, &child_id));
132 EXPECT_EQ(FILE_ERROR_OK, storage_->GetChild(key1, name3, &child_id));
133 EXPECT_EQ(key3, child_id);
135 // Remove entries.
136 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key3));
137 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key3, &result));
138 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key2));
139 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key2, &result));
140 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key1));
141 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &result));
144 TEST_F(ResourceMetadataStorageTest, Iterator) {
145 // Prepare data.
146 std::vector<std::string> keys;
148 keys.push_back("entry1");
149 keys.push_back("entry2");
150 keys.push_back("entry3");
151 keys.push_back("entry4");
153 for (size_t i = 0; i < keys.size(); ++i) {
154 ResourceEntry entry;
155 entry.set_local_id(keys[i]);
156 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
159 // Iterate and check the result.
160 std::map<std::string, ResourceEntry> found_entries;
161 scoped_ptr<ResourceMetadataStorage::Iterator> it = storage_->GetIterator();
162 ASSERT_TRUE(it);
163 for (; !it->IsAtEnd(); it->Advance()) {
164 const ResourceEntry& entry = it->GetValue();
165 found_entries[it->GetID()] = entry;
167 EXPECT_FALSE(it->HasError());
169 EXPECT_EQ(keys.size(), found_entries.size());
170 for (size_t i = 0; i < keys.size(); ++i)
171 EXPECT_EQ(1U, found_entries.count(keys[i]));
174 TEST_F(ResourceMetadataStorageTest, GetIdByResourceId) {
175 const std::string local_id = "local_id";
176 const std::string resource_id = "resource_id";
178 // Resource ID to local ID mapping is not stored yet.
179 std::string id;
180 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
181 storage_->GetIdByResourceId(resource_id, &id));
183 // Put an entry with the resource ID.
184 ResourceEntry entry;
185 entry.set_local_id(local_id);
186 entry.set_resource_id(resource_id);
187 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
189 // Can get local ID by resource ID.
190 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id));
191 EXPECT_EQ(local_id, id);
193 // Resource ID to local ID mapping is removed.
194 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(local_id));
195 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
196 storage_->GetIdByResourceId(resource_id, &id));
199 TEST_F(ResourceMetadataStorageTest, GetChildren) {
200 const std::string parents_id[] = { "mercury", "venus", "mars", "jupiter",
201 "saturn" };
202 std::vector<base::StringPairs> children_name_id(arraysize(parents_id));
203 // Skip children_name_id[0/1] here because Mercury and Venus have no moon.
204 children_name_id[2].push_back(std::make_pair("phobos", "mars_i"));
205 children_name_id[2].push_back(std::make_pair("deimos", "mars_ii"));
206 children_name_id[3].push_back(std::make_pair("io", "jupiter_i"));
207 children_name_id[3].push_back(std::make_pair("europa", "jupiter_ii"));
208 children_name_id[3].push_back(std::make_pair("ganymede", "jupiter_iii"));
209 children_name_id[3].push_back(std::make_pair("calisto", "jupiter_iv"));
210 children_name_id[4].push_back(std::make_pair("mimas", "saturn_i"));
211 children_name_id[4].push_back(std::make_pair("enceladus", "saturn_ii"));
212 children_name_id[4].push_back(std::make_pair("tethys", "saturn_iii"));
213 children_name_id[4].push_back(std::make_pair("dione", "saturn_iv"));
214 children_name_id[4].push_back(std::make_pair("rhea", "saturn_v"));
215 children_name_id[4].push_back(std::make_pair("titan", "saturn_vi"));
216 children_name_id[4].push_back(std::make_pair("iapetus", "saturn_vii"));
218 // Put parents.
219 for (size_t i = 0; i < arraysize(parents_id); ++i) {
220 ResourceEntry entry;
221 entry.set_local_id(parents_id[i]);
222 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
225 // Put children.
226 for (size_t i = 0; i < children_name_id.size(); ++i) {
227 for (size_t j = 0; j < children_name_id[i].size(); ++j) {
228 ResourceEntry entry;
229 entry.set_local_id(children_name_id[i][j].second);
230 entry.set_parent_local_id(parents_id[i]);
231 entry.set_base_name(children_name_id[i][j].first);
232 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
236 // Try to get children.
237 for (size_t i = 0; i < children_name_id.size(); ++i) {
238 std::vector<std::string> children;
239 storage_->GetChildren(parents_id[i], &children);
240 EXPECT_EQ(children_name_id[i].size(), children.size());
241 for (size_t j = 0; j < children_name_id[i].size(); ++j) {
242 EXPECT_EQ(1, std::count(children.begin(),
243 children.end(),
244 children_name_id[i][j].second));
249 TEST_F(ResourceMetadataStorageTest, OpenExistingDB) {
250 const std::string parent_id1 = "abcdefg";
251 const std::string child_name1 = "WXYZABC";
252 const std::string child_id1 = "qwerty";
254 ResourceEntry entry1;
255 entry1.set_local_id(parent_id1);
256 ResourceEntry entry2;
257 entry2.set_local_id(child_id1);
258 entry2.set_parent_local_id(parent_id1);
259 entry2.set_base_name(child_name1);
261 // Put some data.
262 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1));
263 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2));
265 // Close DB and reopen.
266 storage_.reset(new ResourceMetadataStorage(
267 temp_dir_.path(), base::MessageLoopProxy::current().get()));
268 ASSERT_TRUE(storage_->Initialize());
270 // Can read data.
271 ResourceEntry result;
272 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(parent_id1, &result));
274 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(child_id1, &result));
275 EXPECT_EQ(parent_id1, result.parent_local_id());
276 EXPECT_EQ(child_name1, result.base_name());
278 std::string child_id;
279 EXPECT_EQ(FILE_ERROR_OK,
280 storage_->GetChild(parent_id1, child_name1, &child_id));
281 EXPECT_EQ(child_id1, child_id);
284 TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M29) {
285 const int64 kLargestChangestamp = 1234567890;
286 const std::string title = "title";
288 // Construct M29 version DB.
289 SetDBVersion(6);
290 EXPECT_EQ(FILE_ERROR_OK,
291 storage_->SetLargestChangestamp(kLargestChangestamp));
293 leveldb::WriteBatch batch;
295 // Put a file entry and its cache entry.
296 ResourceEntry entry;
297 std::string serialized_entry;
298 entry.set_title(title);
299 entry.set_resource_id("file:abcd");
300 EXPECT_TRUE(entry.SerializeToString(&serialized_entry));
301 batch.Put("file:abcd", serialized_entry);
303 FileCacheEntry cache_entry;
304 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry));
305 batch.Put(std::string("file:abcd") + '\0' + "CACHE", serialized_entry);
307 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok());
309 // Upgrade and reopen.
310 storage_.reset();
311 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path()));
312 storage_.reset(new ResourceMetadataStorage(
313 temp_dir_.path(), base::MessageLoopProxy::current().get()));
314 ASSERT_TRUE(storage_->Initialize());
316 // Resource-ID-to-local-ID mapping is added.
317 std::string id;
318 EXPECT_EQ(FILE_ERROR_OK,
319 storage_->GetIdByResourceId("abcd", &id)); // "file:" is dropped.
321 // Data is erased, except cache entries.
322 int64 largest_changestamp = 0;
323 EXPECT_EQ(FILE_ERROR_OK,
324 storage_->GetLargestChangestamp(&largest_changestamp));
325 EXPECT_EQ(0, largest_changestamp);
326 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry));
327 EXPECT_TRUE(entry.title().empty());
328 EXPECT_TRUE(entry.file_specific_info().has_cache_state());
331 TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M32) {
332 const int64 kLargestChangestamp = 1234567890;
333 const std::string title = "title";
334 const std::string resource_id = "abcd";
335 const std::string local_id = "local-abcd";
337 // Construct M32 version DB.
338 SetDBVersion(11);
339 EXPECT_EQ(FILE_ERROR_OK,
340 storage_->SetLargestChangestamp(kLargestChangestamp));
342 leveldb::WriteBatch batch;
344 // Put a file entry and its cache and id entry.
345 ResourceEntry entry;
346 std::string serialized_entry;
347 entry.set_title(title);
348 entry.set_local_id(local_id);
349 entry.set_resource_id(resource_id);
350 EXPECT_TRUE(entry.SerializeToString(&serialized_entry));
351 batch.Put(local_id, serialized_entry);
353 FileCacheEntry cache_entry;
354 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry));
355 batch.Put(local_id + '\0' + "CACHE", serialized_entry);
357 batch.Put('\0' + std::string("ID") + '\0' + resource_id, local_id);
359 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok());
361 // Upgrade and reopen.
362 storage_.reset();
363 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path()));
364 storage_.reset(new ResourceMetadataStorage(
365 temp_dir_.path(), base::MessageLoopProxy::current().get()));
366 ASSERT_TRUE(storage_->Initialize());
368 // Data is erased, except cache and id mapping entries.
369 std::string id;
370 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id));
371 EXPECT_EQ(local_id, id);
372 int64 largest_changestamp = 0;
373 EXPECT_EQ(FILE_ERROR_OK,
374 storage_->GetLargestChangestamp(&largest_changestamp));
375 EXPECT_EQ(0, largest_changestamp);
376 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry));
377 EXPECT_TRUE(entry.title().empty());
378 EXPECT_TRUE(entry.file_specific_info().has_cache_state());
381 TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M33) {
382 const int64 kLargestChangestamp = 1234567890;
383 const std::string title = "title";
384 const std::string resource_id = "abcd";
385 const std::string local_id = "local-abcd";
386 const std::string md5 = "md5";
387 const std::string resource_id2 = "efgh";
388 const std::string local_id2 = "local-efgh";
389 const std::string md5_2 = "md5_2";
391 // Construct M33 version DB.
392 SetDBVersion(12);
393 EXPECT_EQ(FILE_ERROR_OK,
394 storage_->SetLargestChangestamp(kLargestChangestamp));
396 leveldb::WriteBatch batch;
398 // Put a file entry and its cache and id entry.
399 ResourceEntry entry;
400 std::string serialized_entry;
401 entry.set_title(title);
402 entry.set_local_id(local_id);
403 entry.set_resource_id(resource_id);
404 EXPECT_TRUE(entry.SerializeToString(&serialized_entry));
405 batch.Put(local_id, serialized_entry);
407 FileCacheEntry cache_entry;
408 cache_entry.set_md5(md5);
409 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry));
410 batch.Put(local_id + '\0' + "CACHE", serialized_entry);
412 batch.Put('\0' + std::string("ID") + '\0' + resource_id, local_id);
414 // Put another cache entry which is not accompanied by a ResourceEntry.
415 cache_entry.set_md5(md5_2);
416 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry));
417 batch.Put(local_id2 + '\0' + "CACHE", serialized_entry);
418 batch.Put('\0' + std::string("ID") + '\0' + resource_id2, local_id2);
420 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok());
422 // Upgrade and reopen.
423 storage_.reset();
424 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path()));
425 storage_.reset(new ResourceMetadataStorage(
426 temp_dir_.path(), base::MessageLoopProxy::current().get()));
427 ASSERT_TRUE(storage_->Initialize());
429 // No data is lost.
430 int64 largest_changestamp = 0;
431 EXPECT_EQ(FILE_ERROR_OK,
432 storage_->GetLargestChangestamp(&largest_changestamp));
433 EXPECT_EQ(kLargestChangestamp, largest_changestamp);
435 std::string id;
436 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id));
437 EXPECT_EQ(local_id, id);
438 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry));
439 EXPECT_EQ(title, entry.title());
440 EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5());
442 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id2, &id));
443 EXPECT_EQ(local_id2, id);
444 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry));
445 EXPECT_EQ(md5_2, entry.file_specific_info().cache_state().md5());
448 TEST_F(ResourceMetadataStorageTest, IncompatibleDB_Unknown) {
449 const int64 kLargestChangestamp = 1234567890;
450 const std::string key1 = "abcd";
452 // Put some data.
453 EXPECT_EQ(FILE_ERROR_OK,
454 storage_->SetLargestChangestamp(kLargestChangestamp));
455 ResourceEntry entry;
456 entry.set_local_id(key1);
457 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
459 // Set newer version, upgrade and reopen DB.
460 SetDBVersion(ResourceMetadataStorage::kDBVersion + 1);
461 storage_.reset();
462 EXPECT_FALSE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path()));
463 storage_.reset(new ResourceMetadataStorage(
464 temp_dir_.path(), base::MessageLoopProxy::current().get()));
465 ASSERT_TRUE(storage_->Initialize());
467 // Data is erased because of the incompatible version.
468 int64 largest_changestamp = 0;
469 EXPECT_EQ(FILE_ERROR_OK,
470 storage_->GetLargestChangestamp(&largest_changestamp));
471 EXPECT_EQ(0, largest_changestamp);
472 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &entry));
475 TEST_F(ResourceMetadataStorageTest, DeleteUnusedIDEntries) {
476 leveldb::WriteBatch batch;
478 // Put an ID entry with a corresponding ResourceEntry.
479 ResourceEntry entry;
480 entry.set_local_id("id1");
481 entry.set_resource_id("resource_id1");
483 std::string serialized_entry;
484 EXPECT_TRUE(entry.SerializeToString(&serialized_entry));
485 batch.Put("id1", serialized_entry);
486 batch.Put('\0' + std::string("ID") + '\0' + "resource_id1", "id1");
488 // Put an ID entry without any corresponding entries.
489 batch.Put('\0' + std::string("ID") + '\0' + "resource_id2", "id3");
491 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok());
493 // Upgrade and reopen.
494 storage_.reset();
495 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path()));
496 storage_.reset(new ResourceMetadataStorage(
497 temp_dir_.path(), base::MessageLoopProxy::current().get()));
498 ASSERT_TRUE(storage_->Initialize());
500 // Only the unused entry is deleted.
501 std::string id;
502 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId("resource_id1", &id));
503 EXPECT_EQ("id1", id);
504 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
505 storage_->GetIdByResourceId("resource_id2", &id));
508 TEST_F(ResourceMetadataStorageTest, WrongPath) {
509 // Create a file.
510 base::FilePath path;
511 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &path));
513 storage_.reset(new ResourceMetadataStorage(
514 path, base::MessageLoopProxy::current().get()));
515 // Cannot initialize DB beacause the path does not point a directory.
516 ASSERT_FALSE(storage_->Initialize());
519 TEST_F(ResourceMetadataStorageTest, RecoverCacheEntriesFromTrashedResourceMap) {
520 // Put entry with id_foo.
521 ResourceEntry entry;
522 entry.set_local_id("id_foo");
523 entry.set_base_name("foo");
524 entry.set_title("foo");
525 entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_foo");
526 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
528 // Put entry with id_bar as a id_foo's child.
529 entry.set_local_id("id_bar");
530 entry.set_parent_local_id("id_foo");
531 entry.set_base_name("bar");
532 entry.set_title("bar");
533 entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_bar");
534 entry.mutable_file_specific_info()->mutable_cache_state()->set_is_dirty(true);
535 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
537 // Remove parent-child relationship to make the DB invalid.
538 RemoveChild("id_foo", "bar");
539 EXPECT_FALSE(CheckValidity());
541 // Reopen. This should result in trashing the DB.
542 storage_.reset(new ResourceMetadataStorage(
543 temp_dir_.path(), base::MessageLoopProxy::current().get()));
544 ASSERT_TRUE(storage_->Initialize());
546 // Recover cache entries from the trashed DB.
547 ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info;
548 storage_->RecoverCacheInfoFromTrashedResourceMap(&recovered_cache_info);
549 EXPECT_EQ(2U, recovered_cache_info.size());
550 EXPECT_FALSE(recovered_cache_info["id_foo"].is_dirty);
551 EXPECT_EQ("md5_foo", recovered_cache_info["id_foo"].md5);
552 EXPECT_EQ("foo", recovered_cache_info["id_foo"].title);
553 EXPECT_TRUE(recovered_cache_info["id_bar"].is_dirty);
554 EXPECT_EQ("md5_bar", recovered_cache_info["id_bar"].md5);
555 EXPECT_EQ("bar", recovered_cache_info["id_bar"].title);
558 TEST_F(ResourceMetadataStorageTest, CheckValidity) {
559 const std::string key1 = "foo";
560 const std::string name1 = "hoge";
561 const std::string key2 = "bar";
562 const std::string name2 = "fuga";
563 const std::string key3 = "boo";
564 const std::string name3 = "piyo";
566 // Empty storage is valid.
567 EXPECT_TRUE(CheckValidity());
569 // Put entry with key1.
570 ResourceEntry entry;
571 entry.set_local_id(key1);
572 entry.set_base_name(name1);
573 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
574 EXPECT_TRUE(CheckValidity());
576 // Put entry with key2 under key1.
577 entry.set_local_id(key2);
578 entry.set_parent_local_id(key1);
579 entry.set_base_name(name2);
580 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
581 EXPECT_TRUE(CheckValidity());
583 RemoveChild(key1, name2);
584 EXPECT_FALSE(CheckValidity()); // Missing parent-child relationship.
586 // Add back parent-child relationship between key1 and key2.
587 PutChild(key1, name2, key2);
588 EXPECT_TRUE(CheckValidity());
590 // Add parent-child relationship between key2 and key3.
591 PutChild(key2, name3, key3);
592 EXPECT_FALSE(CheckValidity()); // key3 is not stored in the storage.
594 // Put entry with key3 under key2.
595 entry.set_local_id(key3);
596 entry.set_parent_local_id(key2);
597 entry.set_base_name(name3);
598 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
599 EXPECT_TRUE(CheckValidity());
601 // Parent-child relationship with wrong name.
602 RemoveChild(key2, name3);
603 EXPECT_FALSE(CheckValidity());
604 PutChild(key2, name2, key3);
605 EXPECT_FALSE(CheckValidity());
607 // Fix up the relationship between key2 and key3.
608 RemoveChild(key2, name2);
609 EXPECT_FALSE(CheckValidity());
610 PutChild(key2, name3, key3);
611 EXPECT_TRUE(CheckValidity());
613 // Remove key2.
614 RemoveChild(key1, name2);
615 EXPECT_FALSE(CheckValidity());
616 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key2));
617 EXPECT_FALSE(CheckValidity());
619 // Remove key3.
620 RemoveChild(key2, name3);
621 EXPECT_FALSE(CheckValidity());
622 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key3));
623 EXPECT_TRUE(CheckValidity());
625 // Remove key1.
626 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key1));
627 EXPECT_TRUE(CheckValidity());
630 } // namespace internal
631 } // namespace drive