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

Side by Side Diff: components/history/core/browser/thumbnail_database_unittest.cc

Issue 2903573002: [Thumbnails DB] Add functionality to clear unused on-demand favicons. (Closed)
Patch Set: Peter's comments Created 3 years, 6 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <stddef.h> 5 #include <stddef.h>
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/files/file_enumerator.h" 10 #include "base/files/file_enumerator.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/files/scoped_temp_dir.h" 12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/ref_counted_memory.h" 13 #include "base/memory/ref_counted_memory.h"
14 #include "base/path_service.h" 14 #include "base/path_service.h"
15 #include "components/history/core/browser/history_backend_client.h"
15 #include "components/history/core/browser/thumbnail_database.h" 16 #include "components/history/core/browser/thumbnail_database.h"
16 #include "components/history/core/test/database_test_utils.h" 17 #include "components/history/core/test/database_test_utils.h"
17 #include "sql/connection.h" 18 #include "sql/connection.h"
18 #include "sql/recovery.h" 19 #include "sql/recovery.h"
19 #include "sql/test/scoped_error_expecter.h" 20 #include "sql/test/scoped_error_expecter.h"
20 #include "sql/test/test_helpers.h" 21 #include "sql/test/test_helpers.h"
22 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/sqlite/sqlite3.h" 24 #include "third_party/sqlite/sqlite3.h"
23 #include "url/gurl.h" 25 #include "url/gurl.h"
24 26
27 using testing::StrictMock;
28 using testing::Return;
29
25 namespace history { 30 namespace history {
26 31
27 namespace { 32 namespace {
28 33
29 // Blobs for the bitmap tests. These aren't real bitmaps. Golden 34 // Blobs for the bitmap tests. These aren't real bitmaps. Golden
30 // database files store the same blobs (see VersionN tests). 35 // database files store the same blobs (see VersionN tests).
31 const unsigned char kBlob1[] = 36 const unsigned char kBlob1[] =
32 "12346102356120394751634516591348710478123649165419234519234512349134"; 37 "12346102356120394751634516591348710478123649165419234519234512349134";
33 const unsigned char kBlob2[] = 38 const unsigned char kBlob2[] =
34 "goiwuegrqrcomizqyzkjalitbahxfjytrqvpqeroicxmnlkhlzunacxaneviawrtxcywhgef"; 39 "goiwuegrqrcomizqyzkjalitbahxfjytrqvpqeroicxmnlkhlzunacxaneviawrtxcywhgef";
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 167 }
163 168
164 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) { 169 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) {
165 return a.icon_url < b.icon_url; 170 return a.icon_url < b.icon_url;
166 } 171 }
167 172
168 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) { 173 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) {
169 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl); 174 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl);
170 } 175 }
171 176
177 class MockHistoryBackendClient : public HistoryBackendClient {
178 public:
179 // MOCK_METHOD0(~HistoryBackendClient, void());
180 MOCK_METHOD1(IsBookmarked, bool(const GURL& url));
181 MOCK_METHOD1(GetBookmarks, void(std::vector<URLAndTitle>* bookmarks));
182 MOCK_METHOD0(ShouldReportDatabaseError, bool());
183 MOCK_METHOD1(IsWebSafe, bool(const GURL& url));
184
185 #if defined(OS_ANDROID)
186 MOCK_METHOD4(OnHistoryBackendInitialized,
187 void(HistoryBackend* history_backend,
188 HistoryDatabase* history_database,
189 ThumbnailDatabase* thumbnail_database,
190 const base::FilePath& history_dir));
191 MOCK_METHOD2(OnHistoryBackendDestroyed,
192 void(HistoryBackend* history_backend,
193 const base::FilePath& history_dir));
194 #endif // defined(OS_ANDROID)
195 };
196
172 } // namespace 197 } // namespace
173 198
174 class ThumbnailDatabaseTest : public testing::Test { 199 class ThumbnailDatabaseTest : public testing::Test {
175 public: 200 public:
176 ThumbnailDatabaseTest() {} 201 ThumbnailDatabaseTest() {}
177 ~ThumbnailDatabaseTest() override {} 202 ~ThumbnailDatabaseTest() override {}
178 203
179 // Initialize a thumbnail database instance from the SQL file at 204 // Initialize a thumbnail database instance from the SQL file at
180 // |golden_path| in the "History/" subdirectory of test data. 205 // |golden_path| in the "History/" subdirectory of test data.
181 std::unique_ptr<ThumbnailDatabase> LoadFromGolden(const char* golden_path) { 206 std::unique_ptr<ThumbnailDatabase> LoadFromGolden(const char* golden_path) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 db.TouchOnDemandFavicon(url, end); 385 db.TouchOnDemandFavicon(url, end);
361 386
362 base::Time last_updated; 387 base::Time last_updated;
363 base::Time last_requested; 388 base::Time last_requested;
364 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested, 389 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested,
365 nullptr, nullptr)); 390 nullptr, nullptr));
366 EXPECT_EQ(start, last_updated); // Does not mess with last_updated. 391 EXPECT_EQ(start, last_updated); // Does not mess with last_updated.
367 EXPECT_EQ(base::Time(), last_requested); // No update. 392 EXPECT_EQ(base::Time(), last_requested); // No update.
368 } 393 }
369 394
395 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsSuccess) {
396 StrictMock<MockHistoryBackendClient> mock_client;
397 ThumbnailDatabase db(&mock_client);
398 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
399 db.BeginTransaction();
400
401 base::Time start;
402 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
403 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
404 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
405
406 // Icon: old unused case (not bookmarked).
407 GURL url("http://google.com");
408 EXPECT_CALL(mock_client, IsBookmarked(url)).WillOnce(Return(false));
409 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
410 ASSERT_NE(0, icon);
411 FaviconBitmapID bitmap =
412 db.AddOnDemandFaviconBitmap(icon, favicon, start, gfx::Size());
413 ASSERT_NE(0, bitmap);
414 ASSERT_NE(0, db.AddIconMapping(url, icon));
415
416 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
417 db.ClearOldOnDemandFavicons(delete_older_than);
418
419 // The icon gets deleted.
420 EXPECT_FALSE(db.GetIconMappingsForPageURL(url, nullptr));
421 EXPECT_FALSE(db.GetFaviconHeader(icon, nullptr, nullptr));
422 EXPECT_FALSE(db.GetFaviconBitmaps(icon, nullptr));
423 }
424
425 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsDoesNotDeleteFreshOne) {
426 StrictMock<MockHistoryBackendClient> mock_client;
427 ThumbnailDatabase db(&mock_client);
428 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
429 db.BeginTransaction();
430
431 base::Time start;
432 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
433 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
434 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
435
436 // Icon: freshly used case.
437 GURL url("http://google.com");
438 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
439 ASSERT_NE(0, icon);
440 FaviconBitmapID bitmap =
441 db.AddOnDemandFaviconBitmap(icon, favicon, start, gfx::Size());
442 ASSERT_NE(0, bitmap);
443 ASSERT_NE(0, db.AddIconMapping(url, icon));
444
445 // Touch the icon 3 weeks later.
446 base::Time now = start + base::TimeDelta::FromDays(21);
447 EXPECT_TRUE(db.TouchOnDemandFavicon(url, now));
448
449 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
450 db.ClearOldOnDemandFavicons(delete_older_than);
451
452 // Nothing gets deleted.
453 EXPECT_TRUE(db.GetFaviconHeader(icon, nullptr, nullptr));
454 std::vector<FaviconBitmap> favicon_bitmaps;
455 EXPECT_TRUE(db.GetFaviconBitmaps(icon, &favicon_bitmaps));
456 EXPECT_EQ(1u, favicon_bitmaps.size());
457 std::vector<IconMapping> icon_mapping;
458 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mapping));
459 EXPECT_EQ(1u, icon_mapping.size());
460 EXPECT_EQ(icon, icon_mapping[0].icon_id);
461 }
462
463 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsDoesNotDeleteBookmarked) {
464 StrictMock<MockHistoryBackendClient> mock_client;
465 ThumbnailDatabase db(&mock_client);
466 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
467 db.BeginTransaction();
468
469 base::Time start;
470 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
471 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
472 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
473
474 // Icon: unused but bookmarked case.
475 GURL url("http://google.com");
476 EXPECT_CALL(mock_client, IsBookmarked(url)).WillOnce(Return(true));
477 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
478 ASSERT_NE(0, icon);
479 FaviconBitmapID bitmap =
480 db.AddOnDemandFaviconBitmap(icon, favicon, start, gfx::Size());
481 ASSERT_NE(0, bitmap);
482 ASSERT_NE(0, db.AddIconMapping(url, icon));
483
484 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
485 db.ClearOldOnDemandFavicons(delete_older_than);
486
487 // Nothing gets deleted.
488 EXPECT_TRUE(db.GetFaviconHeader(icon, nullptr, nullptr));
489 std::vector<FaviconBitmap> favicon_bitmaps;
490 EXPECT_TRUE(db.GetFaviconBitmaps(icon, &favicon_bitmaps));
491 EXPECT_EQ(1u, favicon_bitmaps.size());
492 std::vector<IconMapping> icon_mapping;
493 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mapping));
494 EXPECT_EQ(1u, icon_mapping.size());
495 EXPECT_EQ(icon, icon_mapping[0].icon_id);
496 }
497
498 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsDoesNotDeleteStandard) {
499 StrictMock<MockHistoryBackendClient> mock_client;
500 ThumbnailDatabase db(&mock_client);
501 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
502 db.BeginTransaction();
503
504 base::Time start;
505 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
506 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
507 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
508
509 // Icon: standard favicon (not on-demand).
510 GURL url("http://google.com");
511 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
512 ASSERT_NE(0, icon);
513 FaviconBitmapID bitmap =
514 db.AddFaviconBitmap(icon, favicon, start, gfx::Size());
515 ASSERT_NE(0, bitmap);
516 ASSERT_NE(0, db.AddIconMapping(url, icon));
517
518 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
519 db.ClearOldOnDemandFavicons(delete_older_than);
520
521 // Nothing gets deleted.
522 EXPECT_TRUE(db.GetFaviconHeader(icon, nullptr, nullptr));
523 std::vector<FaviconBitmap> favicon_bitmaps;
524 EXPECT_TRUE(db.GetFaviconBitmaps(icon, &favicon_bitmaps));
525 EXPECT_EQ(1u, favicon_bitmaps.size());
526 std::vector<IconMapping> icon_mapping;
527 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mapping));
528 EXPECT_EQ(1u, icon_mapping.size());
529 EXPECT_EQ(icon, icon_mapping[0].icon_id);
530 }
531
370 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) { 532 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) {
371 ThumbnailDatabase db(NULL); 533 ThumbnailDatabase db(NULL);
372 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 534 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
373 db.BeginTransaction(); 535 db.BeginTransaction();
374 536
375 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); 537 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
376 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); 538 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
377 539
378 GURL url("http://google.com"); 540 GURL url("http://google.com");
379 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON); 541 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON);
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 ThumbnailDatabase db(NULL); 1343 ThumbnailDatabase db(NULL);
1182 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); 1344 ASSERT_EQ(sql::INIT_OK, db.Init(db_path));
1183 1345
1184 // Verify that the resulting schema is correct, whether it 1346 // Verify that the resulting schema is correct, whether it
1185 // involved razing the file or fixing things in place. 1347 // involved razing the file or fixing things in place.
1186 VerifyTablesAndColumns(&db.db_); 1348 VerifyTablesAndColumns(&db.db_);
1187 } 1349 }
1188 } 1350 }
1189 1351
1190 } // namespace history 1352 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698