OLD | NEW |
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_impl.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 "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
14 #include "base/test/test_simple_task_runner.h" | 15 #include "base/test/test_simple_task_runner.h" |
15 #include "base/thread_task_runner_handle.h" | 16 #include "base/thread_task_runner_handle.h" |
16 #include "components/leveldb_proto/proto_database_impl.h" | 17 #include "components/leveldb_proto/proto_database_impl.h" |
17 #include "components/offline_pages/offline_page_item.h" | 18 #include "components/offline_pages/offline_page_item.h" |
18 #include "components/offline_pages/offline_page_model.h" | 19 #include "components/offline_pages/offline_page_model.h" |
19 #include "components/offline_pages/proto/offline_pages.pb.h" | 20 #include "components/offline_pages/proto/offline_pages.pb.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
21 | 22 |
22 using leveldb_proto::ProtoDatabaseImpl; | 23 using leveldb_proto::ProtoDatabaseImpl; |
23 | 24 |
24 namespace offline_pages { | 25 namespace offline_pages { |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
28 const char kTestURL[] = "https://example.com"; | 29 const char kTestURL[] = "https://example.com"; |
29 const ClientId kTestBookmarkId(BOOKMARK_NAMESPACE, "1234"); | 30 const ClientId kTestBookmarkId(BOOKMARK_NAMESPACE, "1234"); |
30 const ClientId kTestBookmarkId2(BOOKMARK_NAMESPACE, "5678"); | 31 const ClientId kTestBookmarkId2(BOOKMARK_NAMESPACE, "5678"); |
31 const base::FilePath::CharType kFilePath[] = | 32 const base::FilePath::CharType kFilePath[] = |
32 FILE_PATH_LITERAL("/offline_pages/example_com.mhtml"); | 33 FILE_PATH_LITERAL("/offline_pages/example_com.mhtml"); |
33 int64_t kFileSize = 234567; | 34 int64_t kFileSize = 234567; |
34 | 35 |
| 36 } // namespace |
| 37 |
35 class OfflinePageMetadataStoreImplTest : public testing::Test { | 38 class OfflinePageMetadataStoreImplTest : public testing::Test { |
36 public: | 39 public: |
37 enum CalledCallback { NONE, LOAD, ADD, REMOVE, DESTROY }; | 40 enum CalledCallback { NONE, LOAD, ADD, REMOVE, DESTROY }; |
38 enum Status { STATUS_NONE, STATUS_TRUE, STATUS_FALSE }; | 41 enum Status { STATUS_NONE, STATUS_TRUE, STATUS_FALSE }; |
39 | 42 |
40 OfflinePageMetadataStoreImplTest(); | 43 OfflinePageMetadataStoreImplTest(); |
41 ~OfflinePageMetadataStoreImplTest() override; | 44 ~OfflinePageMetadataStoreImplTest() override; |
42 | 45 |
43 void TearDown() override { | 46 void TearDown() override { |
44 // Wait for all the pieces of the store to delete itself properly. | 47 // Wait for all the pieces of the store to delete itself properly. |
45 PumpLoop(); | 48 PumpLoop(); |
46 } | 49 } |
47 | 50 |
48 scoped_ptr<OfflinePageMetadataStoreImpl> BuildStore(); | 51 scoped_ptr<OfflinePageMetadataStoreImpl> BuildStore(); |
49 void PumpLoop(); | 52 void PumpLoop(); |
50 | 53 |
51 void LoadCallback(OfflinePageMetadataStore::LoadStatus load_status, | 54 void LoadCallback(OfflinePageMetadataStore::LoadStatus load_status, |
52 const std::vector<OfflinePageItem>& offline_pages); | 55 const std::vector<OfflinePageItem>& offline_pages); |
53 void UpdateCallback(CalledCallback called_callback, bool success); | 56 void UpdateCallback(CalledCallback called_callback, bool success); |
54 | 57 |
55 void ClearResults(); | 58 void ClearResults(); |
56 | 59 |
| 60 void UpdateStoreEntries( |
| 61 OfflinePageMetadataStoreImpl* store, |
| 62 scoped_ptr<leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector> |
| 63 entries_to_save); |
| 64 |
57 protected: | 65 protected: |
58 CalledCallback last_called_callback_; | 66 CalledCallback last_called_callback_; |
59 Status last_status_; | 67 Status last_status_; |
60 std::vector<OfflinePageItem> offline_pages_; | 68 std::vector<OfflinePageItem> offline_pages_; |
61 | 69 |
62 base::ScopedTempDir temp_directory_; | 70 base::ScopedTempDir temp_directory_; |
63 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 71 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
64 base::ThreadTaskRunnerHandle task_runner_handle_; | 72 base::ThreadTaskRunnerHandle task_runner_handle_; |
65 }; | 73 }; |
66 | 74 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 last_called_callback_ = called_callback; | 113 last_called_callback_ = called_callback; |
106 last_status_ = status ? STATUS_TRUE : STATUS_FALSE; | 114 last_status_ = status ? STATUS_TRUE : STATUS_FALSE; |
107 } | 115 } |
108 | 116 |
109 void OfflinePageMetadataStoreImplTest::ClearResults() { | 117 void OfflinePageMetadataStoreImplTest::ClearResults() { |
110 last_called_callback_ = NONE; | 118 last_called_callback_ = NONE; |
111 last_status_ = STATUS_NONE; | 119 last_status_ = STATUS_NONE; |
112 offline_pages_.clear(); | 120 offline_pages_.clear(); |
113 } | 121 } |
114 | 122 |
| 123 void OfflinePageMetadataStoreImplTest::UpdateStoreEntries( |
| 124 OfflinePageMetadataStoreImpl* store, |
| 125 scoped_ptr<leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector> |
| 126 entries_to_save) { |
| 127 scoped_ptr<std::vector<std::string>> keys_to_remove( |
| 128 new std::vector<std::string>()); |
| 129 store->UpdateEntries( |
| 130 std::move(entries_to_save), std::move(keys_to_remove), |
| 131 base::Bind(&OfflinePageMetadataStoreImplTest::UpdateCallback, |
| 132 base::Unretained(this), ADD)); |
| 133 } |
| 134 |
115 // Loads empty store and makes sure that there are no offline pages stored in | 135 // Loads empty store and makes sure that there are no offline pages stored in |
116 // it. | 136 // it. |
117 TEST_F(OfflinePageMetadataStoreImplTest, LoadEmptyStore) { | 137 TEST_F(OfflinePageMetadataStoreImplTest, LoadEmptyStore) { |
118 scoped_ptr<OfflinePageMetadataStoreImpl> store(BuildStore()); | 138 scoped_ptr<OfflinePageMetadataStoreImpl> store(BuildStore()); |
119 EXPECT_EQ(LOAD, last_called_callback_); | 139 EXPECT_EQ(LOAD, last_called_callback_); |
120 EXPECT_EQ(STATUS_TRUE, last_status_); | 140 EXPECT_EQ(STATUS_TRUE, last_status_); |
121 EXPECT_EQ(0U, offline_pages_.size()); | 141 EXPECT_EQ(0U, offline_pages_.size()); |
122 } | 142 } |
123 | 143 |
124 // Adds metadata of an offline page into a store and then opens the store | 144 // Adds metadata of an offline page into a store and then opens the store |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 EXPECT_EQ(offline_page.offline_id, offline_pages_[0].offline_id); | 365 EXPECT_EQ(offline_page.offline_id, offline_pages_[0].offline_id); |
346 EXPECT_EQ(offline_page.version, offline_pages_[0].version); | 366 EXPECT_EQ(offline_page.version, offline_pages_[0].version); |
347 EXPECT_EQ(offline_page.file_path, offline_pages_[0].file_path); | 367 EXPECT_EQ(offline_page.file_path, offline_pages_[0].file_path); |
348 EXPECT_EQ(offline_page.file_size, offline_pages_[0].file_size); | 368 EXPECT_EQ(offline_page.file_size, offline_pages_[0].file_size); |
349 EXPECT_EQ(offline_page.creation_time, offline_pages_[0].creation_time); | 369 EXPECT_EQ(offline_page.creation_time, offline_pages_[0].creation_time); |
350 EXPECT_EQ(offline_page.last_access_time, offline_pages_[0].last_access_time); | 370 EXPECT_EQ(offline_page.last_access_time, offline_pages_[0].last_access_time); |
351 EXPECT_EQ(offline_page.access_count, offline_pages_[0].access_count); | 371 EXPECT_EQ(offline_page.access_count, offline_pages_[0].access_count); |
352 EXPECT_EQ(offline_page.client_id, offline_pages_[0].client_id); | 372 EXPECT_EQ(offline_page.client_id, offline_pages_[0].client_id); |
353 } | 373 } |
354 | 374 |
355 } // namespace | |
356 | |
357 // Test that loading a store with a bad value still loads. | 375 // Test that loading a store with a bad value still loads. |
358 // Needs to be outside of the anonymous namespace in order for FRIEND_TEST | 376 // Needs to be outside of the anonymous namespace in order for FRIEND_TEST |
359 // to work. | 377 // to work. |
360 TEST_F(OfflinePageMetadataStoreImplTest, LoadCorruptedStore) { | 378 TEST_F(OfflinePageMetadataStoreImplTest, LoadCorruptedStore) { |
361 scoped_ptr<OfflinePageMetadataStoreImpl> store(BuildStore()); | 379 scoped_ptr<OfflinePageMetadataStoreImpl> store(BuildStore()); |
362 | 380 |
363 // Write one ok page. | 381 // Write one ok page. |
364 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestBookmarkId, | 382 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestBookmarkId, |
365 base::FilePath(kFilePath), kFileSize); | 383 base::FilePath(kFilePath), kFileSize); |
366 store->AddOrUpdateOfflinePage( | 384 store->AddOrUpdateOfflinePage( |
367 offline_page, | 385 offline_page, |
368 base::Bind(&OfflinePageMetadataStoreImplTest::UpdateCallback, | 386 base::Bind(&OfflinePageMetadataStoreImplTest::UpdateCallback, |
369 base::Unretained(this), ADD)); | 387 base::Unretained(this), ADD)); |
370 PumpLoop(); | 388 PumpLoop(); |
371 EXPECT_EQ(ADD, last_called_callback_); | 389 EXPECT_EQ(ADD, last_called_callback_); |
372 EXPECT_EQ(STATUS_TRUE, last_status_); | 390 EXPECT_EQ(STATUS_TRUE, last_status_); |
373 | 391 |
374 // Manually write one broken page (no id) | 392 // Manually write one broken page (no id) |
375 scoped_ptr<leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector> | 393 scoped_ptr<leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector> |
376 entries_to_save( | 394 entries_to_save( |
377 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); | 395 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); |
378 scoped_ptr<std::vector<std::string>> keys_to_remove( | |
379 new std::vector<std::string>()); | |
380 | 396 |
381 OfflinePageEntry offline_page_proto; | 397 OfflinePageEntry offline_page_proto; |
382 entries_to_save->push_back(std::make_pair("0", offline_page_proto)); | 398 entries_to_save->push_back(std::make_pair("0", offline_page_proto)); |
383 | 399 |
384 store->UpdateEntries( | 400 UpdateStoreEntries(store.get(), std::move(entries_to_save)); |
385 std::move(entries_to_save), std::move(keys_to_remove), | |
386 base::Bind(&OfflinePageMetadataStoreImplTest::UpdateCallback, | |
387 base::Unretained(this), ADD)); | |
388 PumpLoop(); | 401 PumpLoop(); |
389 | 402 |
390 EXPECT_EQ(ADD, last_called_callback_); | 403 EXPECT_EQ(ADD, last_called_callback_); |
391 EXPECT_EQ(STATUS_TRUE, last_status_); | 404 EXPECT_EQ(STATUS_TRUE, last_status_); |
392 | 405 |
393 ClearResults(); | 406 ClearResults(); |
394 | 407 |
395 // Close the store first to ensure file lock is removed. | 408 // Close the store first to ensure file lock is removed. |
396 store.reset(); | 409 store.reset(); |
397 store = BuildStore(); | 410 store = BuildStore(); |
(...skipping 16 matching lines...) Expand all Loading... |
414 // Test that loading a store with nothing but bad values errors. | 427 // Test that loading a store with nothing but bad values errors. |
415 // Needs to be outside of the anonymous namespace in order for FRIEND_TEST | 428 // Needs to be outside of the anonymous namespace in order for FRIEND_TEST |
416 // to work. | 429 // to work. |
417 TEST_F(OfflinePageMetadataStoreImplTest, LoadTotallyCorruptedStore) { | 430 TEST_F(OfflinePageMetadataStoreImplTest, LoadTotallyCorruptedStore) { |
418 scoped_ptr<OfflinePageMetadataStoreImpl> store(BuildStore()); | 431 scoped_ptr<OfflinePageMetadataStoreImpl> store(BuildStore()); |
419 | 432 |
420 // Manually write two broken pages (no id) | 433 // Manually write two broken pages (no id) |
421 scoped_ptr<leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector> | 434 scoped_ptr<leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector> |
422 entries_to_save( | 435 entries_to_save( |
423 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); | 436 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); |
424 scoped_ptr<std::vector<std::string>> keys_to_remove( | |
425 new std::vector<std::string>()); | |
426 | 437 |
427 OfflinePageEntry offline_page_proto; | 438 OfflinePageEntry offline_page_proto; |
428 entries_to_save->push_back(std::make_pair("0", offline_page_proto)); | 439 entries_to_save->push_back(std::make_pair("0", offline_page_proto)); |
429 entries_to_save->push_back(std::make_pair("1", offline_page_proto)); | 440 entries_to_save->push_back(std::make_pair("1", offline_page_proto)); |
430 | 441 |
431 store->UpdateEntries( | 442 UpdateStoreEntries(store.get(), std::move(entries_to_save));; |
432 std::move(entries_to_save), std::move(keys_to_remove), | |
433 base::Bind(&OfflinePageMetadataStoreImplTest::UpdateCallback, | |
434 base::Unretained(this), ADD)); | |
435 PumpLoop(); | 443 PumpLoop(); |
436 | 444 |
437 EXPECT_EQ(ADD, last_called_callback_); | 445 EXPECT_EQ(ADD, last_called_callback_); |
438 EXPECT_EQ(STATUS_TRUE, last_status_); | 446 EXPECT_EQ(STATUS_TRUE, last_status_); |
439 | 447 |
440 ClearResults(); | 448 ClearResults(); |
441 | 449 |
442 // Close the store first to ensure file lock is removed. | 450 // Close the store first to ensure file lock is removed. |
443 store.reset(); | 451 store.reset(); |
444 store = BuildStore(); | 452 store = BuildStore(); |
445 PumpLoop(); | 453 PumpLoop(); |
446 | 454 |
447 // One of the pages was busted, so only expect one page. | 455 // One of the pages was busted, so only expect one page. |
448 EXPECT_EQ(LOAD, last_called_callback_); | 456 EXPECT_EQ(LOAD, last_called_callback_); |
449 EXPECT_EQ(STATUS_FALSE, last_status_); | 457 EXPECT_EQ(STATUS_FALSE, last_status_); |
450 } | 458 } |
451 | 459 |
| 460 TEST_F(OfflinePageMetadataStoreImplTest, UpgradeStoreFromBookmarkIdToClientId) { |
| 461 scoped_ptr<OfflinePageMetadataStoreImpl> store(BuildStore()); |
| 462 |
| 463 // Manually write a page referring to legacy bookmark id. |
| 464 scoped_ptr<leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector> |
| 465 entries_to_save( |
| 466 new leveldb_proto::ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); |
| 467 |
| 468 OfflinePageEntry offline_page_proto; |
| 469 offline_page_proto.set_deprecated_bookmark_id(1LL); |
| 470 offline_page_proto.set_version(1); |
| 471 offline_page_proto.set_url(kTestURL); |
| 472 offline_page_proto.set_file_path("/foo/bar"); |
| 473 entries_to_save->push_back(std::make_pair("1", offline_page_proto)); |
| 474 |
| 475 UpdateStoreEntries(store.get(), std::move(entries_to_save)); |
| 476 PumpLoop(); |
| 477 |
| 478 EXPECT_EQ(ADD, last_called_callback_); |
| 479 EXPECT_EQ(STATUS_TRUE, last_status_); |
| 480 |
| 481 ClearResults(); |
| 482 |
| 483 // Close the store first to ensure file lock is removed. |
| 484 store.reset(); |
| 485 store = BuildStore(); |
| 486 PumpLoop(); |
| 487 |
| 488 // The page should be upgraded with new Client ID format. |
| 489 EXPECT_EQ(LOAD, last_called_callback_); |
| 490 EXPECT_EQ(STATUS_TRUE, last_status_); |
| 491 EXPECT_EQ(1U, offline_pages_.size()); |
| 492 EXPECT_TRUE(offline_pages_[0].offline_id != 0); |
| 493 EXPECT_EQ(offline_pages::BOOKMARK_NAMESPACE, |
| 494 offline_pages_[0].client_id.name_space); |
| 495 EXPECT_EQ(base::Int64ToString(offline_page_proto.deprecated_bookmark_id()), |
| 496 offline_pages_[0].client_id.id); |
| 497 EXPECT_EQ(GURL(kTestURL), offline_pages_[0].url); |
| 498 EXPECT_EQ(offline_page_proto.version(), offline_pages_[0].version); |
| 499 EXPECT_EQ(offline_page_proto.file_path(), |
| 500 offline_pages_[0].file_path.MaybeAsASCII()); |
| 501 } |
| 502 |
452 } // namespace offline_pages | 503 } // namespace offline_pages |
OLD | NEW |