Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / prerender / prerender_tracker_unittest.cc
blob44e18246b8a1d4d785ffbf1a92a8e0471f062997
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
3 // found in the LICENSE file.
5 #include <set>
6 #include <utility>
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/threading/sequenced_worker_pool.h"
13 #include "chrome/browser/net/url_request_mock_util.h"
14 #include "chrome/browser/prerender/prerender_contents.h"
15 #include "chrome/browser/prerender/prerender_manager.h"
16 #include "chrome/browser/prerender/prerender_resource_throttle.h"
17 #include "chrome/browser/prerender/prerender_tracker.h"
18 #include "chrome/test/base/testing_browser_process.h"
19 #include "content/public/browser/resource_controller.h"
20 #include "content/public/browser/resource_request_info.h"
21 #include "content/public/test/test_browser_thread.h"
22 #include "content/test/net/url_request_mock_http_job.h"
23 #include "ipc/ipc_message.h"
24 #include "net/base/request_priority.h"
25 #include "net/url_request/url_request.h"
26 #include "net/url_request/url_request_test_util.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 using content::BrowserThread;
31 namespace prerender {
33 namespace {
35 class TestPrerenderContents : public PrerenderContents {
36 public:
37 TestPrerenderContents(PrerenderManager* prerender_manager,
38 int child_id, int route_id)
39 : PrerenderContents(prerender_manager, static_cast<Profile*>(NULL),
40 GURL(), content::Referrer(), ORIGIN_NONE,
41 PrerenderManager::kNoExperiment),
42 child_id_(child_id),
43 route_id_(route_id) {
44 PrerenderResourceThrottle::OverridePrerenderContentsForTesting(this);
47 virtual ~TestPrerenderContents() {
48 if (final_status() == FINAL_STATUS_MAX)
49 SetFinalStatus(FINAL_STATUS_USED);
50 PrerenderResourceThrottle::OverridePrerenderContentsForTesting(NULL);
53 virtual bool GetChildId(int* child_id) const OVERRIDE {
54 *child_id = child_id_;
55 return true;
58 virtual bool GetRouteId(int* route_id) const OVERRIDE {
59 *route_id = route_id_;
60 return true;
63 void Start() {
64 prerendering_has_started_ = true;
65 NotifyPrerenderStart();
68 void Cancel() {
69 Destroy(FINAL_STATUS_CANCELLED);
72 void Use() {
73 PrepareForUse();
76 private:
77 int child_id_;
78 int route_id_;
81 class TestPrerenderManager : public PrerenderManager {
82 public:
83 explicit TestPrerenderManager(PrerenderTracker* prerender_tracker) :
84 PrerenderManager(NULL, prerender_tracker) {
85 mutable_config().rate_limit_enabled = false;
88 // We never allocate our PrerenderContents in PrerenderManager, so we don't
89 // ever want the default pending delete behaviour.
90 virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
91 FinalStatus final_status) OVERRIDE {
95 class DeferredRedirectDelegate : public net::URLRequest::Delegate,
96 public content::ResourceController {
97 public:
98 DeferredRedirectDelegate()
99 : throttle_(NULL),
100 was_deferred_(false),
101 cancel_called_(false),
102 resume_called_(false) {
105 void SetThrottle(PrerenderResourceThrottle* throttle) {
106 throttle_ = throttle;
107 throttle_->set_controller_for_testing(this);
110 void Run() {
111 run_loop_.reset(new base::RunLoop());
112 run_loop_->Run();
115 bool was_deferred() const { return was_deferred_; }
116 bool cancel_called() const { return cancel_called_; }
117 bool resume_called() const { return resume_called_; }
119 // net::URLRequest::Delegate implementation:
120 virtual void OnReceivedRedirect(net::URLRequest* request,
121 const GURL& new_url,
122 bool* defer_redirect) OVERRIDE {
123 // Defer the redirect either way.
124 *defer_redirect = true;
126 // Find out what the throttle would have done.
127 throttle_->WillRedirectRequest(new_url, &was_deferred_);
128 run_loop_->Quit();
130 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE { }
131 virtual void OnReadCompleted(net::URLRequest* request,
132 int bytes_read) OVERRIDE {
135 // content::ResourceController implementation:
136 virtual void Cancel() OVERRIDE {
137 EXPECT_FALSE(cancel_called_);
138 EXPECT_FALSE(resume_called_);
140 cancel_called_ = true;
141 run_loop_->Quit();
143 virtual void CancelAndIgnore() OVERRIDE { Cancel(); }
144 virtual void CancelWithError(int error_code) OVERRIDE { Cancel(); }
145 virtual void Resume() OVERRIDE {
146 EXPECT_TRUE(was_deferred_);
147 EXPECT_FALSE(cancel_called_);
148 EXPECT_FALSE(resume_called_);
150 resume_called_ = true;
151 run_loop_->Quit();
154 private:
155 scoped_ptr<base::RunLoop> run_loop_;
156 PrerenderResourceThrottle* throttle_;
157 bool was_deferred_;
158 bool cancel_called_;
159 bool resume_called_;
161 DISALLOW_COPY_AND_ASSIGN(DeferredRedirectDelegate);
164 } // namespace
166 class PrerenderTrackerTest : public testing::Test {
167 public:
168 static const int kDefaultChildId = 0;
169 static const int kDefaultRouteId = 100;
171 PrerenderTrackerTest() :
172 ui_thread_(BrowserThread::UI, &message_loop_),
173 io_thread_(BrowserThread::IO, &message_loop_),
174 prerender_manager_(prerender_tracker()),
175 test_contents_(&prerender_manager_, kDefaultChildId, kDefaultRouteId) {
176 chrome_browser_net::SetUrlRequestMocksEnabled(true);
179 virtual ~PrerenderTrackerTest() {
180 chrome_browser_net::SetUrlRequestMocksEnabled(false);
182 // Cleanup work so the file IO tasks from URLRequestMockHTTPJob
183 // are gone.
184 content::BrowserThread::GetBlockingPool()->FlushForTesting();
185 RunEvents();
188 PrerenderTracker* prerender_tracker() {
189 return g_browser_process->prerender_tracker();
192 TestPrerenderManager* prerender_manager() {
193 return &prerender_manager_;
196 TestPrerenderContents* test_contents() {
197 return &test_contents_;
200 // Runs any tasks queued on either thread.
201 void RunEvents() {
202 message_loop_.RunUntilIdle();
205 private:
206 base::MessageLoopForIO message_loop_;
207 content::TestBrowserThread ui_thread_;
208 content::TestBrowserThread io_thread_;
210 TestPrerenderManager prerender_manager_;
211 TestPrerenderContents test_contents_;
214 // Checks that deferred redirects are throttled and resumed correctly.
215 TEST_F(PrerenderTrackerTest, PrerenderThrottledRedirectResume) {
216 const base::FilePath::CharType kRedirectPath[] =
217 FILE_PATH_LITERAL("prerender/image-deferred.png");
219 test_contents()->Start();
220 RunEvents();
222 // Fake a request.
223 net::TestURLRequestContext url_request_context;
224 DeferredRedirectDelegate delegate;
225 net::URLRequest request(
226 content::URLRequestMockHTTPJob::GetMockUrl(base::FilePath(kRedirectPath)),
227 net::DEFAULT_PRIORITY,
228 &delegate,
229 &url_request_context);
230 content::ResourceRequestInfo::AllocateForTesting(
231 &request, ResourceType::IMAGE, NULL,
232 kDefaultChildId, kDefaultRouteId, MSG_ROUTING_NONE, true);
234 // Install a prerender throttle.
235 PrerenderResourceThrottle throttle(&request);
236 delegate.SetThrottle(&throttle);
238 // Start the request and wait for a redirect.
239 request.Start();
240 delegate.Run();
241 EXPECT_TRUE(delegate.was_deferred());
242 // This calls WillRedirectRequestOnUI().
243 RunEvents();
245 // Display the prerendered RenderView and wait for the throttle to
246 // notice.
247 test_contents()->Use();
248 delegate.Run();
249 EXPECT_TRUE(delegate.resume_called());
250 EXPECT_FALSE(delegate.cancel_called());
253 // Checks that redirects in main frame loads are not deferred.
254 TEST_F(PrerenderTrackerTest, PrerenderThrottledRedirectMainFrame) {
255 const base::FilePath::CharType kRedirectPath[] =
256 FILE_PATH_LITERAL("prerender/image-deferred.png");
258 test_contents()->Start();
259 RunEvents();
261 // Fake a request.
262 net::TestURLRequestContext url_request_context;
263 DeferredRedirectDelegate delegate;
264 net::URLRequest request(
265 content::URLRequestMockHTTPJob::GetMockUrl(base::FilePath(kRedirectPath)),
266 net::DEFAULT_PRIORITY,
267 &delegate,
268 &url_request_context);
269 content::ResourceRequestInfo::AllocateForTesting(
270 &request, ResourceType::MAIN_FRAME, NULL,
271 kDefaultChildId, kDefaultRouteId, MSG_ROUTING_NONE, true);
273 // Install a prerender throttle.
274 PrerenderResourceThrottle throttle(&request);
275 delegate.SetThrottle(&throttle);
277 // Start the request and wait for a redirect. This time, it should
278 // not be deferred.
279 request.Start();
280 delegate.Run();
281 // This calls WillRedirectRequestOnUI().
282 RunEvents();
284 // Cleanup work so the prerender is gone.
285 test_contents()->Cancel();
286 RunEvents();
289 // Checks that attempting to defer a synchronous request aborts the
290 // prerender.
291 TEST_F(PrerenderTrackerTest, PrerenderThrottledRedirectSyncXHR) {
292 const base::FilePath::CharType kRedirectPath[] =
293 FILE_PATH_LITERAL("prerender/image-deferred.png");
295 test_contents()->Start();
296 RunEvents();
298 // Fake a request.
299 net::TestURLRequestContext url_request_context;
300 DeferredRedirectDelegate delegate;
301 net::URLRequest request(
302 content::URLRequestMockHTTPJob::GetMockUrl(base::FilePath(kRedirectPath)),
303 net::DEFAULT_PRIORITY,
304 &delegate,
305 &url_request_context);
306 content::ResourceRequestInfo::AllocateForTesting(
307 &request, ResourceType::XHR, NULL,
308 kDefaultChildId, kDefaultRouteId, MSG_ROUTING_NONE, false);
310 // Install a prerender throttle.
311 PrerenderResourceThrottle throttle(&request);
312 delegate.SetThrottle(&throttle);
314 // Start the request and wait for a redirect.
315 request.Start();
316 delegate.Run();
317 // This calls WillRedirectRequestOnUI().
318 RunEvents();
320 // We should have cancelled the prerender.
321 EXPECT_EQ(FINAL_STATUS_BAD_DEFERRED_REDIRECT,
322 test_contents()->final_status());
324 // Cleanup work so the prerender is gone.
325 test_contents()->Cancel();
326 RunEvents();
329 } // namespace prerender