Roll WebRTC 7546:7549.
[chromium-blink-merge.git] / content / renderer / resource_fetcher_browsertest.cc
blobc016754ef3f19e9b22d721a4164dd38deb6e8b8d
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/test_utils.h"
19 #include "content/shell/browser/shell.h"
20 #include "third_party/WebKit/public/platform/WebURLResponse.h"
21 #include "third_party/WebKit/public/web/WebFrame.h"
22 #include "third_party/WebKit/public/web/WebView.h"
24 using blink::WebFrame;
25 using blink::WebURLRequest;
26 using blink::WebURLResponse;
28 namespace {
30 // The first RenderFrame is routing ID 1, and the first RenderView is 2.
31 const int kRenderViewRoutingId = 2;
35 namespace content {
37 static const int kMaxWaitTimeMs = 5000;
39 class FetcherDelegate {
40 public:
41 FetcherDelegate()
42 : completed_(false),
43 timed_out_(false) {
44 // Start a repeating timer waiting for the download to complete. The
45 // callback has to be a static function, so we hold on to our instance.
46 FetcherDelegate::instance_ = this;
47 StartTimer();
50 virtual ~FetcherDelegate() {}
52 ResourceFetcher::Callback NewCallback() {
53 return base::Bind(&FetcherDelegate::OnURLFetchComplete,
54 base::Unretained(this));
57 virtual void OnURLFetchComplete(const WebURLResponse& response,
58 const std::string& data) {
59 response_ = response;
60 data_ = data;
61 completed_ = true;
62 timer_.Stop();
63 if (!timed_out_)
64 quit_task_.Run();
67 bool completed() const { return completed_; }
68 bool timed_out() const { return timed_out_; }
70 std::string data() const { return data_; }
71 const WebURLResponse& response() const { return response_; }
73 // Wait for the request to complete or timeout.
74 void WaitForResponse() {
75 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
76 quit_task_ = runner->QuitClosure();
77 runner->Run();
80 void StartTimer() {
81 timer_.Start(FROM_HERE,
82 base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs),
83 this,
84 &FetcherDelegate::TimerFired);
87 void TimerFired() {
88 ASSERT_FALSE(completed_);
90 timed_out_ = true;
91 if (!completed_)
92 quit_task_.Run();
93 FAIL() << "fetch timed out";
96 static FetcherDelegate* instance_;
98 private:
99 base::OneShotTimer<FetcherDelegate> timer_;
100 bool completed_;
101 bool timed_out_;
102 WebURLResponse response_;
103 std::string data_;
104 base::Closure quit_task_;
107 FetcherDelegate* FetcherDelegate::instance_ = NULL;
109 class EvilFetcherDelegate : public FetcherDelegate {
110 public:
111 ~EvilFetcherDelegate() override {}
113 void SetFetcher(ResourceFetcher* fetcher) {
114 fetcher_.reset(fetcher);
117 void OnURLFetchComplete(const WebURLResponse& response,
118 const std::string& data) override {
119 FetcherDelegate::OnURLFetchComplete(response, data);
121 // Destroy the ResourceFetcher here. We are testing that upon returning
122 // to the ResourceFetcher that it does not crash. This must be done after
123 // calling FetcherDelegate::OnURLFetchComplete, since deleting the fetcher
124 // invalidates |response| and |data|.
125 fetcher_.reset();
128 private:
129 scoped_ptr<ResourceFetcher> fetcher_;
132 class ResourceFetcherTests : public ContentBrowserTest {
133 public:
134 void SetUpCommandLine(CommandLine* command_line) override {
135 command_line->AppendSwitch(switches::kSingleProcess);
136 #if defined(OS_WIN)
137 // Don't want to try to create a GPU process.
138 command_line->AppendSwitch(switches::kDisableGpu);
139 #endif
142 RenderView* GetRenderView() {
143 // We could have the test on the UI thread get the WebContent's routing ID,
144 // but we know this will be the first RV so skip that and just hardcode it.
145 return RenderView::FromRoutingID(kRenderViewRoutingId);
148 void ResourceFetcherDownloadOnRenderer(const GURL& url) {
149 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
151 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
152 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
153 fetcher->Start(frame,
154 WebURLRequest::RequestContextInternal,
155 WebURLRequest::FrameTypeNone,
156 ResourceFetcher::PLATFORM_LOADER,
157 delegate->NewCallback());
159 delegate->WaitForResponse();
161 ASSERT_TRUE(delegate->completed());
162 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
163 std::string text = delegate->data();
164 EXPECT_TRUE(text.find("Basic html test.") != std::string::npos);
167 void ResourceFetcher404OnRenderer(const GURL& url) {
168 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
170 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
171 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
172 fetcher->Start(frame,
173 WebURLRequest::RequestContextInternal,
174 WebURLRequest::FrameTypeNone,
175 ResourceFetcher::PLATFORM_LOADER,
176 delegate->NewCallback());
178 delegate->WaitForResponse();
180 ASSERT_TRUE(delegate->completed());
181 EXPECT_EQ(delegate->response().httpStatusCode(), 404);
182 EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos);
185 void ResourceFetcherDidFailOnRenderer() {
186 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
188 // Try to fetch a page on a site that doesn't exist.
189 GURL url("http://localhost:1339/doesnotexist");
190 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
191 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
192 fetcher->Start(frame,
193 WebURLRequest::RequestContextInternal,
194 WebURLRequest::FrameTypeNone,
195 ResourceFetcher::PLATFORM_LOADER,
196 delegate->NewCallback());
198 delegate->WaitForResponse();
200 // When we fail, we still call the Delegate callback but we pass in empty
201 // values.
202 EXPECT_TRUE(delegate->completed());
203 EXPECT_TRUE(delegate->response().isNull());
204 EXPECT_EQ(delegate->data(), std::string());
205 EXPECT_FALSE(delegate->timed_out());
208 void ResourceFetcherTimeoutOnRenderer(const GURL& url) {
209 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
211 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
212 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
213 fetcher->Start(frame,
214 WebURLRequest::RequestContextInternal,
215 WebURLRequest::FrameTypeNone,
216 ResourceFetcher::PLATFORM_LOADER,
217 delegate->NewCallback());
218 fetcher->SetTimeout(base::TimeDelta());
220 delegate->WaitForResponse();
222 // When we timeout, we still call the Delegate callback but we pass in empty
223 // values.
224 EXPECT_TRUE(delegate->completed());
225 EXPECT_TRUE(delegate->response().isNull());
226 EXPECT_EQ(delegate->data(), std::string());
227 EXPECT_FALSE(delegate->timed_out());
230 void ResourceFetcherDeletedInCallbackOnRenderer(const GURL& url) {
231 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
233 scoped_ptr<EvilFetcherDelegate> delegate(new EvilFetcherDelegate);
234 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
235 fetcher->Start(frame,
236 WebURLRequest::RequestContextInternal,
237 WebURLRequest::FrameTypeNone,
238 ResourceFetcher::PLATFORM_LOADER,
239 delegate->NewCallback());
240 fetcher->SetTimeout(base::TimeDelta());
241 delegate->SetFetcher(fetcher.release());
243 delegate->WaitForResponse();
244 EXPECT_FALSE(delegate->timed_out());
247 void ResourceFetcherPost(const GURL& url) {
248 const char* kBody = "Really nifty POST body!";
250 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
252 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
253 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
254 fetcher->SetMethod("POST");
255 fetcher->SetBody(kBody);
256 fetcher->Start(frame,
257 WebURLRequest::RequestContextInternal,
258 WebURLRequest::FrameTypeNone,
259 ResourceFetcher::PLATFORM_LOADER,
260 delegate->NewCallback());
262 delegate->WaitForResponse();
263 ASSERT_TRUE(delegate->completed());
264 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
265 EXPECT_EQ(kBody, delegate->data());
268 void ResourceFetcherSetHeader(const GURL& url) {
269 const char* kHeader = "Rather boring header.";
271 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
273 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
274 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
275 fetcher->SetHeader("header", kHeader);
276 fetcher->Start(frame,
277 WebURLRequest::RequestContextInternal,
278 WebURLRequest::FrameTypeNone,
279 ResourceFetcher::PLATFORM_LOADER,
280 delegate->NewCallback());
282 delegate->WaitForResponse();
283 ASSERT_TRUE(delegate->completed());
284 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
285 EXPECT_EQ(kHeader, delegate->data());
289 #if defined(OS_ANDROID)
290 // Disable (http://crbug.com/248796).
291 #define MAYBE_ResourceFetcher404 DISABLED_ResourceFetcher404
292 #define MAYBE_ResourceFetcherDeletedInCallback \
293 DISABLED_ResourceFetcherDeletedInCallback
294 #define MAYBE_ResourceFetcherTimeout DISABLED_ResourceFetcherTimeout
295 #define MAYBE_ResourceFetcherDownload DISABLED_ResourceFetcherDownload
296 // Disable (http://crbug.com/341142).
297 #define MAYBE_ResourceFetcherPost DISABLED_ResourceFetcherPost
298 #define MAYBE_ResourceFetcherSetHeader DISABLED_ResourceFetcherSetHeader
299 #else
300 #define MAYBE_ResourceFetcher404 ResourceFetcher404
301 #define MAYBE_ResourceFetcherDeletedInCallback ResourceFetcherDeletedInCallback
302 #define MAYBE_ResourceFetcherTimeout ResourceFetcherTimeout
303 #define MAYBE_ResourceFetcherDownload ResourceFetcherDownload
304 #define MAYBE_ResourceFetcherPost ResourceFetcherPost
305 #define MAYBE_ResourceFetcherSetHeader ResourceFetcherSetHeader
306 #endif
308 // Test a fetch from the test server.
309 // If this flakes, use http://crbug.com/51622.
310 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, MAYBE_ResourceFetcherDownload) {
311 // Need to spin up the renderer.
312 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
314 ASSERT_TRUE(test_server()->Start());
315 GURL url(test_server()->GetURL("files/simple_page.html"));
317 PostTaskToInProcessRendererAndWait(
318 base::Bind(&ResourceFetcherTests::ResourceFetcherDownloadOnRenderer,
319 base::Unretained(this), url));
322 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, MAYBE_ResourceFetcher404) {
323 // Need to spin up the renderer.
324 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
326 // Test 404 response.
327 ASSERT_TRUE(test_server()->Start());
328 GURL url = test_server()->GetURL("files/thisfiledoesntexist.html");
330 PostTaskToInProcessRendererAndWait(
331 base::Bind(&ResourceFetcherTests::ResourceFetcher404OnRenderer,
332 base::Unretained(this), url));
335 // If this flakes, use http://crbug.com/51622.
336 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) {
337 // Need to spin up the renderer.
338 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
340 PostTaskToInProcessRendererAndWait(
341 base::Bind(&ResourceFetcherTests::ResourceFetcherDidFailOnRenderer,
342 base::Unretained(this)));
345 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, MAYBE_ResourceFetcherTimeout) {
346 // Need to spin up the renderer.
347 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
349 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
350 // timeout in 0 sec.
351 ASSERT_TRUE(test_server()->Start());
352 GURL url(test_server()->GetURL("slow?1"));
354 PostTaskToInProcessRendererAndWait(
355 base::Bind(&ResourceFetcherTests::ResourceFetcherTimeoutOnRenderer,
356 base::Unretained(this), url));
359 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests,
360 MAYBE_ResourceFetcherDeletedInCallback) {
361 // Need to spin up the renderer.
362 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
364 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
365 // timeout in 0 sec.
366 ASSERT_TRUE(test_server()->Start());
367 GURL url(test_server()->GetURL("slow?1"));
369 PostTaskToInProcessRendererAndWait(
370 base::Bind(
371 &ResourceFetcherTests::ResourceFetcherDeletedInCallbackOnRenderer,
372 base::Unretained(this), url));
377 // Test that ResourceFetchers can handle POSTs.
378 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, MAYBE_ResourceFetcherPost) {
379 // Need to spin up the renderer.
380 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
382 // Grab a page that echos the POST body.
383 ASSERT_TRUE(test_server()->Start());
384 GURL url(test_server()->GetURL("echo"));
386 PostTaskToInProcessRendererAndWait(
387 base::Bind(
388 &ResourceFetcherTests::ResourceFetcherPost,
389 base::Unretained(this), url));
392 // Test that ResourceFetchers can set headers.
393 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, MAYBE_ResourceFetcherSetHeader) {
394 // Need to spin up the renderer.
395 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
397 // Grab a page that echos the POST body.
398 ASSERT_TRUE(test_server()->Start());
399 GURL url(test_server()->GetURL("echoheader?header"));
401 PostTaskToInProcessRendererAndWait(
402 base::Bind(
403 &ResourceFetcherTests::ResourceFetcherSetHeader,
404 base::Unretained(this), url));
407 } // namespace content