| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2014 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/bind.h" | 
|  | 6 #include "base/lazy_instance.h" | 
|  | 7 #include "base/memory/weak_ptr.h" | 
|  | 8 #include "base/message_loop/message_loop.h" | 
|  | 9 #include "base/run_loop.h" | 
|  | 10 #include "mojo/common/message_pump_mojo.h" | 
|  | 11 #include "mojo/public/cpp/application/application_test_base.h" | 
|  | 12 #include "mojo/services/network/network_context.h" | 
|  | 13 #include "mojo/services/network/url_loader_impl.h" | 
|  | 14 #include "net/url_request/url_request_job.h" | 
|  | 15 #include "net/url_request/url_request_job_factory_impl.h" | 
|  | 16 #include "net/url_request/url_request_test_util.h" | 
|  | 17 #include "testing/gtest/include/gtest/gtest.h" | 
|  | 18 | 
|  | 19 namespace mojo { | 
|  | 20 namespace { | 
|  | 21 | 
|  | 22 class TestURLRequestJob; | 
|  | 23 | 
|  | 24 TestURLRequestJob* g_current_job = nullptr; | 
|  | 25 | 
|  | 26 template <class A> | 
|  | 27 void PassA(A* destination, A value) { | 
|  | 28   *destination = value.Pass(); | 
|  | 29 } | 
|  | 30 | 
|  | 31 // Extends URLLoaderImpl to allow to get a weak pointer and check if it has been | 
|  | 32 // correctly deleted. | 
|  | 33 class TestedURLLoaderImpl : public URLLoaderImpl, | 
|  | 34                             public base::SupportsWeakPtr<TestedURLLoaderImpl> { | 
|  | 35  public: | 
|  | 36   TestedURLLoaderImpl(NetworkContext* context, | 
|  | 37                       InterfaceRequest<URLLoader> request) | 
|  | 38       : URLLoaderImpl(context, request.Pass()) {} | 
|  | 39 }; | 
|  | 40 | 
|  | 41 class TestURLRequestJob : public net::URLRequestJob { | 
|  | 42  public: | 
|  | 43   enum Status { CREATED, STARTED, READING, COMPLETED }; | 
|  | 44 | 
|  | 45   TestURLRequestJob(net::URLRequest* request, | 
|  | 46                     net::NetworkDelegate* network_delegate) | 
|  | 47       : net::URLRequestJob(request, network_delegate), | 
|  | 48         status_(CREATED), | 
|  | 49         buf_size_(0) { | 
|  | 50     CHECK(!g_current_job); | 
|  | 51     g_current_job = this; | 
|  | 52   } | 
|  | 53 | 
|  | 54   Status status() { return status_; } | 
|  | 55 | 
|  | 56   int buf_size() { return buf_size_; } | 
|  | 57 | 
|  | 58   void Start() override { status_ = STARTED; } | 
|  | 59 | 
|  | 60   bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override { | 
|  | 61     status_ = READING; | 
|  | 62     buf_size_ = buf_size; | 
|  | 63     SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); | 
|  | 64     return false; | 
|  | 65   } | 
|  | 66 | 
|  | 67   void NotifyHeadersComplete() { net::URLRequestJob::NotifyHeadersComplete(); } | 
|  | 68 | 
|  | 69   void NotifyReadComplete(int bytes_read) { | 
|  | 70     if (bytes_read < 0) { | 
|  | 71       status_ = COMPLETED; | 
|  | 72       NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, 0)); | 
|  | 73       net::URLRequestJob::NotifyReadComplete(0); | 
|  | 74     } else if (bytes_read == 0) { | 
|  | 75       status_ = COMPLETED; | 
|  | 76       NotifyDone(net::URLRequestStatus()); | 
|  | 77       net::URLRequestJob::NotifyReadComplete(bytes_read); | 
|  | 78     } else { | 
|  | 79       status_ = STARTED; | 
|  | 80       SetStatus(net::URLRequestStatus()); | 
|  | 81       net::URLRequestJob::NotifyReadComplete(bytes_read); | 
|  | 82     } | 
|  | 83   } | 
|  | 84 | 
|  | 85  private: | 
|  | 86   ~TestURLRequestJob() override { | 
|  | 87     CHECK(g_current_job == this); | 
|  | 88     g_current_job = nullptr; | 
|  | 89   } | 
|  | 90 | 
|  | 91   Status status_; | 
|  | 92   int buf_size_; | 
|  | 93 }; | 
|  | 94 | 
|  | 95 class TestProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { | 
|  | 96  public: | 
|  | 97   net::URLRequestJob* MaybeCreateJob( | 
|  | 98       net::URLRequest* request, | 
|  | 99       net::NetworkDelegate* network_delegate) const override { | 
|  | 100     return new TestURLRequestJob(request, network_delegate); | 
|  | 101   } | 
|  | 102 | 
|  | 103  private: | 
|  | 104   ~TestProtocolHandler() override {} | 
|  | 105 }; | 
|  | 106 | 
|  | 107 class UrlLoaderImplTest : public test::ApplicationTestBase { | 
|  | 108  public: | 
|  | 109   UrlLoaderImplTest() : message_loop_(common::MessagePumpMojo::Create()) {} | 
|  | 110 | 
|  | 111  protected: | 
|  | 112   bool ShouldCreateDefaultRunLoop() override { | 
|  | 113     return false; | 
|  | 114   } | 
|  | 115 | 
|  | 116   void SetUp() { | 
|  | 117     ApplicationTestBase::SetUp(); | 
|  | 118 | 
|  | 119     scoped_ptr<net::TestURLRequestContext> url_request_context( | 
|  | 120         new net::TestURLRequestContext(true)); | 
|  | 121     ASSERT_TRUE(url_request_job_factory_.SetProtocolHandler( | 
|  | 122         "http", new TestProtocolHandler())); | 
|  | 123     url_request_context->set_job_factory(&url_request_job_factory_); | 
|  | 124     url_request_context->Init(); | 
|  | 125     network_context_.reset(new NetworkContext(url_request_context.Pass())); | 
|  | 126     MessagePipe pipe; | 
|  | 127     url_loader_proxy_ = MakeProxy<URLLoader>(pipe.handle0.Pass()); | 
|  | 128     url_loader_ = | 
|  | 129         (new TestedURLLoaderImpl(network_context_.get(), | 
|  | 130                                  MakeRequest<URLLoader>(pipe.handle1.Pass()))) | 
|  | 131             ->AsWeakPtr(); | 
|  | 132     EXPECT_TRUE(url_loader_); | 
|  | 133   } | 
|  | 134 | 
|  | 135   base::MessageLoop message_loop_; | 
|  | 136   net::TestJobInterceptor* job_interceptor_; | 
|  | 137   net::URLRequestJobFactoryImpl url_request_job_factory_; | 
|  | 138   scoped_ptr<NetworkContext> network_context_; | 
|  | 139   URLLoaderPtr url_loader_proxy_; | 
|  | 140   base::WeakPtr<TestedURLLoaderImpl> url_loader_; | 
|  | 141 }; | 
|  | 142 | 
|  | 143 TEST_F(UrlLoaderImplTest, ClosedBeforeAnyCall) { | 
|  | 144   url_loader_proxy_.reset(); | 
|  | 145   base::RunLoop().RunUntilIdle(); | 
|  | 146 | 
|  | 147   EXPECT_FALSE(url_loader_); | 
|  | 148 } | 
|  | 149 | 
|  | 150 TEST_F(UrlLoaderImplTest, ClosedWhileWaitingOnTheNetwork) { | 
|  | 151   URLRequestPtr request(URLRequest::New()); | 
|  | 152   request->url = "http://example.com"; | 
|  | 153 | 
|  | 154   URLResponsePtr response; | 
|  | 155   url_loader_proxy_->Start(request.Pass(), | 
|  | 156                            base::Bind(&PassA<URLResponsePtr>, &response)); | 
|  | 157   base::RunLoop().RunUntilIdle(); | 
|  | 158 | 
|  | 159   EXPECT_TRUE(url_loader_); | 
|  | 160   EXPECT_FALSE(response); | 
|  | 161   ASSERT_TRUE(g_current_job); | 
|  | 162 | 
|  | 163   g_current_job->NotifyHeadersComplete(); | 
|  | 164   base::RunLoop().RunUntilIdle(); | 
|  | 165 | 
|  | 166   EXPECT_TRUE(url_loader_); | 
|  | 167   EXPECT_TRUE(response); | 
|  | 168   EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status()); | 
|  | 169 | 
|  | 170   url_loader_proxy_.reset(); | 
|  | 171   base::RunLoop().RunUntilIdle(); | 
|  | 172 | 
|  | 173   EXPECT_TRUE(url_loader_); | 
|  | 174 | 
|  | 175   response.reset(); | 
|  | 176   base::RunLoop().RunUntilIdle(); | 
|  | 177 | 
|  | 178   EXPECT_FALSE(url_loader_); | 
|  | 179 } | 
|  | 180 | 
|  | 181 TEST_F(UrlLoaderImplTest, ClosedWhileWaitingOnThePipeToBeWriteable) { | 
|  | 182   URLRequestPtr request(URLRequest::New()); | 
|  | 183   request->url = "http://example.com"; | 
|  | 184 | 
|  | 185   URLResponsePtr response; | 
|  | 186   url_loader_proxy_->Start(request.Pass(), | 
|  | 187                            base::Bind(&PassA<URLResponsePtr>, &response)); | 
|  | 188   base::RunLoop().RunUntilIdle(); | 
|  | 189 | 
|  | 190   EXPECT_TRUE(url_loader_); | 
|  | 191   EXPECT_FALSE(response); | 
|  | 192   ASSERT_TRUE(g_current_job); | 
|  | 193 | 
|  | 194   g_current_job->NotifyHeadersComplete(); | 
|  | 195   base::RunLoop().RunUntilIdle(); | 
|  | 196 | 
|  | 197   EXPECT_TRUE(url_loader_); | 
|  | 198   EXPECT_TRUE(response); | 
|  | 199   EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status()); | 
|  | 200 | 
|  | 201   while (g_current_job->status() == TestURLRequestJob::READING) { | 
|  | 202     g_current_job->NotifyReadComplete(g_current_job->buf_size()); | 
|  | 203     base::RunLoop().RunUntilIdle(); | 
|  | 204   } | 
|  | 205 | 
|  | 206   EXPECT_EQ(TestURLRequestJob::STARTED, g_current_job->status()); | 
|  | 207 | 
|  | 208   url_loader_proxy_.reset(); | 
|  | 209   base::RunLoop().RunUntilIdle(); | 
|  | 210 | 
|  | 211   EXPECT_TRUE(url_loader_); | 
|  | 212 | 
|  | 213   response.reset(); | 
|  | 214   base::RunLoop().RunUntilIdle(); | 
|  | 215 | 
|  | 216   EXPECT_FALSE(url_loader_); | 
|  | 217 } | 
|  | 218 | 
|  | 219 TEST_F(UrlLoaderImplTest, RequestCompleted) { | 
|  | 220   URLRequestPtr request(URLRequest::New()); | 
|  | 221   request->url = "http://example.com"; | 
|  | 222 | 
|  | 223   URLResponsePtr response; | 
|  | 224   url_loader_proxy_->Start(request.Pass(), | 
|  | 225                            base::Bind(&PassA<URLResponsePtr>, &response)); | 
|  | 226   base::RunLoop().RunUntilIdle(); | 
|  | 227 | 
|  | 228   EXPECT_TRUE(url_loader_); | 
|  | 229   EXPECT_FALSE(response); | 
|  | 230   ASSERT_TRUE(g_current_job); | 
|  | 231 | 
|  | 232   g_current_job->NotifyHeadersComplete(); | 
|  | 233   base::RunLoop().RunUntilIdle(); | 
|  | 234 | 
|  | 235   EXPECT_TRUE(url_loader_); | 
|  | 236   EXPECT_TRUE(response); | 
|  | 237   EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status()); | 
|  | 238 | 
|  | 239   url_loader_proxy_.reset(); | 
|  | 240   base::RunLoop().RunUntilIdle(); | 
|  | 241 | 
|  | 242   EXPECT_TRUE(url_loader_); | 
|  | 243 | 
|  | 244   g_current_job->NotifyReadComplete(0); | 
|  | 245   base::RunLoop().RunUntilIdle(); | 
|  | 246 | 
|  | 247   EXPECT_FALSE(url_loader_); | 
|  | 248 } | 
|  | 249 | 
|  | 250 TEST_F(UrlLoaderImplTest, RequestFailed) { | 
|  | 251   URLRequestPtr request(URLRequest::New()); | 
|  | 252   request->url = "http://example.com"; | 
|  | 253 | 
|  | 254   URLResponsePtr response; | 
|  | 255   url_loader_proxy_->Start(request.Pass(), | 
|  | 256                            base::Bind(&PassA<URLResponsePtr>, &response)); | 
|  | 257   base::RunLoop().RunUntilIdle(); | 
|  | 258 | 
|  | 259   EXPECT_TRUE(url_loader_); | 
|  | 260   EXPECT_FALSE(response); | 
|  | 261   ASSERT_TRUE(g_current_job); | 
|  | 262 | 
|  | 263   g_current_job->NotifyHeadersComplete(); | 
|  | 264   base::RunLoop().RunUntilIdle(); | 
|  | 265 | 
|  | 266   EXPECT_TRUE(url_loader_); | 
|  | 267   EXPECT_TRUE(response); | 
|  | 268   EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status()); | 
|  | 269 | 
|  | 270   url_loader_proxy_.reset(); | 
|  | 271   base::RunLoop().RunUntilIdle(); | 
|  | 272 | 
|  | 273   EXPECT_TRUE(url_loader_); | 
|  | 274 | 
|  | 275   g_current_job->NotifyReadComplete(-1); | 
|  | 276   base::RunLoop().RunUntilIdle(); | 
|  | 277 | 
|  | 278   EXPECT_FALSE(url_loader_); | 
|  | 279 } | 
|  | 280 | 
|  | 281 }  // namespace mojo | 
|  | 282 }  // namespace | 
| OLD | NEW | 
|---|