Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: components/offline_pages/offline_page_metadata_store_impl_unittest.cc

Issue 2007523003: Revert of delete the levelDB storage implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "components/offline_pages/offline_page_metadata_store.h" 5 #include "components/offline_pages/offline_page_metadata_store_impl.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h" 13 #include "base/files/scoped_temp_dir.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/test/test_simple_task_runner.h" 16 #include "base/test/test_simple_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h" 17 #include "base/threading/thread_task_runner_handle.h"
18 #include "components/leveldb_proto/proto_database_impl.h"
18 #include "components/offline_pages/offline_page_item.h" 19 #include "components/offline_pages/offline_page_item.h"
19 #include "components/offline_pages/offline_page_metadata_store_sql.h" 20 #include "components/offline_pages/offline_page_metadata_store_sql.h"
20 #include "components/offline_pages/offline_page_model.h" 21 #include "components/offline_pages/offline_page_model.h"
22 #include "components/offline_pages/proto/offline_pages.pb.h"
21 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
22 24
25 using leveldb_proto::ProtoDatabaseImpl;
26
23 namespace offline_pages { 27 namespace offline_pages {
24 28
25 namespace { 29 namespace {
26 30
27 const char kTestClientNamespace[] = "CLIENT_NAMESPACE"; 31 const char kTestClientNamespace[] = "CLIENT_NAMESPACE";
28 const char kTestURL[] = "https://example.com"; 32 const char kTestURL[] = "https://example.com";
29 const ClientId kTestClientId1(kTestClientNamespace, "1234"); 33 const ClientId kTestClientId1(kTestClientNamespace, "1234");
30 const ClientId kTestClientId2(kTestClientNamespace, "5678"); 34 const ClientId kTestClientId2(kTestClientNamespace, "5678");
31 const base::FilePath::CharType kFilePath[] = 35 const base::FilePath::CharType kFilePath[] =
32 FILE_PATH_LITERAL("/offline_pages/example_com.mhtml"); 36 FILE_PATH_LITERAL("/offline_pages/example_com.mhtml");
33 int64_t kFileSize = 234567; 37 int64_t kFileSize = 234567;
34 38
35 class OfflinePageMetadataStoreFactory { 39 class OfflinePageMetadataStoreFactory {
36 public: 40 public:
37 virtual OfflinePageMetadataStore* BuildStore(const base::FilePath& file) = 0; 41 virtual OfflinePageMetadataStore* BuildStore(const base::FilePath& file) = 0;
38 }; 42 };
39 43
44 class OfflinePageMetadataStoreImplFactory
45 : public OfflinePageMetadataStoreFactory {
46 public:
47 OfflinePageMetadataStore* BuildStore(const base::FilePath& file) override {
48 return new OfflinePageMetadataStoreImpl(base::ThreadTaskRunnerHandle::Get(),
49 file);
50 }
51 };
52
40 class OfflinePageMetadataStoreSQLFactory 53 class OfflinePageMetadataStoreSQLFactory
41 : public OfflinePageMetadataStoreFactory { 54 : public OfflinePageMetadataStoreFactory {
42 public: 55 public:
43 OfflinePageMetadataStore* BuildStore(const base::FilePath& file) override { 56 OfflinePageMetadataStore* BuildStore(const base::FilePath& file) override {
44 OfflinePageMetadataStoreSQL* store = new OfflinePageMetadataStoreSQL( 57 OfflinePageMetadataStoreSQL* store = new OfflinePageMetadataStoreSQL(
45 base::ThreadTaskRunnerHandle::Get(), file); 58 base::ThreadTaskRunnerHandle::Get(), file);
46 return store; 59 return store;
47 } 60 }
48 }; 61 };
49 62
50 enum CalledCallback { NONE, LOAD, ADD, REMOVE, DESTROY }; 63 enum CalledCallback { NONE, LOAD, ADD, REMOVE, DESTROY };
51 enum Status { STATUS_NONE, STATUS_TRUE, STATUS_FALSE }; 64 enum Status { STATUS_NONE, STATUS_TRUE, STATUS_FALSE };
52 65
53 class OfflinePageMetadataStoreTestBase : public testing::Test { 66 class OfflinePageMetadataStoreTestBase : public testing::Test {
54 public: 67 public:
55 OfflinePageMetadataStoreTestBase(); 68 OfflinePageMetadataStoreTestBase();
56 ~OfflinePageMetadataStoreTestBase() override; 69 ~OfflinePageMetadataStoreTestBase() override;
57 70
58 void TearDown() override { 71 void TearDown() override {
59 // Wait for all the pieces of the store to delete itself properly. 72 // Wait for all the pieces of the store to delete itself properly.
60 PumpLoop(); 73 PumpLoop();
61 } 74 }
62 75
63 std::unique_ptr<OfflinePageMetadataStore> BuildStore(); 76 std::unique_ptr<OfflinePageMetadataStoreImpl> BuildStore();
64 void PumpLoop(); 77 void PumpLoop();
65 78
66 void LoadCallback(OfflinePageMetadataStore::LoadStatus load_status, 79 void LoadCallback(OfflinePageMetadataStore::LoadStatus load_status,
67 const std::vector<OfflinePageItem>& offline_pages); 80 const std::vector<OfflinePageItem>& offline_pages);
68 void UpdateCallback(CalledCallback called_callback, bool success); 81 void UpdateCallback(CalledCallback called_callback, bool success);
69 82
70 void ClearResults(); 83 void ClearResults();
71 84
72 protected: 85 protected:
73 CalledCallback last_called_callback_; 86 CalledCallback last_called_callback_;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 std::unique_ptr<OfflinePageMetadataStore> 141 std::unique_ptr<OfflinePageMetadataStore>
129 OfflinePageMetadataStoreTest<T>::BuildStore() { 142 OfflinePageMetadataStoreTest<T>::BuildStore() {
130 std::unique_ptr<OfflinePageMetadataStore> store( 143 std::unique_ptr<OfflinePageMetadataStore> store(
131 factory_.BuildStore(temp_directory_.path())); 144 factory_.BuildStore(temp_directory_.path()));
132 store->Load(base::Bind(&OfflinePageMetadataStoreTestBase::LoadCallback, 145 store->Load(base::Bind(&OfflinePageMetadataStoreTestBase::LoadCallback,
133 base::Unretained(this))); 146 base::Unretained(this)));
134 PumpLoop(); 147 PumpLoop();
135 return store; 148 return store;
136 } 149 }
137 150
138 typedef testing::Types<OfflinePageMetadataStoreSQLFactory> MyTypes; 151 typedef testing::Types<OfflinePageMetadataStoreImplFactory,
152 OfflinePageMetadataStoreSQLFactory>
153 MyTypes;
139 TYPED_TEST_CASE(OfflinePageMetadataStoreTest, MyTypes); 154 TYPED_TEST_CASE(OfflinePageMetadataStoreTest, MyTypes);
140 155
141 // Loads empty store and makes sure that there are no offline pages stored in 156 // Loads empty store and makes sure that there are no offline pages stored in
142 // it. 157 // it.
143 TYPED_TEST(OfflinePageMetadataStoreTest, LoadEmptyStore) { 158 TYPED_TEST(OfflinePageMetadataStoreTest, LoadEmptyStore) {
144 std::unique_ptr<OfflinePageMetadataStore> store(this->BuildStore()); 159 std::unique_ptr<OfflinePageMetadataStore> store(this->BuildStore());
145 EXPECT_EQ(LOAD, this->last_called_callback_); 160 EXPECT_EQ(LOAD, this->last_called_callback_);
146 EXPECT_EQ(STATUS_TRUE, this->last_status_); 161 EXPECT_EQ(STATUS_TRUE, this->last_status_);
147 EXPECT_EQ(0U, this->offline_pages_.size()); 162 EXPECT_EQ(0U, this->offline_pages_.size());
148 } 163 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 EXPECT_EQ(offline_page.file_path, this->offline_pages_[0].file_path); 390 EXPECT_EQ(offline_page.file_path, this->offline_pages_[0].file_path);
376 EXPECT_EQ(offline_page.file_size, this->offline_pages_[0].file_size); 391 EXPECT_EQ(offline_page.file_size, this->offline_pages_[0].file_size);
377 EXPECT_EQ(offline_page.creation_time, this->offline_pages_[0].creation_time); 392 EXPECT_EQ(offline_page.creation_time, this->offline_pages_[0].creation_time);
378 EXPECT_EQ(offline_page.last_access_time, 393 EXPECT_EQ(offline_page.last_access_time,
379 this->offline_pages_[0].last_access_time); 394 this->offline_pages_[0].last_access_time);
380 EXPECT_EQ(offline_page.access_count, this->offline_pages_[0].access_count); 395 EXPECT_EQ(offline_page.access_count, this->offline_pages_[0].access_count);
381 EXPECT_EQ(offline_page.client_id, this->offline_pages_[0].client_id); 396 EXPECT_EQ(offline_page.client_id, this->offline_pages_[0].client_id);
382 } 397 }
383 398
384 } // namespace 399 } // namespace
400
401 class OfflinePageMetadataStoreImplTest
402 : public OfflinePageMetadataStoreTest<OfflinePageMetadataStoreImplFactory> {
403 public:
404 void UpdateStoreEntries(
405 OfflinePageMetadataStoreImpl* store,
406 std::unique_ptr<leveldb_proto::ProtoDatabase<
407 OfflinePageEntry>::KeyEntryVector> entries_to_save);
408 };
409
410 void OfflinePageMetadataStoreImplTest::UpdateStoreEntries(
411 OfflinePageMetadataStoreImpl* store,
412 std::unique_ptr<leveldb_proto::ProtoDatabase<
413 OfflinePageEntry>::KeyEntryVector> entries_to_save) {
414 std::unique_ptr<std::vector<std::string>> keys_to_remove(
415 new std::vector<std::string>());
416 store->UpdateEntries(
417 std::move(entries_to_save), std::move(keys_to_remove),
418 base::Bind(&OfflinePageMetadataStoreTestBase::UpdateCallback,
419 base::Unretained(this), ADD));
420 }
421
422 // Test that loading a store with a bad value still loads.
423 // Needs to be outside of the anonymous namespace in order for FRIEND_TEST
424 // to work.
425 TEST_F(OfflinePageMetadataStoreImplTest, LoadCorruptedStore) {
426 std::unique_ptr<OfflinePageMetadataStore> store(this->BuildStore());
427
428 // Write one ok page.
429 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestClientId1,
430 base::FilePath(kFilePath), kFileSize);
431 store->AddOrUpdateOfflinePage(
432 offline_page,
433 base::Bind(&OfflinePageMetadataStoreTestBase::UpdateCallback,
434 base::Unretained(this), ADD));
435 this->PumpLoop();
436 EXPECT_EQ(ADD, this->last_called_callback_);
437 EXPECT_EQ(STATUS_TRUE, this->last_status_);
438
439 // Manually write one broken page (no id)
440 std::unique_ptr<
441 leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector>
442 entries_to_save(
443 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
444
445 OfflinePageEntry offline_page_proto;
446 entries_to_save->push_back(std::make_pair("0", offline_page_proto));
447
448 UpdateStoreEntries((OfflinePageMetadataStoreImpl*)store.get(),
449 std::move(entries_to_save));
450 this->PumpLoop();
451
452 EXPECT_EQ(ADD, this->last_called_callback_);
453 EXPECT_EQ(STATUS_TRUE, this->last_status_);
454
455 this->ClearResults();
456
457 // Close the store first to ensure file lock is removed.
458 store.reset();
459 store = this->BuildStore();
460 this->PumpLoop();
461
462 // One of the pages was busted, so only expect one page.
463 EXPECT_EQ(LOAD, this->last_called_callback_);
464 EXPECT_EQ(STATUS_TRUE, this->last_status_);
465 EXPECT_EQ(1U, this->offline_pages_.size());
466 EXPECT_EQ(offline_page.url, this->offline_pages_[0].url);
467 EXPECT_EQ(offline_page.offline_id, this->offline_pages_[0].offline_id);
468 EXPECT_EQ(offline_page.version, this->offline_pages_[0].version);
469 EXPECT_EQ(offline_page.file_path, this->offline_pages_[0].file_path);
470 EXPECT_EQ(offline_page.file_size, this->offline_pages_[0].file_size);
471 EXPECT_EQ(offline_page.creation_time, this->offline_pages_[0].creation_time);
472 EXPECT_EQ(offline_page.last_access_time,
473 this->offline_pages_[0].last_access_time);
474 EXPECT_EQ(offline_page.access_count, this->offline_pages_[0].access_count);
475 }
476
477 // Test that loading a store with nothing but bad values errors.
478 // Needs to be outside of the anonymous namespace in order for FRIEND_TEST
479 // to work.
480 TEST_F(OfflinePageMetadataStoreImplTest, LoadTotallyCorruptedStore) {
481 std::unique_ptr<OfflinePageMetadataStore> store(this->BuildStore());
482
483 // Manually write two broken pages (no id)
484 std::unique_ptr<
485 leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector>
486 entries_to_save(
487 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
488
489 OfflinePageEntry offline_page_proto;
490 entries_to_save->push_back(std::make_pair("0", offline_page_proto));
491 entries_to_save->push_back(std::make_pair("1", offline_page_proto));
492
493 UpdateStoreEntries((OfflinePageMetadataStoreImpl*)store.get(),
494 std::move(entries_to_save));
495 ;
496 this->PumpLoop();
497
498 EXPECT_EQ(ADD, this->last_called_callback_);
499 EXPECT_EQ(STATUS_TRUE, this->last_status_);
500
501 this->ClearResults();
502
503 // Close the store first to ensure file lock is removed.
504 store.reset();
505 store = this->BuildStore();
506 this->PumpLoop();
507
508 // One of the pages was busted, so only expect one page.
509 EXPECT_EQ(LOAD, this->last_called_callback_);
510 EXPECT_EQ(STATUS_FALSE, this->last_status_);
511 }
512
513 TEST_F(OfflinePageMetadataStoreImplTest, UpgradeStoreFromBookmarkIdToClientId) {
514 std::unique_ptr<OfflinePageMetadataStore> store(this->BuildStore());
515
516 // Manually write a page referring to legacy bookmark id.
517 std::unique_ptr<
518 leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector>
519 entries_to_save(
520 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
521
522 OfflinePageEntry offline_page_proto;
523 offline_page_proto.set_deprecated_bookmark_id(1LL);
524 offline_page_proto.set_version(1);
525 offline_page_proto.set_url(kTestURL);
526 offline_page_proto.set_file_path("/foo/bar");
527 entries_to_save->push_back(std::make_pair("1", offline_page_proto));
528
529 UpdateStoreEntries((OfflinePageMetadataStoreImpl*)store.get(),
530 std::move(entries_to_save));
531 PumpLoop();
532
533 EXPECT_EQ(ADD, last_called_callback_);
534 EXPECT_EQ(STATUS_TRUE, last_status_);
535
536 ClearResults();
537
538 // Close the store first to ensure file lock is removed.
539 store.reset();
540 store = BuildStore();
541 PumpLoop();
542
543 // The page should be upgraded with new Client ID format.
544 EXPECT_EQ(LOAD, last_called_callback_);
545 EXPECT_EQ(STATUS_TRUE, last_status_);
546 EXPECT_EQ(1U, offline_pages_.size());
547 EXPECT_TRUE(offline_pages_[0].offline_id != 0);
548 EXPECT_EQ(offline_pages::kBookmarkNamespace,
549 offline_pages_[0].client_id.name_space);
550 EXPECT_EQ(base::Int64ToString(offline_page_proto.deprecated_bookmark_id()),
551 offline_pages_[0].client_id.id);
552 EXPECT_EQ(GURL(kTestURL), offline_pages_[0].url);
553 EXPECT_EQ(offline_page_proto.version(), offline_pages_[0].version);
554 EXPECT_EQ(offline_page_proto.file_path(),
555 offline_pages_[0].file_path.MaybeAsASCII());
556 }
557
385 } // namespace offline_pages 558 } // namespace offline_pages
OLDNEW
« no previous file with comments | « components/offline_pages/offline_page_metadata_store_impl.cc ('k') | components/offline_pages/offline_page_model.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698