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

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: 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 166 }
162 167
163 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) { 168 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) {
164 return a.icon_url < b.icon_url; 169 return a.icon_url < b.icon_url;
165 } 170 }
166 171
167 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) { 172 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) {
168 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl); 173 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl);
169 } 174 }
170 175
176 class MockHistoryBackendClient : public HistoryBackendClient {
177 public:
178 // MOCK_METHOD0(~HistoryBackendClient, void());
179 MOCK_METHOD1(IsBookmarked, bool(const GURL& url));
180 MOCK_METHOD1(GetBookmarks, void(std::vector<URLAndTitle>* bookmarks));
181 MOCK_METHOD0(ShouldReportDatabaseError, bool());
182 MOCK_METHOD1(IsWebSafe, bool(const GURL& url));
183
184 #if defined(OS_ANDROID)
185 MOCK_METHOD4(OnHistoryBackendInitialized,
186 void(HistoryBackend* history_backend,
187 HistoryDatabase* history_database,
188 ThumbnailDatabase* thumbnail_database,
189 const base::FilePath& history_dir));
190 MOCK_METHOD2(OnHistoryBackendDestroyed,
191 void(HistoryBackend* history_backend,
192 const base::FilePath& history_dir));
193 #endif // defined(OS_ANDROID)
194 };
195
171 } // namespace 196 } // namespace
172 197
173 class ThumbnailDatabaseTest : public testing::Test { 198 class ThumbnailDatabaseTest : public testing::Test {
174 public: 199 public:
175 ThumbnailDatabaseTest() {} 200 ThumbnailDatabaseTest() {}
176 ~ThumbnailDatabaseTest() override {} 201 ~ThumbnailDatabaseTest() override {}
177 202
178 // Initialize a thumbnail database instance from the SQL file at 203 // Initialize a thumbnail database instance from the SQL file at
179 // |golden_path| in the "History/" subdirectory of test data. 204 // |golden_path| in the "History/" subdirectory of test data.
180 std::unique_ptr<ThumbnailDatabase> LoadFromGolden(const char* golden_path) { 205 std::unique_ptr<ThumbnailDatabase> LoadFromGolden(const char* golden_path) {
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 db.TouchOnDemandFavicon(url, end); 379 db.TouchOnDemandFavicon(url, end);
355 380
356 base::Time last_updated; 381 base::Time last_updated;
357 base::Time last_requested; 382 base::Time last_requested;
358 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested, 383 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested,
359 nullptr, nullptr)); 384 nullptr, nullptr));
360 EXPECT_EQ(start, last_updated); // Does not mess up with last_updates. 385 EXPECT_EQ(start, last_updated); // Does not mess up with last_updates.
361 EXPECT_EQ(base::Time(), last_requested); // No update. 386 EXPECT_EQ(base::Time(), last_requested); // No update.
362 } 387 }
363 388
389 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsSuccess) {
390 StrictMock<MockHistoryBackendClient> mock_client;
391 ThumbnailDatabase db(&mock_client);
392 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
393 db.BeginTransaction();
394
395 base::Time start;
396 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
397 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
398 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
399
400 // Icon: old unused case (not bookmarked).
401 GURL url("http://google.com");
402 EXPECT_CALL(mock_client, IsBookmarked(url)).WillOnce(Return(false));
403 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
404 ASSERT_NE(0, icon);
405 FaviconBitmapID bitmap =
406 db.AddOnDemandFaviconBitmap(icon, favicon, start, gfx::Size());
407 ASSERT_NE(0, bitmap);
408 ASSERT_NE(0, db.AddIconMapping(url, icon));
409
410 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
411 db.ClearOldOnDemandFavicons(delete_older_than);
412
413 // The icon gets deleted.
414 EXPECT_FALSE(db.GetIconMappingsForPageURL(url, nullptr));
415 EXPECT_FALSE(db.GetFaviconHeader(icon, nullptr, nullptr));
416 EXPECT_FALSE(db.GetFaviconBitmaps(icon, nullptr));
417 }
418
419 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsDoesNotDeleteFreshOne) {
420 StrictMock<MockHistoryBackendClient> mock_client;
421 ThumbnailDatabase db(&mock_client);
422 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
423 db.BeginTransaction();
424
425 base::Time start;
426 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
427 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
428 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
429
430 // Icon: freshly used case.
431 GURL url("http://google.com");
432 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
433 ASSERT_NE(0, icon);
434 FaviconBitmapID bitmap =
435 db.AddOnDemandFaviconBitmap(icon, favicon, start, gfx::Size());
436 ASSERT_NE(0, bitmap);
437 ASSERT_NE(0, db.AddIconMapping(url, icon));
438
439 // Touch the icon 3 weeks later.
440 base::Time now = start + base::TimeDelta::FromDays(21);
441 EXPECT_TRUE(db.TouchOnDemandFavicon(url, now));
442
443 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
444 db.ClearOldOnDemandFavicons(delete_older_than);
445
446 // Nothing gets deleted.
447 EXPECT_TRUE(db.GetFaviconHeader(icon, nullptr, nullptr));
448 std::vector<FaviconBitmap> favicon_bitmaps;
449 EXPECT_TRUE(db.GetFaviconBitmaps(icon, &favicon_bitmaps));
450 EXPECT_EQ(1u, favicon_bitmaps.size());
451 std::vector<IconMapping> icon_mapping;
452 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mapping));
453 EXPECT_EQ(1u, icon_mapping.size());
454 EXPECT_EQ(icon, icon_mapping[0].icon_id);
455 }
456
457 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsDoesNotDeleteBookmarked) {
458 StrictMock<MockHistoryBackendClient> mock_client;
459 ThumbnailDatabase db(&mock_client);
460 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
461 db.BeginTransaction();
462
463 base::Time start;
464 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
465 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
466 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
467
468 // Icon: unused but bookmarked case.
469 GURL url("http://google.com");
470 EXPECT_CALL(mock_client, IsBookmarked(url)).WillOnce(Return(true));
471 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
472 ASSERT_NE(0, icon);
473 FaviconBitmapID bitmap =
474 db.AddOnDemandFaviconBitmap(icon, favicon, start, gfx::Size());
475 ASSERT_NE(0, bitmap);
476 ASSERT_NE(0, db.AddIconMapping(url, icon));
477
478 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
479 db.ClearOldOnDemandFavicons(delete_older_than);
480
481 // Nothing gets deleted.
482 EXPECT_TRUE(db.GetFaviconHeader(icon, nullptr, nullptr));
483 std::vector<FaviconBitmap> favicon_bitmaps;
484 EXPECT_TRUE(db.GetFaviconBitmaps(icon, &favicon_bitmaps));
485 EXPECT_EQ(1u, favicon_bitmaps.size());
486 std::vector<IconMapping> icon_mapping;
487 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mapping));
488 EXPECT_EQ(1u, icon_mapping.size());
489 EXPECT_EQ(icon, icon_mapping[0].icon_id);
490 }
491
492 TEST_F(ThumbnailDatabaseTest, ClearOldOnDemandFaviconsDoesNotDeleteStandard) {
493 StrictMock<MockHistoryBackendClient> mock_client;
494 ThumbnailDatabase db(&mock_client);
495 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
496 db.BeginTransaction();
497
498 base::Time start;
499 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
500 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
501 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
502
503 // Icon: standard favicon (not on-demand).
504 GURL url("http://google.com");
505 favicon_base::FaviconID icon = db.AddFavicon(url, favicon_base::FAVICON);
506 ASSERT_NE(0, icon);
507 FaviconBitmapID bitmap =
508 db.AddFaviconBitmap(icon, favicon, start, gfx::Size());
509 ASSERT_NE(0, bitmap);
510 ASSERT_NE(0, db.AddIconMapping(url, icon));
511
512 base::Time delete_older_than = start + base::TimeDelta::FromDays(7);
513 db.ClearOldOnDemandFavicons(delete_older_than);
514
515 // Nothing gets deleted.
516 EXPECT_TRUE(db.GetFaviconHeader(icon, nullptr, nullptr));
517 std::vector<FaviconBitmap> favicon_bitmaps;
518 EXPECT_TRUE(db.GetFaviconBitmaps(icon, &favicon_bitmaps));
519 EXPECT_EQ(1u, favicon_bitmaps.size());
520 std::vector<IconMapping> icon_mapping;
521 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mapping));
522 EXPECT_EQ(1u, icon_mapping.size());
523 EXPECT_EQ(icon, icon_mapping[0].icon_id);
524 }
525
364 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) { 526 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) {
365 ThumbnailDatabase db(NULL); 527 ThumbnailDatabase db(NULL);
366 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 528 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
367 db.BeginTransaction(); 529 db.BeginTransaction();
368 530
369 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); 531 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
370 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); 532 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
371 533
372 GURL url("http://google.com"); 534 GURL url("http://google.com");
373 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON); 535 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON);
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 ThumbnailDatabase db(NULL); 1337 ThumbnailDatabase db(NULL);
1176 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); 1338 ASSERT_EQ(sql::INIT_OK, db.Init(db_path));
1177 1339
1178 // Verify that the resulting schema is correct, whether it 1340 // Verify that the resulting schema is correct, whether it
1179 // involved razing the file or fixing things in place. 1341 // involved razing the file or fixing things in place.
1180 VerifyTablesAndColumns(&db.db_); 1342 VerifyTablesAndColumns(&db.db_);
1181 } 1343 }
1182 } 1344 }
1183 1345
1184 } // namespace history 1346 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698