| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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/basictypes.h" | |
| 6 #include "base/compiler_specific.h" | |
| 7 #include "base/memory/scoped_ptr.h" | |
| 8 #include "base/stl_util.h" | |
| 9 #include "base/strings/string_number_conversions.h" | |
| 10 #include "net/base/elements_upload_data_stream.h" | |
| 11 #include "net/base/test_completion_callback.h" | |
| 12 #include "net/base/upload_bytes_element_reader.h" | |
| 13 #include "net/base/upload_data_stream.h" | |
| 14 #include "net/cert/mock_cert_verifier.h" | |
| 15 #include "net/dns/mapped_host_resolver.h" | |
| 16 #include "net/dns/mock_host_resolver.h" | |
| 17 #include "net/http/http_auth_handler_factory.h" | |
| 18 #include "net/http/http_network_session.h" | |
| 19 #include "net/http/http_network_transaction.h" | |
| 20 #include "net/http/http_server_properties_impl.h" | |
| 21 #include "net/http/http_transaction_test_util.h" | |
| 22 #include "net/http/transport_security_state.h" | |
| 23 #include "net/proxy/proxy_service.h" | |
| 24 #include "net/quic/test_tools/quic_test_utils.h" | |
| 25 #include "net/ssl/ssl_config_service_defaults.h" | |
| 26 #include "net/tools/quic/quic_in_memory_cache.h" | |
| 27 #include "net/tools/quic/quic_server.h" | |
| 28 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h" | |
| 29 #include "net/tools/quic/test_tools/server_thread.h" | |
| 30 #include "testing/gtest/include/gtest/gtest.h" | |
| 31 #include "testing/platform_test.h" | |
| 32 | |
| 33 using base::StringPiece; | |
| 34 using net::tools::QuicInMemoryCache; | |
| 35 using net::tools::QuicServer; | |
| 36 using net::tools::test::QuicInMemoryCachePeer; | |
| 37 using net::tools::test::ServerThread; | |
| 38 | |
| 39 namespace net { | |
| 40 namespace test { | |
| 41 | |
| 42 namespace { | |
| 43 | |
| 44 const char kResponseBody[] = "some arbitrary response body"; | |
| 45 | |
| 46 // Factory for creating HttpTransactions, used by TestTransactionConsumer. | |
| 47 class TestTransactionFactory : public HttpTransactionFactory { | |
| 48 public: | |
| 49 TestTransactionFactory(const HttpNetworkSession::Params& params) | |
| 50 : session_(new HttpNetworkSession(params)) {} | |
| 51 | |
| 52 ~TestTransactionFactory() override {} | |
| 53 | |
| 54 // HttpTransactionFactory methods | |
| 55 int CreateTransaction(RequestPriority priority, | |
| 56 scoped_ptr<HttpTransaction>* trans) override { | |
| 57 trans->reset(new HttpNetworkTransaction(priority, session_.get())); | |
| 58 return OK; | |
| 59 } | |
| 60 | |
| 61 HttpCache* GetCache() override { return nullptr; } | |
| 62 | |
| 63 HttpNetworkSession* GetSession() override { return session_.get(); }; | |
| 64 | |
| 65 private: | |
| 66 scoped_refptr<HttpNetworkSession> session_; | |
| 67 }; | |
| 68 | |
| 69 } // namespace | |
| 70 | |
| 71 class QuicEndToEndTest : public PlatformTest { | |
| 72 protected: | |
| 73 QuicEndToEndTest() | |
| 74 : host_resolver_impl_(CreateResolverImpl()), | |
| 75 host_resolver_(host_resolver_impl_.Pass()), | |
| 76 ssl_config_service_(new SSLConfigServiceDefaults), | |
| 77 proxy_service_(ProxyService::CreateDirect()), | |
| 78 auth_handler_factory_( | |
| 79 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)), | |
| 80 strike_register_no_startup_period_(false) { | |
| 81 request_.method = "GET"; | |
| 82 request_.url = GURL("http://www.google.com/"); | |
| 83 request_.load_flags = 0; | |
| 84 | |
| 85 params_.enable_quic = true; | |
| 86 params_.quic_clock = nullptr; | |
| 87 params_.quic_random = nullptr; | |
| 88 params_.host_resolver = &host_resolver_; | |
| 89 params_.cert_verifier = &cert_verifier_; | |
| 90 params_.transport_security_state = &transport_security_state_; | |
| 91 params_.proxy_service = proxy_service_.get(); | |
| 92 params_.ssl_config_service = ssl_config_service_.get(); | |
| 93 params_.http_auth_handler_factory = auth_handler_factory_.get(); | |
| 94 params_.http_server_properties = http_server_properties.GetWeakPtr(); | |
| 95 } | |
| 96 | |
| 97 // Creates a mock host resolver in which www.google.com | |
| 98 // resolves to localhost. | |
| 99 static MockHostResolver* CreateResolverImpl() { | |
| 100 MockHostResolver* resolver = new MockHostResolver(); | |
| 101 resolver->rules()->AddRule("www.google.com", "127.0.0.1"); | |
| 102 return resolver; | |
| 103 } | |
| 104 | |
| 105 void SetUp() override { | |
| 106 QuicInMemoryCachePeer::ResetForTests(); | |
| 107 StartServer(); | |
| 108 | |
| 109 // Use a mapped host resolver so that request for www.google.com (port 80) | |
| 110 // reach the server running on localhost. | |
| 111 std::string map_rule = "MAP www.google.com www.google.com:" + | |
| 112 base::IntToString(server_thread_->GetPort()); | |
| 113 EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule)); | |
| 114 | |
| 115 // To simplify the test, and avoid the race with the HTTP request, we force | |
| 116 // QUIC for these requests. | |
| 117 params_.origin_to_force_quic_on = | |
| 118 HostPortPair::FromString("www.google.com:80"); | |
| 119 | |
| 120 transaction_factory_.reset(new TestTransactionFactory(params_)); | |
| 121 } | |
| 122 | |
| 123 void TearDown() override { | |
| 124 StopServer(); | |
| 125 QuicInMemoryCachePeer::ResetForTests(); | |
| 126 } | |
| 127 | |
| 128 // Starts the QUIC server listening on a random port. | |
| 129 void StartServer() { | |
| 130 net::IPAddressNumber ip; | |
| 131 CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip)); | |
| 132 server_address_ = IPEndPoint(ip, 0); | |
| 133 server_config_.SetInitialStreamFlowControlWindowToSend( | |
| 134 kInitialStreamFlowControlWindowForTest); | |
| 135 server_config_.SetInitialSessionFlowControlWindowToSend( | |
| 136 kInitialSessionFlowControlWindowForTest); | |
| 137 server_thread_.reset(new ServerThread( | |
| 138 new QuicServer(server_config_, QuicSupportedVersions()), | |
| 139 server_address_, | |
| 140 strike_register_no_startup_period_)); | |
| 141 server_thread_->Initialize(); | |
| 142 server_address_ = IPEndPoint(server_address_.address(), | |
| 143 server_thread_->GetPort()); | |
| 144 server_thread_->Start(); | |
| 145 server_started_ = true; | |
| 146 } | |
| 147 | |
| 148 // Stops the QUIC server. | |
| 149 void StopServer() { | |
| 150 if (!server_started_) { | |
| 151 return; | |
| 152 } | |
| 153 if (server_thread_.get()) { | |
| 154 server_thread_->Quit(); | |
| 155 server_thread_->Join(); | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 // Adds an entry to the cache used by the QUIC server to serve | |
| 160 // responses. | |
| 161 void AddToCache(const StringPiece& method, | |
| 162 const StringPiece& path, | |
| 163 const StringPiece& version, | |
| 164 const StringPiece& response_code, | |
| 165 const StringPiece& response_detail, | |
| 166 const StringPiece& body) { | |
| 167 QuicInMemoryCache::GetInstance()->AddSimpleResponse( | |
| 168 method, path, version, response_code, response_detail, body); | |
| 169 } | |
| 170 | |
| 171 // Populates |request_body_| with |length_| ASCII bytes. | |
| 172 void GenerateBody(size_t length) { | |
| 173 request_body_.clear(); | |
| 174 request_body_.reserve(length); | |
| 175 for (size_t i = 0; i < length; ++i) { | |
| 176 request_body_.append(1, static_cast<char>(32 + i % (126 - 32))); | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 // Initializes |request_| for a post of |length| bytes. | |
| 181 void InitializePostRequest(size_t length) { | |
| 182 GenerateBody(length); | |
| 183 ScopedVector<UploadElementReader> element_readers; | |
| 184 element_readers.push_back( | |
| 185 new UploadBytesElementReader(request_body_.data(), | |
| 186 request_body_.length())); | |
| 187 upload_data_stream_.reset( | |
| 188 new ElementsUploadDataStream(element_readers.Pass(), 0)); | |
| 189 request_.method = "POST"; | |
| 190 request_.url = GURL("http://www.google.com/"); | |
| 191 request_.upload_data_stream = upload_data_stream_.get(); | |
| 192 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); | |
| 193 } | |
| 194 | |
| 195 // Checks that |consumer| completed and received |status_line| and |body|. | |
| 196 void CheckResponse(const TestTransactionConsumer& consumer, | |
| 197 const std::string& status_line, | |
| 198 const std::string& body) { | |
| 199 ASSERT_TRUE(consumer.is_done()); | |
| 200 EXPECT_EQ(OK, consumer.error()); | |
| 201 EXPECT_EQ(status_line, | |
| 202 consumer.response_info()->headers->GetStatusLine()); | |
| 203 EXPECT_EQ(body, consumer.content()); | |
| 204 } | |
| 205 | |
| 206 scoped_ptr<MockHostResolver> host_resolver_impl_; | |
| 207 MappedHostResolver host_resolver_; | |
| 208 MockCertVerifier cert_verifier_; | |
| 209 TransportSecurityState transport_security_state_; | |
| 210 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_; | |
| 211 scoped_ptr<ProxyService> proxy_service_; | |
| 212 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_; | |
| 213 HttpServerPropertiesImpl http_server_properties; | |
| 214 HttpNetworkSession::Params params_; | |
| 215 scoped_ptr<TestTransactionFactory> transaction_factory_; | |
| 216 HttpRequestInfo request_; | |
| 217 std::string request_body_; | |
| 218 scoped_ptr<UploadDataStream> upload_data_stream_; | |
| 219 scoped_ptr<ServerThread> server_thread_; | |
| 220 IPEndPoint server_address_; | |
| 221 std::string server_hostname_; | |
| 222 QuicConfig server_config_; | |
| 223 bool server_started_; | |
| 224 bool strike_register_no_startup_period_; | |
| 225 }; | |
| 226 | |
| 227 TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) { | |
| 228 std::string response(10 * 1024, 'x'); | |
| 229 | |
| 230 AddToCache("GET", request_.url.spec(), | |
| 231 "HTTP/1.1", "200", "OK", | |
| 232 response); | |
| 233 | |
| 234 TestTransactionConsumer consumer(DEFAULT_PRIORITY, | |
| 235 transaction_factory_.get()); | |
| 236 consumer.Start(&request_, BoundNetLog()); | |
| 237 | |
| 238 // Will terminate when the last consumer completes. | |
| 239 base::MessageLoop::current()->Run(); | |
| 240 | |
| 241 CheckResponse(consumer, "HTTP/1.1 200 OK", response); | |
| 242 } | |
| 243 | |
| 244 // http://crbug.com/307284 | |
| 245 TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) { | |
| 246 InitializePostRequest(10 * 1024 * 1024); | |
| 247 | |
| 248 AddToCache("POST", request_.url.spec(), | |
| 249 "HTTP/1.1", "200", "OK", | |
| 250 kResponseBody); | |
| 251 | |
| 252 TestTransactionConsumer consumer(DEFAULT_PRIORITY, | |
| 253 transaction_factory_.get()); | |
| 254 consumer.Start(&request_, BoundNetLog()); | |
| 255 | |
| 256 // Will terminate when the last consumer completes. | |
| 257 base::MessageLoop::current()->Run(); | |
| 258 | |
| 259 CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody); | |
| 260 } | |
| 261 | |
| 262 TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) { | |
| 263 // FLAGS_fake_packet_loss_percentage = 30; | |
| 264 InitializePostRequest(1024 * 1024); | |
| 265 | |
| 266 const char kResponseBody[] = "some really big response body"; | |
| 267 AddToCache("POST", request_.url.spec(), | |
| 268 "HTTP/1.1", "200", "OK", | |
| 269 kResponseBody); | |
| 270 | |
| 271 TestTransactionConsumer consumer(DEFAULT_PRIORITY, | |
| 272 transaction_factory_.get()); | |
| 273 consumer.Start(&request_, BoundNetLog()); | |
| 274 | |
| 275 // Will terminate when the last consumer completes. | |
| 276 base::MessageLoop::current()->Run(); | |
| 277 | |
| 278 CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody); | |
| 279 } | |
| 280 | |
| 281 TEST_F(QuicEndToEndTest, UberTest) { | |
| 282 // FLAGS_fake_packet_loss_percentage = 30; | |
| 283 | |
| 284 const char kResponseBody[] = "some really big response body"; | |
| 285 AddToCache("GET", request_.url.spec(), | |
| 286 "HTTP/1.1", "200", "OK", | |
| 287 kResponseBody); | |
| 288 | |
| 289 std::vector<TestTransactionConsumer*> consumers; | |
| 290 size_t num_requests = 100; | |
| 291 for (size_t i = 0; i < num_requests; ++i) { | |
| 292 TestTransactionConsumer* consumer = | |
| 293 new TestTransactionConsumer(DEFAULT_PRIORITY, | |
| 294 transaction_factory_.get()); | |
| 295 consumers.push_back(consumer); | |
| 296 consumer->Start(&request_, BoundNetLog()); | |
| 297 } | |
| 298 | |
| 299 // Will terminate when the last consumer completes. | |
| 300 base::MessageLoop::current()->Run(); | |
| 301 | |
| 302 for (size_t i = 0; i < num_requests; ++i) { | |
| 303 CheckResponse(*consumers[i], "HTTP/1.1 200 OK", kResponseBody); | |
| 304 } | |
| 305 STLDeleteElements(&consumers); | |
| 306 } | |
| 307 | |
| 308 } // namespace test | |
| 309 } // namespace net | |
| OLD | NEW |