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