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 |