Make castv2 performance test work.
[chromium-blink-merge.git] / chrome / browser / favicon / favicon_tab_helper_browsertest.cc
blob25e2223b34339986eef90f6b4aac057153912b34
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
3 // found in the LICENSE file.
5 #include "chrome/browser/favicon/favicon_tab_helper.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/run_loop.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_commands.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "components/favicon/core/favicon_handler.h"
17 #include "content/public/browser/notification_observer.h"
18 #include "content/public/browser/notification_registrar.h"
19 #include "content/public/browser/notification_types.h"
20 #include "content/public/browser/resource_dispatcher_host.h"
21 #include "content/public/browser/resource_dispatcher_host_delegate.h"
22 #include "net/base/load_flags.h"
23 #include "net/test/spawned_test_server/spawned_test_server.h"
24 #include "net/url_request/url_request.h"
25 #include "url/url_constants.h"
27 namespace {
29 // Tracks whether the URL passed to the constructor is requested and whether
30 // the request bypasses the cache.
31 class TestResourceDispatcherHostDelegate
32 : public content::ResourceDispatcherHostDelegate {
33 public:
34 explicit TestResourceDispatcherHostDelegate(const GURL& url)
35 : url_(url), was_requested_(false), bypassed_cache_(false) {}
36 ~TestResourceDispatcherHostDelegate() override {}
38 void Reset() {
39 was_requested_ = false;
40 bypassed_cache_ = false;
43 // Resturns whether |url_| was requested.
44 bool was_requested() const { return was_requested_; }
46 // Returns whether any of the requests bypassed the HTTP cache.
47 bool bypassed_cache() const { return bypassed_cache_; }
49 private:
50 // content::ResourceDispatcherHostDelegate:
51 bool ShouldBeginRequest(const std::string& method,
52 const GURL& url,
53 content::ResourceType resource_type,
54 content::ResourceContext* resource_context) override {
55 return true;
58 void RequestBeginning(
59 net::URLRequest* request,
60 content::ResourceContext* resource_context,
61 content::AppCacheService* appcache_service,
62 content::ResourceType resource_type,
63 ScopedVector<content::ResourceThrottle>* throttles) override {
64 if (request->url() == url_) {
65 was_requested_ = true;
66 if (request->load_flags() & net::LOAD_BYPASS_CACHE)
67 bypassed_cache_ = true;
71 void DownloadStarting(
72 net::URLRequest* request,
73 content::ResourceContext* resource_context,
74 int child_id,
75 int route_id,
76 int request_id,
77 bool is_content_initiated,
78 bool must_download,
79 ScopedVector<content::ResourceThrottle>* throttles) override {}
81 private:
82 GURL url_;
83 bool was_requested_;
84 bool bypassed_cache_;
86 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
89 // Checks whether the FaviconTabHelper is waiting for a download to complete or
90 // for data from the FaviconService.
91 class FaviconTabHelperPendingTaskChecker {
92 public:
93 virtual ~FaviconTabHelperPendingTaskChecker() {}
95 virtual bool HasPendingTasks() = 0;
98 // Waits for the following the finish:
99 // - The pending navigation.
100 // - FaviconHandler's pending favicon database requests.
101 // - FaviconHandler's pending downloads.
102 class PendingTaskWaiter : public content::NotificationObserver {
103 public:
104 PendingTaskWaiter(content::WebContents* web_contents,
105 FaviconTabHelperPendingTaskChecker* checker)
106 : checker_(checker), load_stopped_(false), weak_factory_(this) {
107 registrar_.Add(this, chrome::NOTIFICATION_FAVICON_UPDATED,
108 content::Source<content::WebContents>(web_contents));
109 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
110 content::Source<content::NavigationController>(
111 &web_contents->GetController()));
113 ~PendingTaskWaiter() override {}
115 void Wait() {
116 if (load_stopped_ && !checker_->HasPendingTasks())
117 return;
119 base::RunLoop run_loop;
120 quit_closure_ = run_loop.QuitClosure();
121 run_loop.Run();
124 private:
125 // content::NotificationObserver:
126 void Observe(int type,
127 const content::NotificationSource& source,
128 const content::NotificationDetails& details) override {
129 if (type == content::NOTIFICATION_LOAD_STOP)
130 load_stopped_ = true;
132 if (!quit_closure_.is_null()) {
133 // We stop waiting based on changes in state to FaviconHandler which occur
134 // immediately after NOTIFICATION_FAVICON_UPDATED is sent. Post a task to
135 // check if we can stop waiting.
136 base::MessageLoopForUI::current()->PostTask(
137 FROM_HERE, base::Bind(&PendingTaskWaiter::EndLoopIfCanStopWaiting,
138 weak_factory_.GetWeakPtr()));
142 void EndLoopIfCanStopWaiting() {
143 if (!quit_closure_.is_null() &&
144 load_stopped_ &&
145 !checker_->HasPendingTasks()) {
146 quit_closure_.Run();
150 FaviconTabHelperPendingTaskChecker* checker_; // Not owned.
151 bool load_stopped_;
152 base::Closure quit_closure_;
153 content::NotificationRegistrar registrar_;
154 base::WeakPtrFactory<PendingTaskWaiter> weak_factory_;
156 DISALLOW_COPY_AND_ASSIGN(PendingTaskWaiter);
159 } // namespace
161 class FaviconTabHelperTest : public InProcessBrowserTest,
162 public FaviconTabHelperPendingTaskChecker {
163 public:
164 FaviconTabHelperTest() {}
165 ~FaviconTabHelperTest() override {}
167 content::WebContents* web_contents() {
168 return browser()->tab_strip_model()->GetActiveWebContents();
171 // FaviconTabHelperPendingTaskChecker:
172 bool HasPendingTasks() override {
173 favicon::FaviconHandler* favicon_handler =
174 FaviconTabHelper::FromWebContents(web_contents())
175 ->favicon_handler_.get();
176 return !favicon_handler->download_requests_.empty() ||
177 favicon_handler->cancelable_task_tracker_.HasTrackedTasks();
180 private:
181 DISALLOW_COPY_AND_ASSIGN(FaviconTabHelperTest);
184 // Test that when a user reloads a page ignoring the cache that the favicon is
185 // is redownloaded and (not returned from either the favicon cache or the HTTP
186 // cache).
187 IN_PROC_BROWSER_TEST_F(FaviconTabHelperTest, ReloadIgnoringCache) {
188 ASSERT_TRUE(test_server()->Start());
189 GURL url = test_server()->GetURL("files/favicon/page_with_favicon.html");
190 GURL icon_url = test_server()->GetURL("files/favicon/icon.ico");
192 scoped_ptr<TestResourceDispatcherHostDelegate> delegate(
193 new TestResourceDispatcherHostDelegate(icon_url));
194 content::ResourceDispatcherHost::Get()->SetDelegate(delegate.get());
196 // Initial visit in order to populate the cache.
198 PendingTaskWaiter waiter(web_contents(), this);
199 ui_test_utils::NavigateToURLWithDisposition(
200 browser(), url, CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
201 waiter.Wait();
203 ASSERT_TRUE(delegate->was_requested());
204 EXPECT_FALSE(delegate->bypassed_cache());
205 delegate->Reset();
207 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
209 // A normal visit should fetch the favicon from either the favicon database or
210 // the HTTP cache.
212 PendingTaskWaiter waiter(web_contents(), this);
213 ui_test_utils::NavigateToURLWithDisposition(
214 browser(), url, CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
215 waiter.Wait();
217 EXPECT_FALSE(delegate->bypassed_cache());
218 delegate->Reset();
220 // A reload ignoring the cache should refetch the favicon from the website.
222 PendingTaskWaiter waiter(web_contents(), this);
223 chrome::ExecuteCommand(browser(), IDC_RELOAD_IGNORING_CACHE);
224 waiter.Wait();
226 ASSERT_TRUE(delegate->was_requested());
227 EXPECT_TRUE(delegate->bypassed_cache());