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

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: Another build fix Created 3 years, 5 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 "base/strings/stringprintf.h"
16 #include "build/build_config.h"
17 #include "components/history/core/browser/history_backend_client.h"
pkotwicz 2017/07/10 05:23:28 Do you need this include?
jkrcal 2017/07/10 16:14:30 Ah, correct. Thanks!
15 #include "components/history/core/browser/thumbnail_database.h" 18 #include "components/history/core/browser/thumbnail_database.h"
16 #include "components/history/core/test/database_test_utils.h" 19 #include "components/history/core/test/database_test_utils.h"
17 #include "sql/connection.h" 20 #include "sql/connection.h"
18 #include "sql/recovery.h" 21 #include "sql/recovery.h"
19 #include "sql/test/scoped_error_expecter.h" 22 #include "sql/test/scoped_error_expecter.h"
20 #include "sql/test/test_helpers.h" 23 #include "sql/test/test_helpers.h"
24 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/sqlite/sqlite3.h" 26 #include "third_party/sqlite/sqlite3.h"
23 #include "url/gurl.h" 27 #include "url/gurl.h"
24 28
29 using testing::AllOf;
30 using testing::ElementsAre;
31 using testing::Field;
32 using testing::StrictMock;
pkotwicz 2017/07/10 05:23:28 Do you need this line?
jkrcal 2017/07/10 16:14:30 Done.
33 using testing::Pair;
34 using testing::Return;
35
25 namespace history { 36 namespace history {
26 37
27 namespace { 38 namespace {
28 39
29 // Blobs for the bitmap tests. These aren't real bitmaps. Golden 40 // Blobs for the bitmap tests. These aren't real bitmaps. Golden
30 // database files store the same blobs (see VersionN tests). 41 // database files store the same blobs (see VersionN tests).
31 const unsigned char kBlob1[] = 42 const unsigned char kBlob1[] =
32 "12346102356120394751634516591348710478123649165419234519234512349134"; 43 "12346102356120394751634516591348710478123649165419234519234512349134";
33 const unsigned char kBlob2[] = 44 const unsigned char kBlob2[] =
34 "goiwuegrqrcomizqyzkjalitbahxfjytrqvpqeroicxmnlkhlzunacxaneviawrtxcywhgef"; 45 "goiwuegrqrcomizqyzkjalitbahxfjytrqvpqeroicxmnlkhlzunacxaneviawrtxcywhgef";
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 173 }
163 174
164 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) { 175 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) {
165 return a.icon_url < b.icon_url; 176 return a.icon_url < b.icon_url;
166 } 177 }
167 178
168 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) { 179 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) {
169 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl); 180 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl);
170 } 181 }
171 182
183 class MockHistoryBackendClient : public HistoryBackendClient {
184 public:
185 // MOCK_METHOD0(~HistoryBackendClient, void());
186 MOCK_METHOD1(IsBookmarked, bool(const GURL& url));
187 MOCK_METHOD1(GetBookmarks, void(std::vector<URLAndTitle>* bookmarks));
188 MOCK_METHOD0(ShouldReportDatabaseError, bool());
189 MOCK_METHOD1(IsWebSafe, bool(const GURL& url));
190
191 #if defined(OS_ANDROID)
192 MOCK_METHOD4(OnHistoryBackendInitialized,
193 void(HistoryBackend* history_backend,
194 HistoryDatabase* history_database,
195 ThumbnailDatabase* thumbnail_database,
196 const base::FilePath& history_dir));
197 MOCK_METHOD2(OnHistoryBackendDestroyed,
198 void(HistoryBackend* history_backend,
199 const base::FilePath& history_dir));
200 #endif // defined(OS_ANDROID)
201 };
202
172 } // namespace 203 } // namespace
173 204
174 class ThumbnailDatabaseTest : public testing::Test { 205 class ThumbnailDatabaseTest : public testing::Test {
175 public: 206 public:
176 ThumbnailDatabaseTest() {} 207 ThumbnailDatabaseTest() {}
177 ~ThumbnailDatabaseTest() override {} 208 ~ThumbnailDatabaseTest() override {}
178 209
179 // Initialize a thumbnail database instance from the SQL file at 210 // Initialize a thumbnail database instance from the SQL file at
180 // |golden_path| in the "History/" subdirectory of test data. 211 // |golden_path| in the "History/" subdirectory of test data.
181 std::unique_ptr<ThumbnailDatabase> LoadFromGolden(const char* golden_path) { 212 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); 391 db.TouchOnDemandFavicon(url, end);
361 392
362 base::Time last_updated; 393 base::Time last_updated;
363 base::Time last_requested; 394 base::Time last_requested;
364 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested, 395 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested,
365 nullptr, nullptr)); 396 nullptr, nullptr));
366 EXPECT_EQ(start, last_updated); // Does not mess with last_updated. 397 EXPECT_EQ(start, last_updated); // Does not mess with last_updated.
367 EXPECT_EQ(base::Time(), last_requested); // No update. 398 EXPECT_EQ(base::Time(), last_requested); // No update.
368 } 399 }
369 400
401 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() returns on-demand icons
402 // which were requested prior to the passed in timestamp.
403 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsReturnsOld) {
404 ThumbnailDatabase db(nullptr);
405 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
406 db.BeginTransaction();
407
408 base::Time start;
409 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
410 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
411 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
412
413 // Icon: old unused case.
pkotwicz 2017/07/10 05:23:28 You don't need the comment here because you have a
jkrcal 2017/07/10 16:14:30 Done.
414 GURL url("http://google.com/favicon.ico");
415 favicon_base::FaviconID icon =
416 db.AddFavicon(url, favicon_base::FAVICON, favicon,
417 FaviconBitmapType::ON_DEMAND, start, gfx::Size());
418 ASSERT_NE(0, icon);
419 // Associate two different URLs with the icon.
420 GURL page_url1("http://google.com/1");
421 ASSERT_NE(0, db.AddIconMapping(page_url1, icon));
422 GURL page_url2("http://google.com/2");
423 ASSERT_NE(0, db.AddIconMapping(page_url2, icon));
424
425 base::Time get_older_than = start + base::TimeDelta::FromSeconds(1);
426 auto map = db.GetOldOnDemandFavicons(get_older_than);
427
428 // The icon is returned.
429 EXPECT_THAT(map, ElementsAre(Pair(
430 icon, AllOf(Field(&FaviconURLs::icon_url, url),
431 Field(&FaviconURLs::page_urls,
432 ElementsAre(page_url1, page_url2))))));
433 }
434
435 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() returns on-visit icons
436 // if the on-visit icons have expired. We need this behavior in order to delete
437 // icons stored via HistoryService::SetOnDemandFavicons() prior to on-demand
438 // icons setting the "last_requested" time.
439 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsReturnsExpired) {
440 ThumbnailDatabase db(nullptr);
441 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
442 db.BeginTransaction();
443
444 base::Time start;
445 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
446 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
447 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
448
449 // Icon: standard favicon (not on-demand) but expired.
450 GURL url("http://google.com/favicon.ico");
451 favicon_base::FaviconID icon =
452 db.AddFavicon(url, favicon_base::FAVICON, favicon,
453 FaviconBitmapType::ON_VISIT, start, gfx::Size());
454 ASSERT_NE(0, icon);
455 GURL page_url("http://google.com/");
456 ASSERT_NE(0, db.AddIconMapping(page_url, icon));
457 ASSERT_TRUE(db.SetFaviconOutOfDate(icon));
458
459 // The threshold is ignored for expired icons.
460 auto map = db.GetOldOnDemandFavicons(/*threshold=*/base::Time::Now());
461
462 // The icon is returned.
463 EXPECT_THAT(map,
464 ElementsAre(Pair(icon, AllOf(Field(&FaviconURLs::icon_url, url),
465 Field(&FaviconURLs::page_urls,
466 ElementsAre(page_url))))));
467 }
468
469 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() does not return
470 // on-demand icons which were requested after to the passed in timestamp.
pkotwicz 2017/07/10 05:23:28 Nit: "after to the" -> "after the"
jkrcal 2017/07/10 16:14:30 Done. (sorry for not proof-reading your previous p
471 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsDoesNotReturnFresh) {
472 ThumbnailDatabase db(nullptr);
473 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
474 db.BeginTransaction();
475
476 base::Time start;
477 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
478 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
479 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
480
481 // Icon: freshly used case.
482 GURL url("http://google.com/favicon.ico");
483 favicon_base::FaviconID icon =
484 db.AddFavicon(url, favicon_base::FAVICON, favicon,
485 FaviconBitmapType::ON_DEMAND, start, gfx::Size());
486 ASSERT_NE(0, icon);
487 ASSERT_NE(0, db.AddIconMapping(GURL("http://google.com/"), icon));
488
489 // Touch the icon 3 weeks later.
490 base::Time now = start + base::TimeDelta::FromDays(21);
491 EXPECT_TRUE(db.TouchOnDemandFavicon(url, now));
492
493 base::Time get_older_than = start + base::TimeDelta::FromSeconds(1);
494 auto list = db.GetOldOnDemandFavicons(get_older_than);
495
496 // No icon is returned.
497 EXPECT_TRUE(list.empty());
498 }
499
500 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() does not return
501 // non-expired on-visit icons.
502 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsDoesNotDeleteStandard) {
503 ThumbnailDatabase db(nullptr);
504 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
505 db.BeginTransaction();
506
507 base::Time start;
508 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start));
509 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
510 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
511
512 // Icon: standard favicon (not on-demand).
513 favicon_base::FaviconID icon = db.AddFavicon(
514 GURL("http://google.com/favicon.ico"), favicon_base::FAVICON, favicon,
515 FaviconBitmapType::ON_VISIT, start, gfx::Size());
516 ASSERT_NE(0, icon);
517 ASSERT_NE(0, db.AddIconMapping(GURL("http://google.com/"), icon));
518
519 base::Time get_older_than = start + base::TimeDelta::FromSeconds(1);
520 auto list = db.GetOldOnDemandFavicons(get_older_than);
521
522 // No icon is returned.
523 EXPECT_TRUE(list.empty());
524 }
525
370 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) { 526 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) {
371 ThumbnailDatabase db(NULL); 527 ThumbnailDatabase db(NULL);
372 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 528 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
373 db.BeginTransaction(); 529 db.BeginTransaction();
374 530
375 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); 531 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
376 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); 532 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
377 533
378 GURL url("http://google.com"); 534 GURL url("http://google.com");
379 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
1181 ThumbnailDatabase db(NULL); 1337 ThumbnailDatabase db(NULL);
1182 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); 1338 ASSERT_EQ(sql::INIT_OK, db.Init(db_path));
1183 1339
1184 // Verify that the resulting schema is correct, whether it 1340 // Verify that the resulting schema is correct, whether it
1185 // involved razing the file or fixing things in place. 1341 // involved razing the file or fixing things in place.
1186 VerifyTablesAndColumns(&db.db_); 1342 VerifyTablesAndColumns(&db.db_);
1187 } 1343 }
1188 } 1344 }
1189 1345
1190 } // namespace history 1346 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698