OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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. | |
4 | |
5 #include "base/message_loop_proxy.h" | |
6 #include "base/synchronization/waitable_event.h" | |
7 #include "base/threading/thread.h" | |
8 #include "build/build_config.h" | |
9 #include "chrome/common/net/url_fetcher.h" | |
10 #include "net/http/http_response_headers.h" | |
11 #include "net/test/test_server.h" | |
12 #include "net/url_request/url_request_context_getter.h" | |
13 #include "net/url_request/url_request_test_util.h" | |
14 #include "net/url_request/url_request_throttler_manager.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | |
16 | |
17 #if defined(USE_NSS) | |
18 #include "net/ocsp/nss_ocsp.h" | |
19 #endif | |
20 | |
21 using base::Time; | |
22 using base::TimeDelta; | |
23 | |
24 // TODO(eroman): Add a regression test for http://crbug.com/40505. | |
25 | |
26 namespace { | |
27 | |
28 const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data"); | |
29 const std::string kTestServerFilePrefix = "files/"; | |
30 | |
31 class CurriedTask : public Task { | |
32 public: | |
33 CurriedTask(Task* task, MessageLoop* target_loop) | |
34 : task_(task), | |
35 target_loop_(target_loop) {} | |
36 | |
37 virtual void Run() { | |
38 target_loop_->PostTask(FROM_HERE, task_); | |
39 } | |
40 | |
41 private: | |
42 Task* const task_; | |
43 MessageLoop* const target_loop_; | |
44 | |
45 DISALLOW_COPY_AND_ASSIGN(CurriedTask); | |
46 }; | |
47 | |
48 class TestURLRequestContextGetter : public net::URLRequestContextGetter { | |
49 public: | |
50 explicit TestURLRequestContextGetter( | |
51 base::MessageLoopProxy* io_message_loop_proxy) | |
52 : io_message_loop_proxy_(io_message_loop_proxy) { | |
53 } | |
54 virtual net::URLRequestContext* GetURLRequestContext() { | |
55 if (!context_) | |
56 context_ = new TestURLRequestContext(); | |
57 return context_; | |
58 } | |
59 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const { | |
60 return io_message_loop_proxy_; | |
61 } | |
62 | |
63 protected: | |
64 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
65 | |
66 private: | |
67 ~TestURLRequestContextGetter() {} | |
68 | |
69 scoped_refptr<net::URLRequestContext> context_; | |
70 }; | |
71 | |
72 } // namespace | |
73 | |
74 class URLFetcherTest : public testing::Test, public URLFetcher::Delegate { | |
75 public: | |
76 URLFetcherTest() : fetcher_(NULL) { } | |
77 | |
78 // Creates a URLFetcher, using the program's main thread to do IO. | |
79 virtual void CreateFetcher(const GURL& url); | |
80 | |
81 // URLFetcher::Delegate | |
82 virtual void OnURLFetchComplete(const URLFetcher* source, | |
83 const GURL& url, | |
84 const net::URLRequestStatus& status, | |
85 int response_code, | |
86 const net::ResponseCookies& cookies, | |
87 const std::string& data); | |
88 | |
89 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() { | |
90 return io_message_loop_proxy_; | |
91 } | |
92 | |
93 protected: | |
94 virtual void SetUp() { | |
95 testing::Test::SetUp(); | |
96 | |
97 io_message_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread(); | |
98 | |
99 #if defined(USE_NSS) | |
100 net::EnsureOCSPInit(); | |
101 #endif | |
102 } | |
103 | |
104 virtual void TearDown() { | |
105 #if defined(USE_NSS) | |
106 net::ShutdownOCSP(); | |
107 #endif | |
108 } | |
109 | |
110 int GetNumFetcherCores() const { | |
111 return URLFetcher::GetNumFetcherCores(); | |
112 } | |
113 | |
114 // URLFetcher is designed to run on the main UI thread, but in our tests | |
115 // we assume that the current thread is the IO thread where the URLFetcher | |
116 // dispatches its requests to. When we wish to simulate being used from | |
117 // a UI thread, we dispatch a worker thread to do so. | |
118 MessageLoopForIO io_loop_; | |
119 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
120 | |
121 URLFetcher* fetcher_; | |
122 }; | |
123 | |
124 void URLFetcherTest::CreateFetcher(const GURL& url) { | |
125 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
126 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
127 io_message_loop_proxy())); | |
128 fetcher_->Start(); | |
129 } | |
130 | |
131 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source, | |
132 const GURL& url, | |
133 const net::URLRequestStatus& status, | |
134 int response_code, | |
135 const net::ResponseCookies& cookies, | |
136 const std::string& data) { | |
137 EXPECT_TRUE(status.is_success()); | |
138 EXPECT_EQ(200, response_code); // HTTP OK | |
139 EXPECT_FALSE(data.empty()); | |
140 | |
141 delete fetcher_; // Have to delete this here and not in the destructor, | |
142 // because the destructor won't necessarily run on the | |
143 // same thread that CreateFetcher() did. | |
144 | |
145 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
146 // If the current message loop is not the IO loop, it will be shut down when | |
147 // the main loop returns and this thread subsequently goes out of scope. | |
148 } | |
149 | |
150 namespace { | |
151 | |
152 // Version of URLFetcherTest that does a POST instead | |
153 class URLFetcherPostTest : public URLFetcherTest { | |
154 public: | |
155 virtual void CreateFetcher(const GURL& url); | |
156 | |
157 // URLFetcher::Delegate | |
158 virtual void OnURLFetchComplete(const URLFetcher* source, | |
159 const GURL& url, | |
160 const net::URLRequestStatus& status, | |
161 int response_code, | |
162 const net::ResponseCookies& cookies, | |
163 const std::string& data); | |
164 }; | |
165 | |
166 // Version of URLFetcherTest that tests headers. | |
167 class URLFetcherHeadersTest : public URLFetcherTest { | |
168 public: | |
169 // URLFetcher::Delegate | |
170 virtual void OnURLFetchComplete(const URLFetcher* source, | |
171 const GURL& url, | |
172 const net::URLRequestStatus& status, | |
173 int response_code, | |
174 const net::ResponseCookies& cookies, | |
175 const std::string& data); | |
176 }; | |
177 | |
178 // Version of URLFetcherTest that tests SocketAddress. | |
179 class URLFetcherSocketAddressTest : public URLFetcherTest { | |
180 public: | |
181 // URLFetcher::Delegate | |
182 virtual void OnURLFetchComplete(const URLFetcher* source, | |
183 const GURL& url, | |
184 const net::URLRequestStatus& status, | |
185 int response_code, | |
186 const net::ResponseCookies& cookies, | |
187 const std::string& data); | |
188 protected: | |
189 std::string expected_host_; | |
190 uint16 expected_port_; | |
191 }; | |
192 | |
193 // Version of URLFetcherTest that tests overload protection. | |
194 class URLFetcherProtectTest : public URLFetcherTest { | |
195 public: | |
196 virtual void CreateFetcher(const GURL& url); | |
197 // URLFetcher::Delegate | |
198 virtual void OnURLFetchComplete(const URLFetcher* source, | |
199 const GURL& url, | |
200 const net::URLRequestStatus& status, | |
201 int response_code, | |
202 const net::ResponseCookies& cookies, | |
203 const std::string& data); | |
204 private: | |
205 Time start_time_; | |
206 }; | |
207 | |
208 // Version of URLFetcherTest that tests overload protection, when responses | |
209 // passed through. | |
210 class URLFetcherProtectTestPassedThrough : public URLFetcherTest { | |
211 public: | |
212 virtual void CreateFetcher(const GURL& url); | |
213 // URLFetcher::Delegate | |
214 virtual void OnURLFetchComplete(const URLFetcher* source, | |
215 const GURL& url, | |
216 const net::URLRequestStatus& status, | |
217 int response_code, | |
218 const net::ResponseCookies& cookies, | |
219 const std::string& data); | |
220 private: | |
221 Time start_time_; | |
222 }; | |
223 | |
224 // Version of URLFetcherTest that tests bad HTTPS requests. | |
225 class URLFetcherBadHTTPSTest : public URLFetcherTest { | |
226 public: | |
227 URLFetcherBadHTTPSTest(); | |
228 | |
229 // URLFetcher::Delegate | |
230 virtual void OnURLFetchComplete(const URLFetcher* source, | |
231 const GURL& url, | |
232 const net::URLRequestStatus& status, | |
233 int response_code, | |
234 const net::ResponseCookies& cookies, | |
235 const std::string& data); | |
236 | |
237 private: | |
238 FilePath cert_dir_; | |
239 }; | |
240 | |
241 // Version of URLFetcherTest that tests request cancellation on shutdown. | |
242 class URLFetcherCancelTest : public URLFetcherTest { | |
243 public: | |
244 virtual void CreateFetcher(const GURL& url); | |
245 // URLFetcher::Delegate | |
246 virtual void OnURLFetchComplete(const URLFetcher* source, | |
247 const GURL& url, | |
248 const net::URLRequestStatus& status, | |
249 int response_code, | |
250 const net::ResponseCookies& cookies, | |
251 const std::string& data); | |
252 | |
253 void CancelRequest(); | |
254 }; | |
255 | |
256 // Version of TestURLRequestContext that posts a Quit task to the IO | |
257 // thread once it is deleted. | |
258 class CancelTestURLRequestContext : public TestURLRequestContext { | |
259 virtual ~CancelTestURLRequestContext() { | |
260 // The d'tor should execute in the IO thread. Post the quit task to the | |
261 // current thread. | |
262 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
263 } | |
264 }; | |
265 | |
266 class CancelTestURLRequestContextGetter : public net::URLRequestContextGetter { | |
267 public: | |
268 explicit CancelTestURLRequestContextGetter( | |
269 base::MessageLoopProxy* io_message_loop_proxy) | |
270 : io_message_loop_proxy_(io_message_loop_proxy), | |
271 context_created_(false, false) { | |
272 } | |
273 virtual net::URLRequestContext* GetURLRequestContext() { | |
274 if (!context_) { | |
275 context_ = new CancelTestURLRequestContext(); | |
276 context_created_.Signal(); | |
277 } | |
278 return context_; | |
279 } | |
280 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const { | |
281 return io_message_loop_proxy_; | |
282 } | |
283 void WaitForContextCreation() { | |
284 context_created_.Wait(); | |
285 } | |
286 | |
287 private: | |
288 ~CancelTestURLRequestContextGetter() {} | |
289 | |
290 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
291 base::WaitableEvent context_created_; | |
292 scoped_refptr<net::URLRequestContext> context_; | |
293 }; | |
294 | |
295 // Version of URLFetcherTest that tests retying the same request twice. | |
296 class URLFetcherMultipleAttemptTest : public URLFetcherTest { | |
297 public: | |
298 // URLFetcher::Delegate | |
299 virtual void OnURLFetchComplete(const URLFetcher* source, | |
300 const GURL& url, | |
301 const net::URLRequestStatus& status, | |
302 int response_code, | |
303 const net::ResponseCookies& cookies, | |
304 const std::string& data); | |
305 private: | |
306 std::string data_; | |
307 }; | |
308 | |
309 class URLFetcherTempFileTest : public URLFetcherTest { | |
310 public: | |
311 URLFetcherTempFileTest() | |
312 : take_ownership_of_temp_file_(false) { | |
313 } | |
314 | |
315 // URLFetcher::Delegate | |
316 virtual void OnURLFetchComplete(const URLFetcher* source); | |
317 | |
318 // This obsolete signature should not be used, but must be present | |
319 // to make clang happy. | |
320 virtual void OnURLFetchComplete(const URLFetcher* source, | |
321 const GURL& url, | |
322 const net::URLRequestStatus& status, | |
323 int response_code, | |
324 const net::ResponseCookies& cookies, | |
325 const std::string& data); | |
326 | |
327 virtual void CreateFetcher(const GURL& url); | |
328 | |
329 protected: | |
330 FilePath expected_file_; | |
331 FilePath temp_file_; | |
332 | |
333 // Set by the test. Used in OnURLFetchComplete() to decide if | |
334 // the URLFetcher should own the temp file, so that we can test | |
335 // disowning prevents the file from being deleted. | |
336 bool take_ownership_of_temp_file_; | |
337 }; | |
338 | |
339 void URLFetcherTempFileTest::CreateFetcher(const GURL& url) { | |
340 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
341 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
342 io_message_loop_proxy())); | |
343 | |
344 // Use the IO message loop to do the file operations in this test. | |
345 fetcher_->SaveResponseToTemporaryFile(io_message_loop_proxy()); | |
346 fetcher_->Start(); | |
347 } | |
348 | |
349 TEST_F(URLFetcherTempFileTest, SmallGet) { | |
350 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
351 ASSERT_TRUE(test_server.Start()); | |
352 | |
353 // Get a small file. | |
354 const char* kFileToFetch = "simple.html"; | |
355 expected_file_ = test_server.document_root().AppendASCII(kFileToFetch); | |
356 CreateFetcher(test_server.GetURL(kTestServerFilePrefix + kFileToFetch)); | |
357 | |
358 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). | |
359 | |
360 ASSERT_FALSE(file_util::PathExists(temp_file_)) | |
361 << temp_file_.value() << " not removed."; | |
362 } | |
363 | |
364 TEST_F(URLFetcherTempFileTest, LargeGet) { | |
365 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
366 ASSERT_TRUE(test_server.Start()); | |
367 | |
368 // Get a file large enough to require more than one read into | |
369 // URLFetcher::Core's IOBuffer. | |
370 const char* kFileToFetch = "animate1.gif"; | |
371 expected_file_ = test_server.document_root().AppendASCII(kFileToFetch); | |
372 CreateFetcher(test_server.GetURL(kTestServerFilePrefix + kFileToFetch)); | |
373 | |
374 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). | |
375 } | |
376 | |
377 TEST_F(URLFetcherTempFileTest, CanTakeOwnershipOfFile) { | |
378 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
379 ASSERT_TRUE(test_server.Start()); | |
380 | |
381 // Get a small file. | |
382 const char* kFileToFetch = "simple.html"; | |
383 expected_file_ = test_server.document_root().AppendASCII(kFileToFetch); | |
384 CreateFetcher(test_server.GetURL(kTestServerFilePrefix + kFileToFetch)); | |
385 | |
386 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). | |
387 | |
388 MessageLoop::current()->RunAllPending(); | |
389 ASSERT_FALSE(file_util::PathExists(temp_file_)) | |
390 << temp_file_.value() << " not removed."; | |
391 } | |
392 | |
393 // Wrapper that lets us call CreateFetcher() on a thread of our choice. We | |
394 // could make URLFetcherTest refcounted and use PostTask(FROM_HERE.. ) to call | |
395 // CreateFetcher() directly, but the ownership of the URLFetcherTest is a bit | |
396 // confusing in that case because GTest doesn't know about the refcounting. | |
397 // It's less confusing to just do it this way. | |
398 class FetcherWrapperTask : public Task { | |
399 public: | |
400 FetcherWrapperTask(URLFetcherTest* test, const GURL& url) | |
401 : test_(test), url_(url) { } | |
402 virtual void Run() { | |
403 test_->CreateFetcher(url_); | |
404 } | |
405 | |
406 private: | |
407 URLFetcherTest* test_; | |
408 GURL url_; | |
409 }; | |
410 | |
411 void URLFetcherPostTest::CreateFetcher(const GURL& url) { | |
412 fetcher_ = new URLFetcher(url, URLFetcher::POST, this); | |
413 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
414 io_message_loop_proxy())); | |
415 fetcher_->set_upload_data("application/x-www-form-urlencoded", | |
416 "bobsyeruncle"); | |
417 fetcher_->Start(); | |
418 } | |
419 | |
420 void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source, | |
421 const GURL& url, | |
422 const net::URLRequestStatus& status, | |
423 int response_code, | |
424 const net::ResponseCookies& cookies, | |
425 const std::string& data) { | |
426 EXPECT_EQ(std::string("bobsyeruncle"), data); | |
427 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
428 cookies, data); | |
429 } | |
430 | |
431 void URLFetcherHeadersTest::OnURLFetchComplete( | |
432 const URLFetcher* source, | |
433 const GURL& url, | |
434 const net::URLRequestStatus& status, | |
435 int response_code, | |
436 const net::ResponseCookies& cookies, | |
437 const std::string& data) { | |
438 std::string header; | |
439 EXPECT_TRUE(source->response_headers()->GetNormalizedHeader("cache-control", | |
440 &header)); | |
441 EXPECT_EQ("private", header); | |
442 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
443 cookies, data); | |
444 } | |
445 | |
446 void URLFetcherSocketAddressTest::OnURLFetchComplete( | |
447 const URLFetcher* source, | |
448 const GURL& url, | |
449 const net::URLRequestStatus& status, | |
450 int response_code, | |
451 const net::ResponseCookies& cookies, | |
452 const std::string& data) { | |
453 EXPECT_EQ("127.0.0.1", source->socket_address().host()); | |
454 EXPECT_EQ(expected_port_, source->socket_address().port()); | |
455 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
456 cookies, data); | |
457 } | |
458 | |
459 void URLFetcherProtectTest::CreateFetcher(const GURL& url) { | |
460 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
461 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
462 io_message_loop_proxy())); | |
463 start_time_ = Time::Now(); | |
464 fetcher_->set_max_retries(11); | |
465 fetcher_->Start(); | |
466 } | |
467 | |
468 void URLFetcherProtectTest::OnURLFetchComplete( | |
469 const URLFetcher* source, | |
470 const GURL& url, | |
471 const net::URLRequestStatus& status, | |
472 int response_code, | |
473 const net::ResponseCookies& cookies, | |
474 const std::string& data) { | |
475 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000); | |
476 if (response_code >= 500) { | |
477 // Now running ServerUnavailable test. | |
478 // It takes more than 1 second to finish all 11 requests. | |
479 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); | |
480 EXPECT_TRUE(status.is_success()); | |
481 EXPECT_FALSE(data.empty()); | |
482 delete fetcher_; | |
483 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
484 } else { | |
485 // Now running Overload test. | |
486 static int count = 0; | |
487 count++; | |
488 if (count < 20) { | |
489 fetcher_->Start(); | |
490 } else { | |
491 // We have already sent 20 requests continuously. And we expect that | |
492 // it takes more than 1 second due to the overload protection settings. | |
493 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); | |
494 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
495 cookies, data); | |
496 } | |
497 } | |
498 } | |
499 | |
500 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) { | |
501 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
502 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
503 io_message_loop_proxy())); | |
504 fetcher_->set_automatically_retry_on_5xx(false); | |
505 start_time_ = Time::Now(); | |
506 fetcher_->set_max_retries(11); | |
507 fetcher_->Start(); | |
508 } | |
509 | |
510 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete( | |
511 const URLFetcher* source, | |
512 const GURL& url, | |
513 const net::URLRequestStatus& status, | |
514 int response_code, | |
515 const net::ResponseCookies& cookies, | |
516 const std::string& data) { | |
517 const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000); | |
518 if (response_code >= 500) { | |
519 // Now running ServerUnavailable test. | |
520 // It should get here on the first attempt, so almost immediately and | |
521 // *not* to attempt to execute all 11 requests (2.5 minutes). | |
522 EXPECT_TRUE(Time::Now() - start_time_ < one_minute); | |
523 EXPECT_TRUE(status.is_success()); | |
524 // Check that suggested back off time is bigger than 0. | |
525 EXPECT_GT(fetcher_->backoff_delay().InMicroseconds(), 0); | |
526 EXPECT_FALSE(data.empty()); | |
527 } else { | |
528 // We should not get here! | |
529 ADD_FAILURE(); | |
530 } | |
531 | |
532 delete fetcher_; | |
533 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
534 } | |
535 | |
536 | |
537 URLFetcherBadHTTPSTest::URLFetcherBadHTTPSTest() { | |
538 PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); | |
539 cert_dir_ = cert_dir_.AppendASCII("chrome"); | |
540 cert_dir_ = cert_dir_.AppendASCII("test"); | |
541 cert_dir_ = cert_dir_.AppendASCII("data"); | |
542 cert_dir_ = cert_dir_.AppendASCII("ssl"); | |
543 cert_dir_ = cert_dir_.AppendASCII("certificates"); | |
544 } | |
545 | |
546 // The "server certificate expired" error should result in automatic | |
547 // cancellation of the request by | |
548 // net::URLRequest::Delegate::OnSSLCertificateError. | |
549 void URLFetcherBadHTTPSTest::OnURLFetchComplete( | |
550 const URLFetcher* source, | |
551 const GURL& url, | |
552 const net::URLRequestStatus& status, | |
553 int response_code, | |
554 const net::ResponseCookies& cookies, | |
555 const std::string& data) { | |
556 // This part is different from URLFetcherTest::OnURLFetchComplete | |
557 // because this test expects the request to be cancelled. | |
558 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status()); | |
559 EXPECT_EQ(net::ERR_ABORTED, status.os_error()); | |
560 EXPECT_EQ(-1, response_code); | |
561 EXPECT_TRUE(cookies.empty()); | |
562 EXPECT_TRUE(data.empty()); | |
563 | |
564 // The rest is the same as URLFetcherTest::OnURLFetchComplete. | |
565 delete fetcher_; | |
566 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
567 } | |
568 | |
569 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { | |
570 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
571 CancelTestURLRequestContextGetter* context_getter = | |
572 new CancelTestURLRequestContextGetter(io_message_loop_proxy()); | |
573 fetcher_->set_request_context(context_getter); | |
574 fetcher_->set_max_retries(2); | |
575 fetcher_->Start(); | |
576 // We need to wait for the creation of the net::URLRequestContext, since we | |
577 // rely on it being destroyed as a signal to end the test. | |
578 context_getter->WaitForContextCreation(); | |
579 CancelRequest(); | |
580 } | |
581 | |
582 void URLFetcherCancelTest::OnURLFetchComplete( | |
583 const URLFetcher* source, | |
584 const GURL& url, | |
585 const net::URLRequestStatus& status, | |
586 int response_code, | |
587 const net::ResponseCookies& cookies, | |
588 const std::string& data) { | |
589 // We should have cancelled the request before completion. | |
590 ADD_FAILURE(); | |
591 delete fetcher_; | |
592 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
593 } | |
594 | |
595 void URLFetcherCancelTest::CancelRequest() { | |
596 delete fetcher_; | |
597 // The URLFetcher's test context will post a Quit task once it is | |
598 // deleted. So if this test simply hangs, it means cancellation | |
599 // did not work. | |
600 } | |
601 | |
602 void URLFetcherMultipleAttemptTest::OnURLFetchComplete( | |
603 const URLFetcher* source, | |
604 const GURL& url, | |
605 const net::URLRequestStatus& status, | |
606 int response_code, | |
607 const net::ResponseCookies& cookies, | |
608 const std::string& data) { | |
609 EXPECT_TRUE(status.is_success()); | |
610 EXPECT_EQ(200, response_code); // HTTP OK | |
611 EXPECT_FALSE(data.empty()); | |
612 if (!data.empty() && data_.empty()) { | |
613 data_ = data; | |
614 fetcher_->Start(); | |
615 } else { | |
616 EXPECT_EQ(data, data_); | |
617 delete fetcher_; // Have to delete this here and not in the destructor, | |
618 // because the destructor won't necessarily run on the | |
619 // same thread that CreateFetcher() did. | |
620 | |
621 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
622 // If the current message loop is not the IO loop, it will be shut down when | |
623 // the main loop returns and this thread subsequently goes out of scope. | |
624 } | |
625 } | |
626 | |
627 void URLFetcherTempFileTest::OnURLFetchComplete(const URLFetcher* source) { | |
628 EXPECT_TRUE(source->status().is_success()); | |
629 EXPECT_EQ(source->response_code(), 200); | |
630 | |
631 EXPECT_TRUE(source->GetResponseAsFilePath( | |
632 take_ownership_of_temp_file_, &temp_file_)); | |
633 | |
634 EXPECT_TRUE(file_util::ContentsEqual(expected_file_, temp_file_)); | |
635 | |
636 delete fetcher_; | |
637 | |
638 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
639 } | |
640 | |
641 void URLFetcherTempFileTest::OnURLFetchComplete( | |
642 const URLFetcher* source, | |
643 const GURL& url, | |
644 const net::URLRequestStatus& status, | |
645 int response_code, | |
646 const net::ResponseCookies& cookies, | |
647 const std::string& data) { | |
648 NOTREACHED(); | |
649 } | |
650 | |
651 | |
652 TEST_F(URLFetcherTest, SameThreadsTest) { | |
653 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
654 ASSERT_TRUE(test_server.Start()); | |
655 | |
656 // Create the fetcher on the main thread. Since IO will happen on the main | |
657 // thread, this will test URLFetcher's ability to do everything on one | |
658 // thread. | |
659 CreateFetcher(test_server.GetURL("defaultresponse")); | |
660 | |
661 MessageLoop::current()->Run(); | |
662 } | |
663 | |
664 #if defined(OS_MACOSX) | |
665 // SIGSEGV on Mac: http://crbug.com/60426 | |
666 TEST_F(URLFetcherTest, DISABLED_DifferentThreadsTest) { | |
667 #else | |
668 TEST_F(URLFetcherTest, DifferentThreadsTest) { | |
669 #endif | |
670 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
671 ASSERT_TRUE(test_server.Start()); | |
672 | |
673 // Create a separate thread that will create the URLFetcher. The current | |
674 // (main) thread will do the IO, and when the fetch is complete it will | |
675 // terminate the main thread's message loop; then the other thread's | |
676 // message loop will be shut down automatically as the thread goes out of | |
677 // scope. | |
678 base::Thread t("URLFetcher test thread"); | |
679 ASSERT_TRUE(t.Start()); | |
680 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, | |
681 test_server.GetURL("defaultresponse"))); | |
682 | |
683 MessageLoop::current()->Run(); | |
684 } | |
685 | |
686 #if defined(OS_MACOSX) | |
687 // SIGSEGV on Mac: http://crbug.com/60426 | |
688 TEST_F(URLFetcherPostTest, DISABLED_Basic) { | |
689 #else | |
690 TEST_F(URLFetcherPostTest, Basic) { | |
691 #endif | |
692 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
693 ASSERT_TRUE(test_server.Start()); | |
694 | |
695 CreateFetcher(test_server.GetURL("echo")); | |
696 MessageLoop::current()->Run(); | |
697 } | |
698 | |
699 TEST_F(URLFetcherHeadersTest, Headers) { | |
700 net::TestServer test_server(net::TestServer::TYPE_HTTP, | |
701 FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
702 ASSERT_TRUE(test_server.Start()); | |
703 | |
704 CreateFetcher(test_server.GetURL("files/with-headers.html")); | |
705 MessageLoop::current()->Run(); | |
706 // The actual tests are in the URLFetcherHeadersTest fixture. | |
707 } | |
708 | |
709 TEST_F(URLFetcherSocketAddressTest, SocketAddress) { | |
710 net::TestServer test_server(net::TestServer::TYPE_HTTP, | |
711 FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
712 ASSERT_TRUE(test_server.Start()); | |
713 expected_port_ = test_server.host_port_pair().port(); | |
714 | |
715 // Reusing "with-headers.html" but doesn't really matter. | |
716 CreateFetcher(test_server.GetURL("files/with-headers.html")); | |
717 MessageLoop::current()->Run(); | |
718 // The actual tests are in the URLFetcherSocketAddressTest fixture. | |
719 } | |
720 | |
721 TEST_F(URLFetcherProtectTest, Overload) { | |
722 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
723 ASSERT_TRUE(test_server.Start()); | |
724 | |
725 GURL url(test_server.GetURL("defaultresponse")); | |
726 | |
727 // Registers an entry for test url. It only allows 3 requests to be sent | |
728 // in 200 milliseconds. | |
729 net::URLRequestThrottlerManager* manager = | |
730 net::URLRequestThrottlerManager::GetInstance(); | |
731 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
732 new net::URLRequestThrottlerEntry(manager, "", 200, 3, 1, 2.0, 0.0, 256)); | |
733 manager->OverrideEntryForTests(url, entry); | |
734 | |
735 CreateFetcher(url); | |
736 | |
737 MessageLoop::current()->Run(); | |
738 | |
739 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
740 } | |
741 | |
742 TEST_F(URLFetcherProtectTest, ServerUnavailable) { | |
743 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
744 ASSERT_TRUE(test_server.Start()); | |
745 | |
746 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
747 | |
748 // Registers an entry for test url. The backoff time is calculated by: | |
749 // new_backoff = 2.0 * old_backoff + 0 | |
750 // and maximum backoff time is 256 milliseconds. | |
751 // Maximum retries allowed is set to 11. | |
752 net::URLRequestThrottlerManager* manager = | |
753 net::URLRequestThrottlerManager::GetInstance(); | |
754 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
755 new net::URLRequestThrottlerEntry(manager, "", 200, 3, 1, 2.0, 0.0, 256)); | |
756 manager->OverrideEntryForTests(url, entry); | |
757 | |
758 CreateFetcher(url); | |
759 | |
760 MessageLoop::current()->Run(); | |
761 | |
762 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
763 } | |
764 | |
765 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) { | |
766 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
767 ASSERT_TRUE(test_server.Start()); | |
768 | |
769 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
770 | |
771 // Registers an entry for test url. The backoff time is calculated by: | |
772 // new_backoff = 2.0 * old_backoff + 0 | |
773 // and maximum backoff time is 150000 milliseconds. | |
774 // Maximum retries allowed is set to 11. | |
775 net::URLRequestThrottlerManager* manager = | |
776 net::URLRequestThrottlerManager::GetInstance(); | |
777 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
778 new net::URLRequestThrottlerEntry( | |
779 manager, "", 200, 3, 100, 2.0, 0.0, 150000)); | |
780 // Total time if *not* for not doing automatic backoff would be 150s. | |
781 // In reality it should be "as soon as server responds". | |
782 manager->OverrideEntryForTests(url, entry); | |
783 | |
784 CreateFetcher(url); | |
785 | |
786 MessageLoop::current()->Run(); | |
787 | |
788 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
789 } | |
790 | |
791 #if defined(OS_MACOSX) | |
792 // SIGSEGV on Mac: http://crbug.com/60426 | |
793 TEST_F(URLFetcherBadHTTPSTest, DISABLED_BadHTTPSTest) { | |
794 #else | |
795 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { | |
796 #endif | |
797 net::TestServer::HTTPSOptions https_options( | |
798 net::TestServer::HTTPSOptions::CERT_EXPIRED); | |
799 net::TestServer test_server(https_options, FilePath(kDocRoot)); | |
800 ASSERT_TRUE(test_server.Start()); | |
801 | |
802 CreateFetcher(test_server.GetURL("defaultresponse")); | |
803 MessageLoop::current()->Run(); | |
804 } | |
805 | |
806 #if defined(OS_MACOSX) | |
807 // SIGSEGV on Mac: http://crbug.com/60426 | |
808 TEST_F(URLFetcherCancelTest, DISABLED_ReleasesContext) { | |
809 #else | |
810 TEST_F(URLFetcherCancelTest, ReleasesContext) { | |
811 #endif | |
812 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
813 ASSERT_TRUE(test_server.Start()); | |
814 | |
815 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
816 | |
817 // Registers an entry for test url. The backoff time is calculated by: | |
818 // new_backoff = 2.0 * old_backoff +0 | |
819 // The initial backoff is 2 seconds and maximum backoff is 4 seconds. | |
820 // Maximum retries allowed is set to 2. | |
821 net::URLRequestThrottlerManager* manager = | |
822 net::URLRequestThrottlerManager::GetInstance(); | |
823 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
824 new net::URLRequestThrottlerEntry( | |
825 manager, "", 200, 3, 2000, 2.0, 0.0, 4000)); | |
826 manager->OverrideEntryForTests(url, entry); | |
827 | |
828 // Create a separate thread that will create the URLFetcher. The current | |
829 // (main) thread will do the IO, and when the fetch is complete it will | |
830 // terminate the main thread's message loop; then the other thread's | |
831 // message loop will be shut down automatically as the thread goes out of | |
832 // scope. | |
833 base::Thread t("URLFetcher test thread"); | |
834 ASSERT_TRUE(t.Start()); | |
835 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); | |
836 | |
837 MessageLoop::current()->Run(); | |
838 | |
839 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
840 } | |
841 | |
842 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) { | |
843 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
844 ASSERT_TRUE(test_server.Start()); | |
845 | |
846 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
847 | |
848 // Register an entry for test url. | |
849 // Using a sliding window of 4 seconds, and max of 1 request, under a fast | |
850 // run we expect to have a 4 second delay when posting the Start task. | |
851 net::URLRequestThrottlerManager* manager = | |
852 net::URLRequestThrottlerManager::GetInstance(); | |
853 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
854 new net::URLRequestThrottlerEntry( | |
855 manager, "", 4000, 1, 2000, 2.0, 0.0, 4000)); | |
856 manager->OverrideEntryForTests(url, entry); | |
857 // Fake that a request has just started. | |
858 entry->ReserveSendingTimeForNextRequest(base::TimeTicks()); | |
859 | |
860 // The next request we try to send will be delayed by ~4 seconds. | |
861 // The slower the test runs, the less the delay will be (since it takes the | |
862 // time difference from now). | |
863 | |
864 base::Thread t("URLFetcher test thread"); | |
865 ASSERT_TRUE(t.Start()); | |
866 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); | |
867 | |
868 MessageLoop::current()->Run(); | |
869 | |
870 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
871 } | |
872 | |
873 TEST_F(URLFetcherMultipleAttemptTest, SameData) { | |
874 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
875 ASSERT_TRUE(test_server.Start()); | |
876 | |
877 // Create the fetcher on the main thread. Since IO will happen on the main | |
878 // thread, this will test URLFetcher's ability to do everything on one | |
879 // thread. | |
880 CreateFetcher(test_server.GetURL("defaultresponse")); | |
881 | |
882 MessageLoop::current()->Run(); | |
883 } | |
884 | |
885 // Tests to make sure CancelAll() will successfully cancel existing URLFetchers. | |
886 TEST_F(URLFetcherTest, CancelAll) { | |
887 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
888 ASSERT_TRUE(test_server.Start()); | |
889 EXPECT_EQ(0, GetNumFetcherCores()); | |
890 | |
891 CreateFetcher(test_server.GetURL("defaultresponse")); | |
892 io_message_loop_proxy()->PostTask( | |
893 FROM_HERE, | |
894 new CurriedTask(new MessageLoop::QuitTask(), MessageLoop::current())); | |
895 MessageLoop::current()->Run(); | |
896 EXPECT_EQ(1, GetNumFetcherCores()); | |
897 URLFetcher::CancelAll(); | |
898 EXPECT_EQ(0, GetNumFetcherCores()); | |
899 delete fetcher_; | |
900 } | |
901 | |
902 } // namespace. | |
OLD | NEW |