OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h" | 5 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
| 11 #include "base/single_thread_task_runner.h" |
11 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 13 #include "base/thread_task_runner_handle.h" |
12 #include "chrome/browser/chromeos/drive/drive.pb.h" | 14 #include "chrome/browser/chromeos/drive/drive.pb.h" |
13 #include "chrome/browser/chromeos/drive/test_util.h" | 15 #include "chrome/browser/chromeos/drive/test_util.h" |
14 #include "content/public/test/test_browser_thread_bundle.h" | 16 #include "content/public/test/test_browser_thread_bundle.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 18 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
17 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 19 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
18 | 20 |
19 namespace drive { | 21 namespace drive { |
20 namespace internal { | 22 namespace internal { |
21 | 23 |
22 class ResourceMetadataStorageTest : public testing::Test { | 24 class ResourceMetadataStorageTest : public testing::Test { |
23 protected: | 25 protected: |
24 void SetUp() override { | 26 void SetUp() override { |
25 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 27 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
26 | 28 |
27 storage_.reset(new ResourceMetadataStorage( | 29 storage_.reset(new ResourceMetadataStorage( |
28 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 30 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
29 ASSERT_TRUE(storage_->Initialize()); | 31 ASSERT_TRUE(storage_->Initialize()); |
30 } | 32 } |
31 | 33 |
32 // Overwrites |storage_|'s version. | 34 // Overwrites |storage_|'s version. |
33 void SetDBVersion(int version) { | 35 void SetDBVersion(int version) { |
34 ResourceMetadataHeader header; | 36 ResourceMetadataHeader header; |
35 ASSERT_EQ(FILE_ERROR_OK, storage_->GetHeader(&header)); | 37 ASSERT_EQ(FILE_ERROR_OK, storage_->GetHeader(&header)); |
36 header.set_version(version); | 38 header.set_version(version); |
37 EXPECT_EQ(FILE_ERROR_OK, storage_->PutHeader(header)); | 39 EXPECT_EQ(FILE_ERROR_OK, storage_->PutHeader(header)); |
38 } | 40 } |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 entry2.set_local_id(child_id1); | 259 entry2.set_local_id(child_id1); |
258 entry2.set_parent_local_id(parent_id1); | 260 entry2.set_parent_local_id(parent_id1); |
259 entry2.set_base_name(child_name1); | 261 entry2.set_base_name(child_name1); |
260 | 262 |
261 // Put some data. | 263 // Put some data. |
262 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1)); | 264 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1)); |
263 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2)); | 265 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2)); |
264 | 266 |
265 // Close DB and reopen. | 267 // Close DB and reopen. |
266 storage_.reset(new ResourceMetadataStorage( | 268 storage_.reset(new ResourceMetadataStorage( |
267 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 269 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
268 ASSERT_TRUE(storage_->Initialize()); | 270 ASSERT_TRUE(storage_->Initialize()); |
269 | 271 |
270 // Can read data. | 272 // Can read data. |
271 ResourceEntry result; | 273 ResourceEntry result; |
272 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(parent_id1, &result)); | 274 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(parent_id1, &result)); |
273 | 275 |
274 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(child_id1, &result)); | 276 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(child_id1, &result)); |
275 EXPECT_EQ(parent_id1, result.parent_local_id()); | 277 EXPECT_EQ(parent_id1, result.parent_local_id()); |
276 EXPECT_EQ(child_name1, result.base_name()); | 278 EXPECT_EQ(child_name1, result.base_name()); |
277 | 279 |
(...skipping 25 matching lines...) Expand all Loading... |
303 FileCacheEntry cache_entry; | 305 FileCacheEntry cache_entry; |
304 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); | 306 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); |
305 batch.Put(std::string("file:abcd") + '\0' + "CACHE", serialized_entry); | 307 batch.Put(std::string("file:abcd") + '\0' + "CACHE", serialized_entry); |
306 | 308 |
307 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); | 309 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
308 | 310 |
309 // Upgrade and reopen. | 311 // Upgrade and reopen. |
310 storage_.reset(); | 312 storage_.reset(); |
311 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); | 313 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); |
312 storage_.reset(new ResourceMetadataStorage( | 314 storage_.reset(new ResourceMetadataStorage( |
313 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 315 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
314 ASSERT_TRUE(storage_->Initialize()); | 316 ASSERT_TRUE(storage_->Initialize()); |
315 | 317 |
316 // Resource-ID-to-local-ID mapping is added. | 318 // Resource-ID-to-local-ID mapping is added. |
317 std::string id; | 319 std::string id; |
318 EXPECT_EQ(FILE_ERROR_OK, | 320 EXPECT_EQ(FILE_ERROR_OK, |
319 storage_->GetIdByResourceId("abcd", &id)); // "file:" is dropped. | 321 storage_->GetIdByResourceId("abcd", &id)); // "file:" is dropped. |
320 | 322 |
321 // Data is erased, except cache entries. | 323 // Data is erased, except cache entries. |
322 int64 largest_changestamp = 0; | 324 int64 largest_changestamp = 0; |
323 EXPECT_EQ(FILE_ERROR_OK, | 325 EXPECT_EQ(FILE_ERROR_OK, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 batch.Put(local_id + '\0' + "CACHE", serialized_entry); | 357 batch.Put(local_id + '\0' + "CACHE", serialized_entry); |
356 | 358 |
357 batch.Put('\0' + std::string("ID") + '\0' + resource_id, local_id); | 359 batch.Put('\0' + std::string("ID") + '\0' + resource_id, local_id); |
358 | 360 |
359 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); | 361 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
360 | 362 |
361 // Upgrade and reopen. | 363 // Upgrade and reopen. |
362 storage_.reset(); | 364 storage_.reset(); |
363 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); | 365 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); |
364 storage_.reset(new ResourceMetadataStorage( | 366 storage_.reset(new ResourceMetadataStorage( |
365 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 367 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
366 ASSERT_TRUE(storage_->Initialize()); | 368 ASSERT_TRUE(storage_->Initialize()); |
367 | 369 |
368 // Data is erased, except cache and id mapping entries. | 370 // Data is erased, except cache and id mapping entries. |
369 std::string id; | 371 std::string id; |
370 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id)); | 372 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id)); |
371 EXPECT_EQ(local_id, id); | 373 EXPECT_EQ(local_id, id); |
372 int64 largest_changestamp = 0; | 374 int64 largest_changestamp = 0; |
373 EXPECT_EQ(FILE_ERROR_OK, | 375 EXPECT_EQ(FILE_ERROR_OK, |
374 storage_->GetLargestChangestamp(&largest_changestamp)); | 376 storage_->GetLargestChangestamp(&largest_changestamp)); |
375 EXPECT_EQ(0, largest_changestamp); | 377 EXPECT_EQ(0, largest_changestamp); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); | 418 EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); |
417 batch.Put(local_id2 + '\0' + "CACHE", serialized_entry); | 419 batch.Put(local_id2 + '\0' + "CACHE", serialized_entry); |
418 batch.Put('\0' + std::string("ID") + '\0' + resource_id2, local_id2); | 420 batch.Put('\0' + std::string("ID") + '\0' + resource_id2, local_id2); |
419 | 421 |
420 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); | 422 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
421 | 423 |
422 // Upgrade and reopen. | 424 // Upgrade and reopen. |
423 storage_.reset(); | 425 storage_.reset(); |
424 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); | 426 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); |
425 storage_.reset(new ResourceMetadataStorage( | 427 storage_.reset(new ResourceMetadataStorage( |
426 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 428 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
427 ASSERT_TRUE(storage_->Initialize()); | 429 ASSERT_TRUE(storage_->Initialize()); |
428 | 430 |
429 // No data is lost. | 431 // No data is lost. |
430 int64 largest_changestamp = 0; | 432 int64 largest_changestamp = 0; |
431 EXPECT_EQ(FILE_ERROR_OK, | 433 EXPECT_EQ(FILE_ERROR_OK, |
432 storage_->GetLargestChangestamp(&largest_changestamp)); | 434 storage_->GetLargestChangestamp(&largest_changestamp)); |
433 EXPECT_EQ(kLargestChangestamp, largest_changestamp); | 435 EXPECT_EQ(kLargestChangestamp, largest_changestamp); |
434 | 436 |
435 std::string id; | 437 std::string id; |
436 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id)); | 438 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id)); |
(...skipping 17 matching lines...) Expand all Loading... |
454 storage_->SetLargestChangestamp(kLargestChangestamp)); | 456 storage_->SetLargestChangestamp(kLargestChangestamp)); |
455 ResourceEntry entry; | 457 ResourceEntry entry; |
456 entry.set_local_id(key1); | 458 entry.set_local_id(key1); |
457 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); | 459 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
458 | 460 |
459 // Set newer version, upgrade and reopen DB. | 461 // Set newer version, upgrade and reopen DB. |
460 SetDBVersion(ResourceMetadataStorage::kDBVersion + 1); | 462 SetDBVersion(ResourceMetadataStorage::kDBVersion + 1); |
461 storage_.reset(); | 463 storage_.reset(); |
462 EXPECT_FALSE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); | 464 EXPECT_FALSE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); |
463 storage_.reset(new ResourceMetadataStorage( | 465 storage_.reset(new ResourceMetadataStorage( |
464 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 466 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
465 ASSERT_TRUE(storage_->Initialize()); | 467 ASSERT_TRUE(storage_->Initialize()); |
466 | 468 |
467 // Data is erased because of the incompatible version. | 469 // Data is erased because of the incompatible version. |
468 int64 largest_changestamp = 0; | 470 int64 largest_changestamp = 0; |
469 EXPECT_EQ(FILE_ERROR_OK, | 471 EXPECT_EQ(FILE_ERROR_OK, |
470 storage_->GetLargestChangestamp(&largest_changestamp)); | 472 storage_->GetLargestChangestamp(&largest_changestamp)); |
471 EXPECT_EQ(0, largest_changestamp); | 473 EXPECT_EQ(0, largest_changestamp); |
472 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &entry)); | 474 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &entry)); |
473 } | 475 } |
474 | 476 |
(...skipping 12 matching lines...) Expand all Loading... |
487 | 489 |
488 // Put an ID entry without any corresponding entries. | 490 // Put an ID entry without any corresponding entries. |
489 batch.Put('\0' + std::string("ID") + '\0' + "resource_id2", "id3"); | 491 batch.Put('\0' + std::string("ID") + '\0' + "resource_id2", "id3"); |
490 | 492 |
491 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); | 493 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
492 | 494 |
493 // Upgrade and reopen. | 495 // Upgrade and reopen. |
494 storage_.reset(); | 496 storage_.reset(); |
495 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); | 497 EXPECT_TRUE(ResourceMetadataStorage::UpgradeOldDB(temp_dir_.path())); |
496 storage_.reset(new ResourceMetadataStorage( | 498 storage_.reset(new ResourceMetadataStorage( |
497 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 499 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
498 ASSERT_TRUE(storage_->Initialize()); | 500 ASSERT_TRUE(storage_->Initialize()); |
499 | 501 |
500 // Only the unused entry is deleted. | 502 // Only the unused entry is deleted. |
501 std::string id; | 503 std::string id; |
502 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId("resource_id1", &id)); | 504 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId("resource_id1", &id)); |
503 EXPECT_EQ("id1", id); | 505 EXPECT_EQ("id1", id); |
504 EXPECT_EQ(FILE_ERROR_NOT_FOUND, | 506 EXPECT_EQ(FILE_ERROR_NOT_FOUND, |
505 storage_->GetIdByResourceId("resource_id2", &id)); | 507 storage_->GetIdByResourceId("resource_id2", &id)); |
506 } | 508 } |
507 | 509 |
508 TEST_F(ResourceMetadataStorageTest, WrongPath) { | 510 TEST_F(ResourceMetadataStorageTest, WrongPath) { |
509 // Create a file. | 511 // Create a file. |
510 base::FilePath path; | 512 base::FilePath path; |
511 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &path)); | 513 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &path)); |
512 | 514 |
513 storage_.reset(new ResourceMetadataStorage( | 515 storage_.reset(new ResourceMetadataStorage( |
514 path, base::MessageLoopProxy::current().get())); | 516 path, base::ThreadTaskRunnerHandle::Get().get())); |
515 // Cannot initialize DB beacause the path does not point a directory. | 517 // Cannot initialize DB beacause the path does not point a directory. |
516 ASSERT_FALSE(storage_->Initialize()); | 518 ASSERT_FALSE(storage_->Initialize()); |
517 } | 519 } |
518 | 520 |
519 TEST_F(ResourceMetadataStorageTest, RecoverCacheEntriesFromTrashedResourceMap) { | 521 TEST_F(ResourceMetadataStorageTest, RecoverCacheEntriesFromTrashedResourceMap) { |
520 // Put entry with id_foo. | 522 // Put entry with id_foo. |
521 ResourceEntry entry; | 523 ResourceEntry entry; |
522 entry.set_local_id("id_foo"); | 524 entry.set_local_id("id_foo"); |
523 entry.set_base_name("foo"); | 525 entry.set_base_name("foo"); |
524 entry.set_title("foo"); | 526 entry.set_title("foo"); |
525 entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_foo"); | 527 entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_foo"); |
526 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); | 528 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
527 | 529 |
528 // Put entry with id_bar as a id_foo's child. | 530 // Put entry with id_bar as a id_foo's child. |
529 entry.set_local_id("id_bar"); | 531 entry.set_local_id("id_bar"); |
530 entry.set_parent_local_id("id_foo"); | 532 entry.set_parent_local_id("id_foo"); |
531 entry.set_base_name("bar"); | 533 entry.set_base_name("bar"); |
532 entry.set_title("bar"); | 534 entry.set_title("bar"); |
533 entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_bar"); | 535 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); | 536 entry.mutable_file_specific_info()->mutable_cache_state()->set_is_dirty(true); |
535 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); | 537 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
536 | 538 |
537 // Remove parent-child relationship to make the DB invalid. | 539 // Remove parent-child relationship to make the DB invalid. |
538 RemoveChild("id_foo", "bar"); | 540 RemoveChild("id_foo", "bar"); |
539 EXPECT_FALSE(CheckValidity()); | 541 EXPECT_FALSE(CheckValidity()); |
540 | 542 |
541 // Reopen. This should result in trashing the DB. | 543 // Reopen. This should result in trashing the DB. |
542 storage_.reset(new ResourceMetadataStorage( | 544 storage_.reset(new ResourceMetadataStorage( |
543 temp_dir_.path(), base::MessageLoopProxy::current().get())); | 545 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |
544 ASSERT_TRUE(storage_->Initialize()); | 546 ASSERT_TRUE(storage_->Initialize()); |
545 | 547 |
546 // Recover cache entries from the trashed DB. | 548 // Recover cache entries from the trashed DB. |
547 ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info; | 549 ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info; |
548 storage_->RecoverCacheInfoFromTrashedResourceMap(&recovered_cache_info); | 550 storage_->RecoverCacheInfoFromTrashedResourceMap(&recovered_cache_info); |
549 EXPECT_EQ(2U, recovered_cache_info.size()); | 551 EXPECT_EQ(2U, recovered_cache_info.size()); |
550 EXPECT_FALSE(recovered_cache_info["id_foo"].is_dirty); | 552 EXPECT_FALSE(recovered_cache_info["id_foo"].is_dirty); |
551 EXPECT_EQ("md5_foo", recovered_cache_info["id_foo"].md5); | 553 EXPECT_EQ("md5_foo", recovered_cache_info["id_foo"].md5); |
552 EXPECT_EQ("foo", recovered_cache_info["id_foo"].title); | 554 EXPECT_EQ("foo", recovered_cache_info["id_foo"].title); |
553 EXPECT_TRUE(recovered_cache_info["id_bar"].is_dirty); | 555 EXPECT_TRUE(recovered_cache_info["id_bar"].is_dirty); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key3)); | 624 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key3)); |
623 EXPECT_TRUE(CheckValidity()); | 625 EXPECT_TRUE(CheckValidity()); |
624 | 626 |
625 // Remove key1. | 627 // Remove key1. |
626 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key1)); | 628 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key1)); |
627 EXPECT_TRUE(CheckValidity()); | 629 EXPECT_TRUE(CheckValidity()); |
628 } | 630 } |
629 | 631 |
630 } // namespace internal | 632 } // namespace internal |
631 } // namespace drive | 633 } // namespace drive |
OLD | NEW |