cc: Remove unused disable_hi_res_timer_tasks_on_battery flag.
[chromium-blink-merge.git] / content / renderer / resource_fetcher_browsertest.cc
blobfee84ee8779d1f96a8bd758cee1e77145d8b50a1
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 "content/public/renderer/resource_fetcher.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/time/time.h"
12 #include "base/timer/timer.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/public/common/url_constants.h"
15 #include "content/public/renderer/render_view.h"
16 #include "content/public/test/content_browser_test.h"
17 #include "content/public/test/content_browser_test_utils.h"
18 #include "content/public/test/routing_id_mangling_disabler.h"
19 #include "content/public/test/test_utils.h"
20 #include "content/shell/browser/shell.h"
21 #include "third_party/WebKit/public/platform/WebURLResponse.h"
22 #include "third_party/WebKit/public/web/WebFrame.h"
23 #include "third_party/WebKit/public/web/WebView.h"
25 using blink::WebFrame;
26 using blink::WebURLRequest;
27 using blink::WebURLResponse;
29 namespace {
31 // The first RenderFrame is routing ID 1, and the first RenderView is 2.
32 const int kRenderViewRoutingId = 2;
36 namespace content {
38 static const int kMaxWaitTimeMs = 5000;
40 class FetcherDelegate {
41 public:
42 FetcherDelegate()
43 : completed_(false),
44 timed_out_(false) {
45 // Start a repeating timer waiting for the download to complete. The
46 // callback has to be a static function, so we hold on to our instance.
47 FetcherDelegate::instance_ = this;
48 StartTimer();
51 virtual ~FetcherDelegate() {}
53 ResourceFetcher::Callback NewCallback() {
54 return base::Bind(&FetcherDelegate::OnURLFetchComplete,
55 base::Unretained(this));
58 virtual void OnURLFetchComplete(const WebURLResponse& response,
59 const std::string& data) {
60 response_ = response;
61 data_ = data;
62 completed_ = true;
63 timer_.Stop();
64 if (!timed_out_)
65 quit_task_.Run();
68 bool completed() const { return completed_; }
69 bool timed_out() const { return timed_out_; }
71 std::string data() const { return data_; }
72 const WebURLResponse& response() const { return response_; }
74 // Wait for the request to complete or timeout.
75 void WaitForResponse() {
76 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
77 quit_task_ = runner->QuitClosure();
78 runner->Run();
81 void StartTimer() {
82 timer_.Start(FROM_HERE,
83 base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs),
84 this,
85 &FetcherDelegate::TimerFired);
88 void TimerFired() {
89 ASSERT_FALSE(completed_);
91 timed_out_ = true;
92 if (!completed_)
93 quit_task_.Run();
94 FAIL() << "fetch timed out";
97 static FetcherDelegate* instance_;
99 private:
100 base::OneShotTimer<FetcherDelegate> timer_;
101 bool completed_;
102 bool timed_out_;
103 WebURLResponse response_;
104 std::string data_;
105 base::Closure quit_task_;
108 FetcherDelegate* FetcherDelegate::instance_ = NULL;
110 class EvilFetcherDelegate : public FetcherDelegate {
111 public:
112 ~EvilFetcherDelegate() override {}
114 void SetFetcher(ResourceFetcher* fetcher) {
115 fetcher_.reset(fetcher);
118 void OnURLFetchComplete(const WebURLResponse& response,
119 const std::string& data) override {
120 FetcherDelegate::OnURLFetchComplete(response, data);
122 // Destroy the ResourceFetcher here. We are testing that upon returning
123 // to the ResourceFetcher that it does not crash. This must be done after
124 // calling FetcherDelegate::OnURLFetchComplete, since deleting the fetcher
125 // invalidates |response| and |data|.
126 fetcher_.reset();
129 private:
130 scoped_ptr<ResourceFetcher> fetcher_;
133 class ResourceFetcherTests : public ContentBrowserTest {
134 public:
135 void SetUpCommandLine(base::CommandLine* command_line) override {
136 command_line->AppendSwitch(switches::kSingleProcess);
137 #if defined(OS_WIN)
138 // Don't want to try to create a GPU process.
139 command_line->AppendSwitch(switches::kDisableGpu);
140 #endif
143 RenderView* GetRenderView() {
144 // We could have the test on the UI thread get the WebContent's routing ID,
145 // but we know this will be the first RV so skip that and just hardcode it.
146 return RenderView::FromRoutingID(kRenderViewRoutingId);
149 void ResourceFetcherDownloadOnRenderer(const GURL& url) {
150 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
152 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
153 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
154 fetcher->Start(frame,
155 WebURLRequest::RequestContextInternal,
156 WebURLRequest::FrameTypeNone,
157 ResourceFetcher::PLATFORM_LOADER,
158 delegate->NewCallback());
160 delegate->WaitForResponse();
162 ASSERT_TRUE(delegate->completed());
163 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
164 std::string text = delegate->data();
165 EXPECT_TRUE(text.find("Basic html test.") != std::string::npos);
168 void ResourceFetcher404OnRenderer(const GURL& url) {
169 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
171 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
172 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
173 fetcher->Start(frame,
174 WebURLRequest::RequestContextInternal,
175 WebURLRequest::FrameTypeNone,
176 ResourceFetcher::PLATFORM_LOADER,
177 delegate->NewCallback());
179 delegate->WaitForResponse();
181 ASSERT_TRUE(delegate->completed());
182 EXPECT_EQ(delegate->response().httpStatusCode(), 404);
183 EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos);
186 void ResourceFetcherDidFailOnRenderer() {
187 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
189 // Try to fetch a page on a site that doesn't exist.
190 GURL url("http://localhost:1339/doesnotexist");
191 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
192 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
193 fetcher->Start(frame,
194 WebURLRequest::RequestContextInternal,
195 WebURLRequest::FrameTypeNone,
196 ResourceFetcher::PLATFORM_LOADER,
197 delegate->NewCallback());
199 delegate->WaitForResponse();
201 // When we fail, we still call the Delegate callback but we pass in empty
202 // values.
203 EXPECT_TRUE(delegate->completed());
204 EXPECT_TRUE(delegate->response().isNull());
205 EXPECT_EQ(delegate->data(), std::string());
206 EXPECT_FALSE(delegate->timed_out());
209 void ResourceFetcherTimeoutOnRenderer(const GURL& url) {
210 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
212 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
213 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
214 fetcher->Start(frame,
215 WebURLRequest::RequestContextInternal,
216 WebURLRequest::FrameTypeNone,
217 ResourceFetcher::PLATFORM_LOADER,
218 delegate->NewCallback());
219 fetcher->SetTimeout(base::TimeDelta());
221 delegate->WaitForResponse();
223 // When we timeout, we still call the Delegate callback but we pass in empty
224 // values.
225 EXPECT_TRUE(delegate->completed());
226 EXPECT_TRUE(delegate->response().isNull());
227 EXPECT_EQ(delegate->data(), std::string());
228 EXPECT_FALSE(delegate->timed_out());
231 void ResourceFetcherDeletedInCallbackOnRenderer(const GURL& url) {
232 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
234 scoped_ptr<EvilFetcherDelegate> delegate(new EvilFetcherDelegate);
235 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
236 fetcher->Start(frame,
237 WebURLRequest::RequestContextInternal,
238 WebURLRequest::FrameTypeNone,
239 ResourceFetcher::PLATFORM_LOADER,
240 delegate->NewCallback());
241 fetcher->SetTimeout(base::TimeDelta());
242 delegate->SetFetcher(fetcher.release());
244 delegate->WaitForResponse();
245 EXPECT_FALSE(delegate->timed_out());
248 void ResourceFetcherPost(const GURL& url) {
249 const char* kBody = "Really nifty POST body!";
251 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
253 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
254 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
255 fetcher->SetMethod("POST");
256 fetcher->SetBody(kBody);
257 fetcher->Start(frame,
258 WebURLRequest::RequestContextInternal,
259 WebURLRequest::FrameTypeNone,
260 ResourceFetcher::PLATFORM_LOADER,
261 delegate->NewCallback());
263 delegate->WaitForResponse();
264 ASSERT_TRUE(delegate->completed());
265 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
266 EXPECT_EQ(kBody, delegate->data());
269 void ResourceFetcherSetHeader(const GURL& url) {
270 const char* kHeader = "Rather boring header.";
272 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
274 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
275 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
276 fetcher->SetHeader("header", kHeader);
277 fetcher->Start(frame,
278 WebURLRequest::RequestContextInternal,
279 WebURLRequest::FrameTypeNone,
280 ResourceFetcher::PLATFORM_LOADER,
281 delegate->NewCallback());
283 delegate->WaitForResponse();
284 ASSERT_TRUE(delegate->completed());
285 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
286 EXPECT_EQ(kHeader, delegate->data());
289 content::RoutingIDManglingDisabler routing_id_mangling_disabler_;
292 // Test a fetch from the test server.
293 // If this flakes, use http://crbug.com/51622.
294 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDownload) {
295 // Need to spin up the renderer.
296 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
298 ASSERT_TRUE(test_server()->Start());
299 GURL url(test_server()->GetURL("files/simple_page.html"));
301 PostTaskToInProcessRendererAndWait(
302 base::Bind(&ResourceFetcherTests::ResourceFetcherDownloadOnRenderer,
303 base::Unretained(this), url));
306 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcher404) {
307 // Need to spin up the renderer.
308 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
310 // Test 404 response.
311 ASSERT_TRUE(test_server()->Start());
312 GURL url = test_server()->GetURL("files/thisfiledoesntexist.html");
314 PostTaskToInProcessRendererAndWait(
315 base::Bind(&ResourceFetcherTests::ResourceFetcher404OnRenderer,
316 base::Unretained(this), url));
319 // If this flakes, use http://crbug.com/51622.
320 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) {
321 // Need to spin up the renderer.
322 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
324 PostTaskToInProcessRendererAndWait(
325 base::Bind(&ResourceFetcherTests::ResourceFetcherDidFailOnRenderer,
326 base::Unretained(this)));
329 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherTimeout) {
330 // Need to spin up the renderer.
331 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
333 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
334 // timeout in 0 sec.
335 ASSERT_TRUE(test_server()->Start());
336 GURL url(test_server()->GetURL("slow?1"));
338 PostTaskToInProcessRendererAndWait(
339 base::Bind(&ResourceFetcherTests::ResourceFetcherTimeoutOnRenderer,
340 base::Unretained(this), url));
343 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDeletedInCallback) {
344 // Need to spin up the renderer.
345 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
347 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
348 // timeout in 0 sec.
349 ASSERT_TRUE(test_server()->Start());
350 GURL url(test_server()->GetURL("slow?1"));
352 PostTaskToInProcessRendererAndWait(
353 base::Bind(
354 &ResourceFetcherTests::ResourceFetcherDeletedInCallbackOnRenderer,
355 base::Unretained(this), url));
360 // Test that ResourceFetchers can handle POSTs.
361 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherPost) {
362 // Need to spin up the renderer.
363 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
365 // Grab a page that echos the POST body.
366 ASSERT_TRUE(test_server()->Start());
367 GURL url(test_server()->GetURL("echo"));
369 PostTaskToInProcessRendererAndWait(
370 base::Bind(
371 &ResourceFetcherTests::ResourceFetcherPost,
372 base::Unretained(this), url));
375 // Test that ResourceFetchers can set headers.
376 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherSetHeader) {
377 // Need to spin up the renderer.
378 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
380 // Grab a page that echos the POST body.
381 ASSERT_TRUE(test_server()->Start());
382 GURL url(test_server()->GetURL("echoheader?header"));
384 PostTaskToInProcessRendererAndWait(
385 base::Bind(
386 &ResourceFetcherTests::ResourceFetcherSetHeader,
387 base::Unretained(this), url));
390 } // namespace content