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