Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/url_request/url_fetcher_impl.h" | 5 #include "net/url_request/url_fetcher_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
| 12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
| 13 #include "base/stringprintf.h" | |
| 13 #include "base/synchronization/waitable_event.h" | 14 #include "base/synchronization/waitable_event.h" |
| 14 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 15 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 16 #include "crypto/nss_util.h" | 17 #include "crypto/nss_util.h" |
| 18 #include "net/base/mock_host_resolver.h" | |
| 19 #include "net/base/network_change_notifier.h" | |
| 17 #include "net/http/http_response_headers.h" | 20 #include "net/http/http_response_headers.h" |
| 18 #include "net/test/test_server.h" | 21 #include "net/test/test_server.h" |
| 19 #include "net/url_request/url_fetcher_delegate.h" | 22 #include "net/url_request/url_fetcher_delegate.h" |
| 20 #include "net/url_request/url_request_context_getter.h" | 23 #include "net/url_request/url_request_context_getter.h" |
| 21 #include "net/url_request/url_request_test_util.h" | 24 #include "net/url_request/url_request_test_util.h" |
| 22 #include "net/url_request/url_request_throttler_manager.h" | 25 #include "net/url_request/url_request_throttler_manager.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 27 |
| 25 #if defined(USE_NSS) || defined(OS_IOS) | 28 #if defined(USE_NSS) || defined(OS_IOS) |
| 26 #include "net/ocsp/nss_ocsp.h" | 29 #include "net/ocsp/nss_ocsp.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE { | 68 virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE { |
| 66 return context_; | 69 return context_; |
| 67 } | 70 } |
| 68 | 71 |
| 69 protected: | 72 protected: |
| 70 virtual ~ThrottlingTestURLRequestContextGetter() {} | 73 virtual ~ThrottlingTestURLRequestContextGetter() {} |
| 71 | 74 |
| 72 TestURLRequestContext* const context_; | 75 TestURLRequestContext* const context_; |
| 73 }; | 76 }; |
| 74 | 77 |
| 78 class TestNetworkChangeNotifier : public NetworkChangeNotifier { | |
| 79 public: | |
| 80 TestNetworkChangeNotifier() : connection_type_(CONNECTION_UNKNOWN) {} | |
| 81 | |
| 82 // Implementation of NetworkChangeNotifier: | |
| 83 virtual ConnectionType GetCurrentConnectionType() const OVERRIDE { | |
| 84 return connection_type_; | |
| 85 } | |
| 86 | |
| 87 void SetCurrentConnectionType(ConnectionType type) { | |
| 88 connection_type_ = type; | |
| 89 NotifyObserversOfConnectionTypeChange(); | |
| 90 } | |
| 91 | |
| 92 private: | |
| 93 ConnectionType connection_type_; | |
| 94 }; | |
| 95 | |
| 75 } // namespace | 96 } // namespace |
| 76 | 97 |
| 77 class URLFetcherTest : public testing::Test, | 98 class URLFetcherTest : public testing::Test, |
| 78 public URLFetcherDelegate { | 99 public URLFetcherDelegate { |
| 79 public: | 100 public: |
| 80 URLFetcherTest() | 101 URLFetcherTest() |
| 81 : fetcher_(NULL), | 102 : fetcher_(NULL), |
| 82 context_(new ThrottlingTestURLRequestContext()) { | 103 context_(NULL) { |
| 83 } | 104 } |
| 84 | 105 |
| 85 static int GetNumFetcherCores() { | 106 static int GetNumFetcherCores() { |
| 86 return URLFetcherImpl::GetNumFetcherCores(); | 107 return URLFetcherImpl::GetNumFetcherCores(); |
| 87 } | 108 } |
| 88 | 109 |
| 89 // Creates a URLFetcher, using the program's main thread to do IO. | 110 // Creates a URLFetcher, using the program's main thread to do IO. |
| 90 virtual void CreateFetcher(const GURL& url); | 111 virtual void CreateFetcher(const GURL& url); |
| 91 | 112 |
| 92 // URLFetcherDelegate: | 113 // URLFetcherDelegate: |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 104 | 125 |
| 105 TestURLRequestContext* request_context() { | 126 TestURLRequestContext* request_context() { |
| 106 return context_.get(); | 127 return context_.get(); |
| 107 } | 128 } |
| 108 | 129 |
| 109 protected: | 130 protected: |
| 110 // testing::Test: | 131 // testing::Test: |
| 111 virtual void SetUp() OVERRIDE { | 132 virtual void SetUp() OVERRIDE { |
| 112 testing::Test::SetUp(); | 133 testing::Test::SetUp(); |
| 113 | 134 |
| 135 context_.reset(new ThrottlingTestURLRequestContext()); | |
| 114 io_message_loop_proxy_ = base::MessageLoopProxy::current(); | 136 io_message_loop_proxy_ = base::MessageLoopProxy::current(); |
| 115 | 137 |
| 116 #if defined(USE_NSS) || defined(OS_IOS) | 138 #if defined(USE_NSS) || defined(OS_IOS) |
| 117 crypto::EnsureNSSInit(); | 139 crypto::EnsureNSSInit(); |
| 118 EnsureNSSHttpIOInit(); | 140 EnsureNSSHttpIOInit(); |
| 119 #endif | 141 #endif |
| 120 } | 142 } |
| 121 | 143 |
| 122 virtual void TearDown() OVERRIDE { | 144 virtual void TearDown() OVERRIDE { |
| 123 #if defined(USE_NSS) || defined(OS_IOS) | 145 #if defined(USE_NSS) || defined(OS_IOS) |
| 124 ShutdownNSSHttpIO(); | 146 ShutdownNSSHttpIO(); |
| 125 #endif | 147 #endif |
| 126 } | 148 } |
| 127 | 149 |
| 128 // URLFetcher is designed to run on the main UI thread, but in our tests | 150 // URLFetcher is designed to run on the main UI thread, but in our tests |
| 129 // we assume that the current thread is the IO thread where the URLFetcher | 151 // we assume that the current thread is the IO thread where the URLFetcher |
| 130 // dispatches its requests to. When we wish to simulate being used from | 152 // dispatches its requests to. When we wish to simulate being used from |
| 131 // a UI thread, we dispatch a worker thread to do so. | 153 // a UI thread, we dispatch a worker thread to do so. |
| 132 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 154 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
| 133 | 155 |
| 134 URLFetcherImpl* fetcher_; | 156 URLFetcherImpl* fetcher_; |
| 135 const scoped_ptr<TestURLRequestContext> context_; | 157 scoped_ptr<TestURLRequestContext> context_; |
| 158 }; | |
| 159 | |
| 160 // A test fixture that uses a MockHostResolver, so that name resolutions can | |
| 161 // be manipulated by the tests to keep connections in the resolving state. | |
| 162 class URLFetcherMockDNSTest : public URLFetcherTest { | |
|
szym
2012/12/12 19:50:46
nit: Suggest 'Dns' (like 'Http' and most code in n
Joao da Silva
2012/12/12 20:17:20
Done.
| |
| 163 public: | |
| 164 // testing::Test: | |
| 165 virtual void SetUp() OVERRIDE; | |
| 166 | |
| 167 // URLFetcherTest: | |
| 168 virtual void CreateFetcher(const GURL& url) OVERRIDE; | |
| 169 | |
| 170 // URLFetcherDelegate: | |
| 171 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; | |
| 172 | |
| 173 protected: | |
| 174 GURL test_url_; | |
| 175 scoped_ptr<TestServer> test_server_; | |
| 176 MockHostResolver resolver_; | |
| 177 scoped_ptr<URLFetcher> completed_fetcher_; | |
| 178 NetworkChangeNotifier::DisableForTest disable_default_notifier_; | |
| 179 TestNetworkChangeNotifier network_change_notifier_; | |
| 136 }; | 180 }; |
| 137 | 181 |
| 138 void URLFetcherTest::CreateFetcher(const GURL& url) { | 182 void URLFetcherTest::CreateFetcher(const GURL& url) { |
| 139 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | 183 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); |
| 140 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | 184 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( |
| 141 io_message_loop_proxy(), request_context())); | 185 io_message_loop_proxy(), request_context())); |
| 142 fetcher_->Start(); | 186 fetcher_->Start(); |
| 143 } | 187 } |
| 144 | 188 |
| 145 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) { | 189 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 156 void URLFetcherTest::CleanupAfterFetchComplete() { | 200 void URLFetcherTest::CleanupAfterFetchComplete() { |
| 157 delete fetcher_; // Have to delete this here and not in the destructor, | 201 delete fetcher_; // Have to delete this here and not in the destructor, |
| 158 // because the destructor won't necessarily run on the | 202 // because the destructor won't necessarily run on the |
| 159 // same thread that CreateFetcher() did. | 203 // same thread that CreateFetcher() did. |
| 160 | 204 |
| 161 io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 205 io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 162 // If the current message loop is not the IO loop, it will be shut down when | 206 // If the current message loop is not the IO loop, it will be shut down when |
| 163 // the main loop returns and this thread subsequently goes out of scope. | 207 // the main loop returns and this thread subsequently goes out of scope. |
| 164 } | 208 } |
| 165 | 209 |
| 210 void URLFetcherMockDNSTest::SetUp() { | |
| 211 URLFetcherTest::SetUp(); | |
| 212 | |
| 213 resolver_.set_ondemand_mode(true); | |
| 214 resolver_.rules()->AddRule("example.com", "127.0.0.1"); | |
| 215 | |
| 216 context_.reset(new TestURLRequestContext(true)); | |
| 217 context_->set_host_resolver(&resolver_); | |
| 218 context_->Init(); | |
| 219 | |
| 220 test_server_.reset(new TestServer(TestServer::TYPE_HTTP, | |
| 221 TestServer::kLocalhost, | |
| 222 FilePath(kDocRoot))); | |
| 223 ASSERT_TRUE(test_server_->Start()); | |
| 224 | |
| 225 // test_server_.GetURL() returns a URL with 127.0.0.1 (kLocalhost), that is | |
| 226 // immediately resolved by the MockHostResolver. Use a hostname instead to | |
| 227 // trigger an async resolve. | |
| 228 test_url_ = GURL( | |
| 229 base::StringPrintf("http://example.com:%d/defaultresponse", | |
| 230 test_server_->host_port_pair().port())); | |
| 231 ASSERT_TRUE(test_url_.is_valid()); | |
| 232 } | |
| 233 | |
| 234 void URLFetcherMockDNSTest::CreateFetcher(const GURL& url) { | |
| 235 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | |
| 236 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | |
| 237 io_message_loop_proxy(), request_context())); | |
| 238 } | |
| 239 | |
| 240 void URLFetcherMockDNSTest::OnURLFetchComplete(const URLFetcher* source) { | |
| 241 io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | |
| 242 ASSERT_EQ(fetcher_, source); | |
| 243 EXPECT_EQ(test_url_, source->GetOriginalURL()); | |
| 244 completed_fetcher_.reset(fetcher_); | |
| 245 } | |
| 246 | |
| 166 namespace { | 247 namespace { |
| 167 | 248 |
| 168 // Version of URLFetcherTest that does a POST instead | 249 // Version of URLFetcherTest that does a POST instead |
| 169 class URLFetcherPostTest : public URLFetcherTest { | 250 class URLFetcherPostTest : public URLFetcherTest { |
| 170 public: | 251 public: |
| 171 // URLFetcherTest: | 252 // URLFetcherTest: |
| 172 virtual void CreateFetcher(const GURL& url) OVERRIDE; | 253 virtual void CreateFetcher(const GURL& url) OVERRIDE; |
| 173 | 254 |
| 174 // URLFetcherDelegate: | 255 // URLFetcherDelegate: |
| 175 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; | 256 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 EXPECT_EQ(ERR_ABORTED, source->GetStatus().error()); | 658 EXPECT_EQ(ERR_ABORTED, source->GetStatus().error()); |
| 578 EXPECT_EQ(301, source->GetResponseCode()); | 659 EXPECT_EQ(301, source->GetResponseCode()); |
| 579 CleanupAfterFetchComplete(); | 660 CleanupAfterFetchComplete(); |
| 580 } | 661 } |
| 581 | 662 |
| 582 void URLFetcherProtectTest::CreateFetcher(const GURL& url) { | 663 void URLFetcherProtectTest::CreateFetcher(const GURL& url) { |
| 583 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | 664 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); |
| 584 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | 665 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( |
| 585 io_message_loop_proxy(), request_context())); | 666 io_message_loop_proxy(), request_context())); |
| 586 start_time_ = Time::Now(); | 667 start_time_ = Time::Now(); |
| 587 fetcher_->SetMaxRetries(11); | 668 fetcher_->SetMaxRetriesOn5xx(11); |
| 588 fetcher_->Start(); | 669 fetcher_->Start(); |
| 589 } | 670 } |
| 590 | 671 |
| 591 void URLFetcherProtectTest::OnURLFetchComplete(const URLFetcher* source) { | 672 void URLFetcherProtectTest::OnURLFetchComplete(const URLFetcher* source) { |
| 592 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000); | 673 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000); |
| 593 if (source->GetResponseCode() >= 500) { | 674 if (source->GetResponseCode() >= 500) { |
| 594 // Now running ServerUnavailable test. | 675 // Now running ServerUnavailable test. |
| 595 // It takes more than 1 second to finish all 11 requests. | 676 // It takes more than 1 second to finish all 11 requests. |
| 596 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); | 677 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); |
| 597 EXPECT_TRUE(source->GetStatus().is_success()); | 678 EXPECT_TRUE(source->GetStatus().is_success()); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 616 } | 697 } |
| 617 } | 698 } |
| 618 } | 699 } |
| 619 | 700 |
| 620 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) { | 701 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) { |
| 621 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | 702 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); |
| 622 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | 703 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( |
| 623 io_message_loop_proxy(), request_context())); | 704 io_message_loop_proxy(), request_context())); |
| 624 fetcher_->SetAutomaticallyRetryOn5xx(false); | 705 fetcher_->SetAutomaticallyRetryOn5xx(false); |
| 625 start_time_ = Time::Now(); | 706 start_time_ = Time::Now(); |
| 626 fetcher_->SetMaxRetries(11); | 707 fetcher_->SetMaxRetriesOn5xx(11); |
| 627 fetcher_->Start(); | 708 fetcher_->Start(); |
| 628 } | 709 } |
| 629 | 710 |
| 630 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete( | 711 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete( |
| 631 const URLFetcher* source) { | 712 const URLFetcher* source) { |
| 632 const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000); | 713 const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000); |
| 633 if (source->GetResponseCode() >= 500) { | 714 if (source->GetResponseCode() >= 500) { |
| 634 // Now running ServerUnavailable test. | 715 // Now running ServerUnavailable test. |
| 635 // It should get here on the first attempt, so almost immediately and | 716 // It should get here on the first attempt, so almost immediately and |
| 636 // *not* to attempt to execute all 11 requests (2.5 minutes). | 717 // *not* to attempt to execute all 11 requests (2.5 minutes). |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 675 EXPECT_TRUE(data.empty()); | 756 EXPECT_TRUE(data.empty()); |
| 676 CleanupAfterFetchComplete(); | 757 CleanupAfterFetchComplete(); |
| 677 } | 758 } |
| 678 | 759 |
| 679 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { | 760 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { |
| 680 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | 761 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); |
| 681 CancelTestURLRequestContextGetter* context_getter = | 762 CancelTestURLRequestContextGetter* context_getter = |
| 682 new CancelTestURLRequestContextGetter(io_message_loop_proxy(), | 763 new CancelTestURLRequestContextGetter(io_message_loop_proxy(), |
| 683 url); | 764 url); |
| 684 fetcher_->SetRequestContext(context_getter); | 765 fetcher_->SetRequestContext(context_getter); |
| 685 fetcher_->SetMaxRetries(2); | 766 fetcher_->SetMaxRetriesOn5xx(2); |
| 686 fetcher_->Start(); | 767 fetcher_->Start(); |
| 687 // We need to wait for the creation of the URLRequestContext, since we | 768 // We need to wait for the creation of the URLRequestContext, since we |
| 688 // rely on it being destroyed as a signal to end the test. | 769 // rely on it being destroyed as a signal to end the test. |
| 689 context_getter->WaitForContextCreation(); | 770 context_getter->WaitForContextCreation(); |
| 690 CancelRequest(); | 771 CancelRequest(); |
| 691 } | 772 } |
| 692 | 773 |
| 693 void URLFetcherCancelTest::OnURLFetchComplete( | 774 void URLFetcherCancelTest::OnURLFetchComplete( |
| 694 const URLFetcher* source) { | 775 const URLFetcher* source) { |
| 695 // We should have cancelled the request before completion. | 776 // We should have cancelled the request before completion. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 821 CreateFetcher(test_server.GetURL("defaultresponse")); | 902 CreateFetcher(test_server.GetURL("defaultresponse")); |
| 822 io_message_loop_proxy()->PostTaskAndReply( | 903 io_message_loop_proxy()->PostTaskAndReply( |
| 823 FROM_HERE, | 904 FROM_HERE, |
| 824 base::Bind(&CancelAllOnIO), | 905 base::Bind(&CancelAllOnIO), |
| 825 MessageLoop::QuitClosure()); | 906 MessageLoop::QuitClosure()); |
| 826 MessageLoop::current()->Run(); | 907 MessageLoop::current()->Run(); |
| 827 EXPECT_EQ(0, GetNumFetcherCores()); | 908 EXPECT_EQ(0, GetNumFetcherCores()); |
| 828 delete fetcher_; | 909 delete fetcher_; |
| 829 } | 910 } |
| 830 | 911 |
| 912 TEST_F(URLFetcherMockDNSTest, DontRetryOnNetworkChangedByDefault) { | |
| 913 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 914 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 915 | |
| 916 // This posts a task to start the fetcher. | |
| 917 CreateFetcher(test_url_); | |
| 918 fetcher_->Start(); | |
| 919 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 920 MessageLoop::current()->RunUntilIdle(); | |
| 921 | |
| 922 // The fetcher is now running, but is pending the host resolve. | |
| 923 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 924 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 925 ASSERT_FALSE(completed_fetcher_); | |
| 926 | |
| 927 // A network change notification aborts the connect job. | |
| 928 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 929 MessageLoop::current()->RunUntilIdle(); | |
| 930 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 931 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 932 ASSERT_TRUE(completed_fetcher_); | |
| 933 | |
| 934 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. | |
| 935 EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error()); | |
| 936 } | |
| 937 | |
| 938 TEST_F(URLFetcherMockDNSTest, RetryOnNetworkChangedAndFail) { | |
| 939 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 940 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 941 | |
| 942 // This posts a task to start the fetcher. | |
| 943 CreateFetcher(test_url_); | |
| 944 fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); | |
| 945 fetcher_->Start(); | |
| 946 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 947 MessageLoop::current()->RunUntilIdle(); | |
| 948 | |
| 949 // The fetcher is now running, but is pending the host resolve. | |
| 950 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 951 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 952 ASSERT_FALSE(completed_fetcher_); | |
| 953 | |
| 954 // Make it fail 3 times. | |
| 955 for (int i = 0; i < 3; ++i) { | |
| 956 // A network change notification aborts the connect job. | |
| 957 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 958 MessageLoop::current()->RunUntilIdle(); | |
| 959 | |
| 960 // But the fetcher retries automatically. | |
| 961 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 962 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 963 ASSERT_FALSE(completed_fetcher_); | |
| 964 } | |
| 965 | |
| 966 // A 4th failure doesn't trigger another retry, and propagates the error | |
| 967 // to the owner of the fetcher. | |
| 968 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 969 MessageLoop::current()->RunUntilIdle(); | |
| 970 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 971 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 972 ASSERT_TRUE(completed_fetcher_); | |
| 973 | |
| 974 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. | |
| 975 EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error()); | |
| 976 } | |
| 977 | |
| 978 TEST_F(URLFetcherMockDNSTest, RetryOnNetworkChangedAndSucceed) { | |
| 979 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 980 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 981 | |
| 982 // This posts a task to start the fetcher. | |
| 983 CreateFetcher(test_url_); | |
| 984 fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); | |
| 985 fetcher_->Start(); | |
| 986 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 987 MessageLoop::current()->RunUntilIdle(); | |
| 988 | |
| 989 // The fetcher is now running, but is pending the host resolve. | |
| 990 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 991 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 992 ASSERT_FALSE(completed_fetcher_); | |
| 993 | |
| 994 // Make it fail 3 times. | |
| 995 for (int i = 0; i < 3; ++i) { | |
| 996 // A network change notification aborts the connect job. | |
| 997 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 998 MessageLoop::current()->RunUntilIdle(); | |
| 999 | |
| 1000 // But the fetcher retries automatically. | |
| 1001 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 1002 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 1003 ASSERT_FALSE(completed_fetcher_); | |
| 1004 } | |
| 1005 | |
| 1006 // Now let it succeed by resolving the pending request. | |
| 1007 resolver_.ResolveAllPending(); | |
| 1008 MessageLoop::current()->Run(); | |
| 1009 | |
| 1010 // URLFetcherMockDNSTest::OnURLFetchComplete() will quit the loop. | |
| 1011 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1012 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 1013 ASSERT_TRUE(completed_fetcher_); | |
| 1014 | |
| 1015 // This time the request succeeded. | |
| 1016 EXPECT_EQ(OK, completed_fetcher_->GetStatus().error()); | |
| 1017 EXPECT_EQ(200, completed_fetcher_->GetResponseCode()); | |
| 1018 } | |
| 1019 | |
| 1020 TEST_F(URLFetcherMockDNSTest, RetryAfterComingBackOnline) { | |
| 1021 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1022 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 1023 | |
| 1024 // This posts a task to start the fetcher. | |
| 1025 CreateFetcher(test_url_); | |
| 1026 fetcher_->SetAutomaticallyRetryOnNetworkChanges(1); | |
| 1027 fetcher_->Start(); | |
| 1028 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1029 MessageLoop::current()->RunUntilIdle(); | |
| 1030 | |
| 1031 // The fetcher is now running, but is pending the host resolve. | |
| 1032 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 1033 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 1034 ASSERT_FALSE(completed_fetcher_); | |
| 1035 | |
| 1036 // Make it fail by changing the connection type to offline. | |
| 1037 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, | |
| 1038 NetworkChangeNotifier::GetConnectionType()); | |
| 1039 EXPECT_FALSE(NetworkChangeNotifier::IsOffline()); | |
| 1040 network_change_notifier_.SetCurrentConnectionType( | |
| 1041 NetworkChangeNotifier::CONNECTION_NONE); | |
| 1042 // This makes the connect job fail: | |
| 1043 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 1044 resolver_.ResolveAllPending(); | |
| 1045 MessageLoop::current()->RunUntilIdle(); | |
| 1046 | |
| 1047 // The fetcher is now waiting for the connection to become online again. | |
| 1048 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE, | |
| 1049 NetworkChangeNotifier::GetConnectionType()); | |
| 1050 EXPECT_TRUE(NetworkChangeNotifier::IsOffline()); | |
| 1051 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 1052 ASSERT_FALSE(completed_fetcher_); | |
| 1053 // The core is still alive, but it dropped its request. | |
| 1054 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1055 | |
| 1056 // It should retry once the connection is back. | |
| 1057 network_change_notifier_.SetCurrentConnectionType( | |
| 1058 NetworkChangeNotifier::CONNECTION_WIFI); | |
| 1059 MessageLoop::current()->RunUntilIdle(); | |
| 1060 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 1061 ASSERT_FALSE(completed_fetcher_); | |
| 1062 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 1063 | |
| 1064 // Resolve the pending request; the fetcher should complete now. | |
| 1065 resolver_.ResolveAllPending(); | |
| 1066 MessageLoop::current()->Run(); | |
| 1067 | |
| 1068 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1069 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 1070 ASSERT_TRUE(completed_fetcher_); | |
| 1071 EXPECT_EQ(OK, completed_fetcher_->GetStatus().error()); | |
| 1072 EXPECT_EQ(200, completed_fetcher_->GetResponseCode()); | |
| 1073 } | |
| 1074 | |
| 1075 TEST_F(URLFetcherMockDNSTest, StartOnlyWhenOnline) { | |
| 1076 // Start offline. | |
| 1077 network_change_notifier_.SetCurrentConnectionType( | |
| 1078 NetworkChangeNotifier::CONNECTION_NONE); | |
| 1079 EXPECT_TRUE(NetworkChangeNotifier::IsOffline()); | |
| 1080 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1081 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 1082 | |
| 1083 // Create a fetcher that retries on network changes. It will try to connect | |
| 1084 // only once the network is back online. | |
| 1085 CreateFetcher(test_url_); | |
| 1086 fetcher_->SetAutomaticallyRetryOnNetworkChanges(1); | |
| 1087 fetcher_->Start(); | |
| 1088 MessageLoop::current()->RunUntilIdle(); | |
| 1089 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1090 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 1091 | |
| 1092 // It should retry once the connection is back. | |
| 1093 network_change_notifier_.SetCurrentConnectionType( | |
| 1094 NetworkChangeNotifier::CONNECTION_WIFI); | |
| 1095 MessageLoop::current()->RunUntilIdle(); | |
| 1096 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 1097 ASSERT_FALSE(completed_fetcher_); | |
| 1098 EXPECT_TRUE(resolver_.has_pending_requests()); | |
| 1099 | |
| 1100 // Resolve the pending request; the fetcher should complete now. | |
| 1101 resolver_.ResolveAllPending(); | |
| 1102 MessageLoop::current()->Run(); | |
| 1103 | |
| 1104 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 1105 EXPECT_FALSE(resolver_.has_pending_requests()); | |
| 1106 ASSERT_TRUE(completed_fetcher_); | |
| 1107 EXPECT_EQ(OK, completed_fetcher_->GetStatus().error()); | |
| 1108 EXPECT_EQ(200, completed_fetcher_->GetResponseCode()); | |
| 1109 } | |
| 1110 | |
| 831 #if defined(OS_MACOSX) | 1111 #if defined(OS_MACOSX) |
| 832 // SIGSEGV on Mac: http://crbug.com/60426 | 1112 // SIGSEGV on Mac: http://crbug.com/60426 |
| 833 TEST_F(URLFetcherPostTest, DISABLED_Basic) { | 1113 TEST_F(URLFetcherPostTest, DISABLED_Basic) { |
| 834 #else | 1114 #else |
| 835 TEST_F(URLFetcherPostTest, Basic) { | 1115 TEST_F(URLFetcherPostTest, Basic) { |
| 836 #endif | 1116 #endif |
| 837 TestServer test_server(TestServer::TYPE_HTTP, | 1117 TestServer test_server(TestServer::TYPE_HTTP, |
| 838 TestServer::kLocalhost, | 1118 TestServer::kLocalhost, |
| 839 FilePath(kDocRoot)); | 1119 FilePath(kDocRoot)); |
| 840 ASSERT_TRUE(test_server.Start()); | 1120 ASSERT_TRUE(test_server.Start()); |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1271 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). | 1551 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). |
| 1272 | 1552 |
| 1273 MessageLoop::current()->RunUntilIdle(); | 1553 MessageLoop::current()->RunUntilIdle(); |
| 1274 ASSERT_FALSE(file_util::PathExists(file_path_)) | 1554 ASSERT_FALSE(file_util::PathExists(file_path_)) |
| 1275 << file_path_.value() << " not removed."; | 1555 << file_path_.value() << " not removed."; |
| 1276 } | 1556 } |
| 1277 | 1557 |
| 1278 } // namespace | 1558 } // namespace |
| 1279 | 1559 |
| 1280 } // namespace net | 1560 } // namespace net |
| OLD | NEW |