Get foreground tab on Android
[chromium-blink-merge.git] / content / renderer / resource_fetcher_browsertest.cc
bloba9498cb08232eab753c7ac97442dd39e050179a9
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/test_utils.h"
17 #include "content/shell/browser/shell.h"
18 #include "content/test/content_browser_test.h"
19 #include "content/test/content_browser_test_utils.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 content {
30 static const int kMaxWaitTimeMs = 5000;
32 class FetcherDelegate {
33 public:
34 FetcherDelegate()
35 : completed_(false),
36 timed_out_(false) {
37 // Start a repeating timer waiting for the download to complete. The
38 // callback has to be a static function, so we hold on to our instance.
39 FetcherDelegate::instance_ = this;
40 StartTimer();
43 virtual ~FetcherDelegate() {}
45 ResourceFetcher::Callback NewCallback() {
46 return base::Bind(&FetcherDelegate::OnURLFetchComplete,
47 base::Unretained(this));
50 virtual void OnURLFetchComplete(const WebURLResponse& response,
51 const std::string& data) {
52 response_ = response;
53 data_ = data;
54 completed_ = true;
55 timer_.Stop();
56 if (!timed_out_)
57 quit_task_.Run();
60 bool completed() const { return completed_; }
61 bool timed_out() const { return timed_out_; }
63 std::string data() const { return data_; }
64 const WebURLResponse& response() const { return response_; }
66 // Wait for the request to complete or timeout.
67 void WaitForResponse() {
68 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
69 quit_task_ = runner->QuitClosure();
70 runner->Run();
73 void StartTimer() {
74 timer_.Start(FROM_HERE,
75 base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs),
76 this,
77 &FetcherDelegate::TimerFired);
80 void TimerFired() {
81 ASSERT_FALSE(completed_);
83 timed_out_ = true;
84 if (!completed_)
85 quit_task_.Run();
86 FAIL() << "fetch timed out";
89 static FetcherDelegate* instance_;
91 private:
92 base::OneShotTimer<FetcherDelegate> timer_;
93 bool completed_;
94 bool timed_out_;
95 WebURLResponse response_;
96 std::string data_;
97 base::Closure quit_task_;
100 FetcherDelegate* FetcherDelegate::instance_ = NULL;
102 class EvilFetcherDelegate : public FetcherDelegate {
103 public:
104 virtual ~EvilFetcherDelegate() {}
106 void SetFetcher(ResourceFetcher* fetcher) {
107 fetcher_.reset(fetcher);
110 virtual void OnURLFetchComplete(const WebURLResponse& response,
111 const std::string& data) OVERRIDE {
112 FetcherDelegate::OnURLFetchComplete(response, data);
114 // Destroy the ResourceFetcher here. We are testing that upon returning
115 // to the ResourceFetcher that it does not crash. This must be done after
116 // calling FetcherDelegate::OnURLFetchComplete, since deleting the fetcher
117 // invalidates |response| and |data|.
118 fetcher_.reset();
121 private:
122 scoped_ptr<ResourceFetcher> fetcher_;
125 class ResourceFetcherTests : public ContentBrowserTest {
126 public:
127 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
128 command_line->AppendSwitch(switches::kSingleProcess);
129 #if defined(OS_WIN) && defined(USE_AURA)
130 // Don't want to try to create a GPU process.
131 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
132 #endif
135 RenderView* GetRenderView() {
136 // We could have the test on the UI thread get the WebContent's routing ID,
137 // but we know this will be the first RV so skip that and just hardcode it.
138 return RenderView::FromRoutingID(1);
141 void ResourceFetcherDownloadOnRenderer(const GURL& url) {
142 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
144 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
145 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(
146 url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
148 delegate->WaitForResponse();
150 ASSERT_TRUE(delegate->completed());
151 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
152 std::string text = delegate->data();
153 EXPECT_TRUE(text.find("Basic html test.") != std::string::npos);
156 void ResourceFetcher404OnRenderer(const GURL& url) {
157 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
159 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
160 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(
161 url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
163 delegate->WaitForResponse();
165 ASSERT_TRUE(delegate->completed());
166 EXPECT_EQ(delegate->response().httpStatusCode(), 404);
167 EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos);
170 void ResourceFetcherDidFailOnRenderer() {
171 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
173 // Try to fetch a page on a site that doesn't exist.
174 GURL url("http://localhost:1339/doesnotexist");
175 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
176 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(
177 url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
179 delegate->WaitForResponse();
181 // When we fail, we still call the Delegate callback but we pass in empty
182 // values.
183 EXPECT_TRUE(delegate->completed());
184 EXPECT_TRUE(delegate->response().isNull());
185 EXPECT_EQ(delegate->data(), std::string());
186 EXPECT_FALSE(delegate->timed_out());
189 void ResourceFetcherTimeoutOnRenderer(const GURL& url) {
190 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
192 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
193 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(
194 url, frame, WebURLRequest::TargetIsMainFrame,
195 delegate->NewCallback()));
196 fetcher->SetTimeout(base::TimeDelta());
198 delegate->WaitForResponse();
200 // When we timeout, 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 ResourceFetcherDeletedInCallbackOnRenderer(const GURL& url) {
209 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
211 scoped_ptr<EvilFetcherDelegate> delegate(new EvilFetcherDelegate);
212 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(
213 url, frame, WebURLRequest::TargetIsMainFrame,
214 delegate->NewCallback()));
215 fetcher->SetTimeout(base::TimeDelta());
216 delegate->SetFetcher(fetcher.release());
218 delegate->WaitForResponse();
219 EXPECT_FALSE(delegate->timed_out());
223 // Test a fetch from the test server.
224 // If this flakes, use http://crbug.com/51622.
225 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDownload) {
226 // Need to spin up the renderer.
227 NavigateToURL(shell(), GURL(kAboutBlankURL));
229 ASSERT_TRUE(test_server()->Start());
230 GURL url(test_server()->GetURL("files/simple_page.html"));
232 PostTaskToInProcessRendererAndWait(
233 base::Bind(&ResourceFetcherTests::ResourceFetcherDownloadOnRenderer,
234 base::Unretained(this), url));
237 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcher404) {
238 // Need to spin up the renderer.
239 NavigateToURL(shell(), GURL(kAboutBlankURL));
241 // Test 404 response.
242 ASSERT_TRUE(test_server()->Start());
243 GURL url = test_server()->GetURL("files/thisfiledoesntexist.html");
245 PostTaskToInProcessRendererAndWait(
246 base::Bind(&ResourceFetcherTests::ResourceFetcher404OnRenderer,
247 base::Unretained(this), url));
250 // If this flakes, use http://crbug.com/51622.
251 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) {
252 // Need to spin up the renderer.
253 NavigateToURL(shell(), GURL(kAboutBlankURL));
255 PostTaskToInProcessRendererAndWait(
256 base::Bind(&ResourceFetcherTests::ResourceFetcherDidFailOnRenderer,
257 base::Unretained(this)));
260 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherTimeout) {
261 // Need to spin up the renderer.
262 NavigateToURL(shell(), GURL(kAboutBlankURL));
264 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
265 // timeout in 0 sec.
266 ASSERT_TRUE(test_server()->Start());
267 GURL url(test_server()->GetURL("slow?1"));
269 PostTaskToInProcessRendererAndWait(
270 base::Bind(&ResourceFetcherTests::ResourceFetcherTimeoutOnRenderer,
271 base::Unretained(this), url));
274 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDeletedInCallback) {
275 // Need to spin up the renderer.
276 NavigateToURL(shell(), GURL(kAboutBlankURL));
278 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
279 // timeout in 0 sec.
280 ASSERT_TRUE(test_server()->Start());
281 GURL url(test_server()->GetURL("slow?1"));
283 PostTaskToInProcessRendererAndWait(
284 base::Bind(
285 &ResourceFetcherTests::ResourceFetcherDeletedInCallbackOnRenderer,
286 base::Unretained(this), url));
289 } // namespace content