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

Side by Side Diff: components/favicon/core/favicon_handler_unittest.cc

Issue 2781093002: Add attempt count metric to FaviconHandler (Closed)
Patch Set: Created 3 years, 8 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 "components/favicon/core/favicon_handler.h" 5 #include "components/favicon/core/favicon_handler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <set> 10 #include <set>
11 #include <string>
11 #include <vector> 12 #include <vector>
12 13
13 #include "base/macros.h" 14 #include "base/macros.h"
14 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
15 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 17 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/test/histogram_tester.h"
18 #include "components/favicon/core/favicon_driver.h" 20 #include "components/favicon/core/favicon_driver.h"
19 #include "components/favicon/core/test/mock_favicon_service.h" 21 #include "components/favicon/core/test/mock_favicon_service.h"
20 #include "testing/gmock/include/gmock/gmock.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/skia/include/core/SkBitmap.h" 24 #include "third_party/skia/include/core/SkBitmap.h"
23 #include "ui/base/layout.h" 25 #include "ui/base/layout.h"
24 #include "ui/gfx/codec/png_codec.h" 26 #include "ui/gfx/codec/png_codec.h"
25 #include "ui/gfx/favicon_size.h" 27 #include "ui/gfx/favicon_size.h"
26 #include "ui/gfx/image/image.h" 28 #include "ui/gfx/image/image.h"
27 29
28 namespace favicon { 30 namespace favicon {
29 namespace { 31 namespace {
30 32
31 using favicon_base::FAVICON; 33 using favicon_base::FAVICON;
32 using favicon_base::FaviconRawBitmapResult; 34 using favicon_base::FaviconRawBitmapResult;
33 using favicon_base::TOUCH_ICON; 35 using favicon_base::TOUCH_ICON;
34 using favicon_base::TOUCH_PRECOMPOSED_ICON; 36 using favicon_base::TOUCH_PRECOMPOSED_ICON;
35 using testing::Assign; 37 using testing::Assign;
38 using testing::Contains;
36 using testing::ElementsAre; 39 using testing::ElementsAre;
37 using testing::InSequence; 40 using testing::InSequence;
38 using testing::Invoke; 41 using testing::Invoke;
39 using testing::IsEmpty; 42 using testing::IsEmpty;
40 using testing::Return; 43 using testing::Return;
41 using testing::_; 44 using testing::_;
42 45
43 using IntVector = std::vector<int>; 46 using IntVector = std::vector<int>;
44 using URLVector = std::vector<GURL>; 47 using URLVector = std::vector<GURL>;
45 using BitmapVector = std::vector<SkBitmap>; 48 using BitmapVector = std::vector<SkBitmap>;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 FaviconRawBitmapResult bitmap_result; 86 FaviconRawBitmapResult bitmap_result;
84 bitmap_result.expired = expired; 87 bitmap_result.expired = expired;
85 bitmap_result.bitmap_data = data; 88 bitmap_result.bitmap_data = data;
86 // Use a pixel size other than (0,0) as (0,0) has a special meaning. 89 // Use a pixel size other than (0,0) as (0,0) has a special meaning.
87 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); 90 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
88 bitmap_result.icon_type = icon_type; 91 bitmap_result.icon_type = icon_type;
89 bitmap_result.icon_url = icon_url; 92 bitmap_result.icon_url = icon_url;
90 return {bitmap_result}; 93 return {bitmap_result};
91 } 94 }
92 95
93 // Fake that implements the calls to FaviconHalder::Delegate's DownloadImage(), 96 // Fake that implements the calls to FaviconHandler::Delegate's DownloadImage(),
94 // delegated to this class through MockDelegate. 97 // delegated to this class through MockDelegate.
95 class FakeImageDownloader { 98 class FakeImageDownloader {
96 public: 99 public:
97 struct Response { 100 struct Response {
98 int http_status_code = 404; 101 int http_status_code = 404;
99 BitmapVector bitmaps; 102 BitmapVector bitmaps;
100 SizeVector original_bitmap_sizes; 103 SizeVector original_bitmap_sizes;
101 }; 104 };
102 105
103 FakeImageDownloader() : next_download_id_(1) {} 106 FakeImageDownloader() : next_download_id_(1) {}
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 protected: 317 protected:
315 const std::vector<gfx::Size> kEmptySizes; 318 const std::vector<gfx::Size> kEmptySizes;
316 319
317 // Some known icons for which download will succeed. 320 // Some known icons for which download will succeed.
318 const GURL kPageURL = GURL("http://www.google.com"); 321 const GURL kPageURL = GURL("http://www.google.com");
319 const GURL kIconURL10x10 = GURL("http://www.google.com/favicon10x10"); 322 const GURL kIconURL10x10 = GURL("http://www.google.com/favicon10x10");
320 const GURL kIconURL12x12 = GURL("http://www.google.com/favicon12x12"); 323 const GURL kIconURL12x12 = GURL("http://www.google.com/favicon12x12");
321 const GURL kIconURL16x16 = GURL("http://www.google.com/favicon16x16"); 324 const GURL kIconURL16x16 = GURL("http://www.google.com/favicon16x16");
322 const GURL kIconURL64x64 = GURL("http://www.google.com/favicon64x64"); 325 const GURL kIconURL64x64 = GURL("http://www.google.com/favicon64x64");
323 326
324 FaviconHandlerTest() { 327 FaviconHandlerTest() : download_histogram_(new base::HistogramTester()) {
325 // Register various known icon URLs. 328 // Register various known icon URLs.
326 delegate_.fake_downloader().Add(kIconURL10x10, IntVector{10}); 329 delegate_.fake_downloader().Add(kIconURL10x10, IntVector{10});
327 delegate_.fake_downloader().Add(kIconURL12x12, IntVector{12}); 330 delegate_.fake_downloader().Add(kIconURL12x12, IntVector{12});
328 delegate_.fake_downloader().Add(kIconURL16x16, IntVector{16}); 331 delegate_.fake_downloader().Add(kIconURL16x16, IntVector{16});
329 delegate_.fake_downloader().Add(kIconURL64x64, IntVector{64}); 332 delegate_.fake_downloader().Add(kIconURL64x64, IntVector{64});
330 333
331 // The score computed by SelectFaviconFrames() is dependent on the supported 334 // The score computed by SelectFaviconFrames() is dependent on the supported
332 // scale factors of the platform. It is used for determining the goodness of 335 // scale factors of the platform. It is used for determining the goodness of
333 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon(). 336 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon().
334 // Force the values of the scale factors so that the tests produce the same 337 // Force the values of the scale factors so that the tests produce the same
335 // results on all platforms. 338 // results on all platforms.
336 scoped_set_supported_scale_factors_.reset( 339 scoped_set_supported_scale_factors_.reset(
337 new ui::test::ScopedSetSupportedScaleFactors({ui::SCALE_FACTOR_100P})); 340 new ui::test::ScopedSetSupportedScaleFactors({ui::SCALE_FACTOR_100P}));
338 } 341 }
339 342
343 void TearDown() override {
344 // Check that if any downloads occurred, the attempt count was recorded.
345 if (!download_histogram_name_.empty() && delegate_.downloads().size() > 0) {
346 download_histogram_->ExpectBucketCount(
347 download_histogram_name_,
348 /*sample=*/delegate_.downloads().size(),
349 /*expected_count=*/1);
350 }
351 }
352
340 bool VerifyAndClearExpectations() { 353 bool VerifyAndClearExpectations() {
341 base::RunLoop().RunUntilIdle(); 354 base::RunLoop().RunUntilIdle();
342 favicon_service_.fake()->ClearDbRequests(); 355 favicon_service_.fake()->ClearDbRequests();
343 delegate_.fake_downloader().ClearDownloads(); 356 delegate_.fake_downloader().ClearDownloads();
357 // Drop download histogram without verification.
358 download_histogram_ = base::MakeUnique<base::HistogramTester>();
344 return testing::Mock::VerifyAndClearExpectations(&favicon_service_) && 359 return testing::Mock::VerifyAndClearExpectations(&favicon_service_) &&
345 testing::Mock::VerifyAndClearExpectations(&delegate_); 360 testing::Mock::VerifyAndClearExpectations(&delegate_);
346 } 361 }
347 362
348 // Creates a new handler and feeds in the page URL and the candidates. 363 // Creates a new handler and feeds in the page URL and the candidates.
349 // Returns the handler in case tests want to exercise further steps. 364 // Returns the handler in case tests want to exercise further steps.
350 std::unique_ptr<FaviconHandler> RunHandlerWithCandidates( 365 std::unique_ptr<FaviconHandler> RunHandlerWithCandidates(
351 FaviconDriverObserver::NotificationIconType handler_type, 366 FaviconDriverObserver::NotificationIconType handler_type,
352 const std::vector<favicon::FaviconURL>& candidates) { 367 const std::vector<favicon::FaviconURL>& candidates) {
368 download_histogram_name_ =
369 handler_type == FaviconDriverObserver::TOUCH_LARGEST
370 ? "Favicons.LargeIconDownloadAttempts"
371 : "Favicons.DownloadAttempts";
353 auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_, 372 auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_,
354 &delegate_, handler_type); 373 &delegate_, handler_type);
355 handler->FetchFavicon(kPageURL); 374 handler->FetchFavicon(kPageURL);
356 // The first RunUntilIdle() causes the FaviconService lookups be faster than 375 // The first RunUntilIdle() causes the FaviconService lookups be faster than
357 // OnUpdateFaviconURL(), which is the most likely scenario. 376 // OnUpdateFaviconURL(), which is the most likely scenario.
358 base::RunLoop().RunUntilIdle(); 377 base::RunLoop().RunUntilIdle();
359 handler->OnUpdateFaviconURL(kPageURL, candidates); 378 handler->OnUpdateFaviconURL(kPageURL, candidates);
360 base::RunLoop().RunUntilIdle(); 379 base::RunLoop().RunUntilIdle();
361 return handler; 380 return handler;
362 } 381 }
363 382
364 // Same as above, but for the simplest case where all types are FAVICON and 383 // Same as above, but for the simplest case where all types are FAVICON and
365 // no sizes are provided, using a FaviconHandler of type NON_TOUCH_16_DIP. 384 // no sizes are provided, using a FaviconHandler of type NON_TOUCH_16_DIP.
366 std::unique_ptr<FaviconHandler> RunHandlerWithSimpleFaviconCandidates( 385 std::unique_ptr<FaviconHandler> RunHandlerWithSimpleFaviconCandidates(
367 const std::vector<GURL>& urls) { 386 const std::vector<GURL>& urls) {
368 std::vector<favicon::FaviconURL> candidates; 387 std::vector<favicon::FaviconURL> candidates;
369 for (const GURL& url : urls) { 388 for (const GURL& url : urls) {
370 candidates.emplace_back(url, FAVICON, kEmptySizes); 389 candidates.emplace_back(url, FAVICON, kEmptySizes);
371 } 390 }
372 return RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, 391 return RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP,
373 candidates); 392 candidates);
374 } 393 }
375 394
395 std::string download_histogram_name_;
376 base::MessageLoopForUI message_loop_; 396 base::MessageLoopForUI message_loop_;
377 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors> 397 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors>
378 scoped_set_supported_scale_factors_; 398 scoped_set_supported_scale_factors_;
399 std::unique_ptr<base::HistogramTester> download_histogram_;
379 testing::NiceMock<MockFaviconServiceWithFake> favicon_service_; 400 testing::NiceMock<MockFaviconServiceWithFake> favicon_service_;
380 testing::NiceMock<MockDelegate> delegate_; 401 testing::NiceMock<MockDelegate> delegate_;
381 }; 402 };
382 403
383 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { 404 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
384 const GURL kIconURL("http://www.google.com/favicon"); 405 const GURL kIconURL("http://www.google.com/favicon");
385 406
386 favicon_service_.fake()->Store(kPageURL, kIconURL, 407 favicon_service_.fake()->Store(kPageURL, kIconURL,
387 CreateRawBitmapResult(kIconURL)); 408 CreateRawBitmapResult(kIconURL));
388 409
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 // Defer the download completion such that RunUntilIdle() doesn't complete 621 // Defer the download completion such that RunUntilIdle() doesn't complete
601 // the download. 622 // the download.
602 delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kIconURL1); 623 delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kIconURL1);
603 624
604 delegate_.fake_downloader().Add(kIconURL1, IntVector{16}); 625 delegate_.fake_downloader().Add(kIconURL1, IntVector{16});
605 delegate_.fake_downloader().Add(kIconURL3, IntVector{64}); 626 delegate_.fake_downloader().Add(kIconURL3, IntVector{64});
606 627
607 std::unique_ptr<FaviconHandler> handler = 628 std::unique_ptr<FaviconHandler> handler =
608 RunHandlerWithSimpleFaviconCandidates({kIconURL1, kIconURL2}); 629 RunHandlerWithSimpleFaviconCandidates({kIconURL1, kIconURL2});
609 630
631 download_histogram_->ExpectTotalCount("Favicons.DownloadAttempts", 0);
610 ASSERT_TRUE(VerifyAndClearExpectations()); 632 ASSERT_TRUE(VerifyAndClearExpectations());
611 ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback()); 633 ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
612 634
613 // Favicon update should invalidate the ongoing download. 635 // Favicon update should invalidate the ongoing download.
614 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL3, _, _)); 636 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL3, _, _));
615 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL3, _, _)); 637 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL3, _, _));
616 638
617 handler->OnUpdateFaviconURL(kPageURL, 639 handler->OnUpdateFaviconURL(kPageURL,
618 {FaviconURL(kIconURL3, FAVICON, kEmptySizes)}); 640 {FaviconURL(kIconURL3, FAVICON, kEmptySizes)});
619 641
(...skipping 19 matching lines...) Expand all
639 // Defer the download completion such that RunUntilIdle() doesn't complete 661 // Defer the download completion such that RunUntilIdle() doesn't complete
640 // the download. 662 // the download.
641 delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kSlowLoadingIconURL); 663 delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kSlowLoadingIconURL);
642 delegate_.fake_downloader().Add(kSlowLoadingIconURL, IntVector{16}); 664 delegate_.fake_downloader().Add(kSlowLoadingIconURL, IntVector{16});
643 665
644 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( 666 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
645 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls); 667 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
646 668
647 ASSERT_THAT(favicon_service_.fake()->db_requests(), 669 ASSERT_THAT(favicon_service_.fake()->db_requests(),
648 ElementsAre(kPageURL, kIconURL64x64, kSlowLoadingIconURL)); 670 ElementsAre(kPageURL, kIconURL64x64, kSlowLoadingIconURL));
671 download_histogram_->ExpectTotalCount("Favicons.DownloadAttempts", 0);
649 ASSERT_TRUE(VerifyAndClearExpectations()); 672 ASSERT_TRUE(VerifyAndClearExpectations());
650 ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback()); 673 ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
651 674
652 // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect, 675 // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect,
653 // despite the ongoing download. 676 // despite the ongoing download.
654 handler->OnUpdateFaviconURL(kPageURL, favicon_urls); 677 handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
655 base::RunLoop().RunUntilIdle(); 678 base::RunLoop().RunUntilIdle();
656 679
657 // Complete the download. 680 // Complete the download.
658 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)); 681 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _));
659 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)); 682 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _));
660 EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually()); 683 EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually());
661 base::RunLoop().RunUntilIdle(); 684 base::RunLoop().RunUntilIdle();
662 EXPECT_THAT(delegate_.downloads(), IsEmpty()); 685 EXPECT_THAT(delegate_.downloads(), IsEmpty());
663 } 686 }
664 687
665 // Test that calling OnUpdateFaviconUrl() with the same icon URLs as before is a 688 // Test that calling OnUpdateFaviconUrl() with the same icon URLs as before is a
666 // no-op. This is important because OnUpdateFaviconUrl() is called when the page 689 // no-op. This is important because OnUpdateFaviconUrl() is called when the page
667 // finishes loading. This can occur several times for pages with iframes. 690 // finishes loading. This can occur several times for pages with iframes.
668 TEST_F(FaviconHandlerTest, UpdateSameIconURLsAfterFinishedShouldBeNoop) { 691 TEST_F(FaviconHandlerTest, UpdateSameIconURLsAfterFinishedShouldBeNoop) {
669 const std::vector<FaviconURL> favicon_urls = { 692 const std::vector<FaviconURL> favicon_urls = {
670 FaviconURL(kIconURL10x10, FAVICON, kEmptySizes), 693 FaviconURL(kIconURL10x10, FAVICON, kEmptySizes),
671 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes), 694 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes),
672 }; 695 };
673 696
674 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( 697 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
675 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls); 698 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
676 699
700 download_histogram_->ExpectBucketCount(
701 "Favicons.DownloadAttempts",
702 /*sample=*/delegate_.downloads().size(),
703 /*expected_count=*/1);
677 ASSERT_TRUE(VerifyAndClearExpectations()); 704 ASSERT_TRUE(VerifyAndClearExpectations());
678 705
679 // Calling OnUpdateFaviconURL() with identical data should be a no-op. 706 // Calling OnUpdateFaviconURL() with identical data should be a no-op.
680 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0); 707 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
681 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0); 708 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
682 709
683 handler->OnUpdateFaviconURL(kPageURL, favicon_urls); 710 handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
684 base::RunLoop().RunUntilIdle(); 711 base::RunLoop().RunUntilIdle();
685 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty()); 712 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
686 EXPECT_THAT(delegate_.downloads(), IsEmpty()); 713 EXPECT_THAT(delegate_.downloads(), IsEmpty());
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 1044
1018 RunHandlerWithCandidates( 1045 RunHandlerWithCandidates(
1019 FaviconDriverObserver::NON_TOUCH_LARGEST, 1046 FaviconDriverObserver::NON_TOUCH_LARGEST,
1020 {FaviconURL(kIconURL10x10, FAVICON, SizeVector{gfx::Size(16, 16)}), 1047 {FaviconURL(kIconURL10x10, FAVICON, SizeVector{gfx::Size(16, 16)}),
1021 FaviconURL(kIconURL12x12, FAVICON, SizeVector{gfx::Size(15, 15)}), 1048 FaviconURL(kIconURL12x12, FAVICON, SizeVector{gfx::Size(15, 15)}),
1022 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); 1049 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)});
1023 } 1050 }
1024 1051
1025 } // namespace 1052 } // namespace
1026 } // namespace favicon 1053 } // namespace favicon
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698