OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include <stddef.h> | |
6 #include <string> | |
7 #include <sys/epoll.h> | |
8 #include <vector> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/memory/singleton.h" | |
13 #include "base/strings/string_number_conversions.h" | |
14 #include "base/synchronization/waitable_event.h" | |
15 #include "base/time/time.h" | |
16 #include "net/base/ip_endpoint.h" | |
17 #include "net/quic/congestion_control/tcp_cubic_sender.h" | |
18 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" | |
19 #include "net/quic/crypto/null_encrypter.h" | |
20 #include "net/quic/quic_flags.h" | |
21 #include "net/quic/quic_framer.h" | |
22 #include "net/quic/quic_packet_creator.h" | |
23 #include "net/quic/quic_protocol.h" | |
24 #include "net/quic/quic_server_id.h" | |
25 #include "net/quic/quic_utils.h" | |
26 #include "net/quic/test_tools/quic_connection_peer.h" | |
27 #include "net/quic/test_tools/quic_flow_controller_peer.h" | |
28 #include "net/quic/test_tools/quic_sent_packet_manager_peer.h" | |
29 #include "net/quic/test_tools/quic_session_peer.h" | |
30 #include "net/quic/test_tools/quic_test_utils.h" | |
31 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | |
32 #include "net/test/gtest_util.h" | |
33 #include "net/tools/epoll_server/epoll_server.h" | |
34 #include "net/tools/quic/quic_epoll_connection_helper.h" | |
35 #include "net/tools/quic/quic_in_memory_cache.h" | |
36 #include "net/tools/quic/quic_packet_writer_wrapper.h" | |
37 #include "net/tools/quic/quic_server.h" | |
38 #include "net/tools/quic/quic_socket_utils.h" | |
39 #include "net/tools/quic/quic_spdy_client_stream.h" | |
40 #include "net/tools/quic/test_tools/http_message.h" | |
41 #include "net/tools/quic/test_tools/packet_dropping_test_writer.h" | |
42 #include "net/tools/quic/test_tools/quic_client_peer.h" | |
43 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" | |
44 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h" | |
45 #include "net/tools/quic/test_tools/quic_server_peer.h" | |
46 #include "net/tools/quic/test_tools/quic_test_client.h" | |
47 #include "net/tools/quic/test_tools/server_thread.h" | |
48 #include "testing/gtest/include/gtest/gtest.h" | |
49 | |
50 using base::StringPiece; | |
51 using base::WaitableEvent; | |
52 using net::EpollServer; | |
53 using net::test::GenerateBody; | |
54 using net::test::QuicConnectionPeer; | |
55 using net::test::QuicFlowControllerPeer; | |
56 using net::test::QuicSentPacketManagerPeer; | |
57 using net::test::QuicSessionPeer; | |
58 using net::test::ReliableQuicStreamPeer; | |
59 using net::test::ValueRestore; | |
60 using net::test::kClientDataStreamId1; | |
61 using net::tools::test::PacketDroppingTestWriter; | |
62 using net::tools::test::QuicDispatcherPeer; | |
63 using net::tools::test::QuicServerPeer; | |
64 using std::ostream; | |
65 using std::string; | |
66 using std::vector; | |
67 | |
68 namespace net { | |
69 namespace tools { | |
70 namespace test { | |
71 namespace { | |
72 | |
73 const char kFooResponseBody[] = "Artichoke hearts make me happy."; | |
74 const char kBarResponseBody[] = "Palm hearts are pretty delicious, also."; | |
75 | |
76 // Run all tests with the cross products of all versions. | |
77 struct TestParams { | |
78 TestParams(const QuicVersionVector& client_supported_versions, | |
79 const QuicVersionVector& server_supported_versions, | |
80 QuicVersion negotiated_version, | |
81 bool use_pacing, | |
82 bool use_fec, | |
83 QuicTag congestion_control_tag) | |
84 : client_supported_versions(client_supported_versions), | |
85 server_supported_versions(server_supported_versions), | |
86 negotiated_version(negotiated_version), | |
87 use_pacing(use_pacing), | |
88 use_fec(use_fec), | |
89 congestion_control_tag(congestion_control_tag) { | |
90 } | |
91 | |
92 friend ostream& operator<<(ostream& os, const TestParams& p) { | |
93 os << "{ server_supported_versions: " | |
94 << QuicVersionVectorToString(p.server_supported_versions); | |
95 os << " client_supported_versions: " | |
96 << QuicVersionVectorToString(p.client_supported_versions); | |
97 os << " negotiated_version: " << QuicVersionToString(p.negotiated_version); | |
98 os << " use_pacing: " << p.use_pacing; | |
99 os << " use_fec: " << p.use_fec; | |
100 os << " congestion_control_tag: " | |
101 << QuicUtils::TagToString(p.congestion_control_tag) << " }"; | |
102 return os; | |
103 } | |
104 | |
105 QuicVersionVector client_supported_versions; | |
106 QuicVersionVector server_supported_versions; | |
107 QuicVersion negotiated_version; | |
108 bool use_pacing; | |
109 bool use_fec; | |
110 QuicTag congestion_control_tag; | |
111 }; | |
112 | |
113 // Constructs various test permutations. | |
114 vector<TestParams> GetTestParams() { | |
115 vector<TestParams> params; | |
116 QuicVersionVector all_supported_versions = QuicSupportedVersions(); | |
117 // TODO(rtenneti): Add kTBBR after BBR code is checked in. | |
118 // QuicTag congestion_control_tags[] = {kRENO, kTBBR, kQBIC}; | |
119 QuicTag congestion_control_tags[] = {kRENO, kQBIC}; | |
120 QuicVersionVector spdy3_versions; | |
121 QuicVersionVector spdy4_versions; | |
122 for (QuicVersion version : all_supported_versions) { | |
123 if (version > QUIC_VERSION_23) { | |
124 spdy4_versions.push_back(version); | |
125 } else { | |
126 spdy3_versions.push_back(version); | |
127 } | |
128 } | |
129 for (size_t congestion_control_index = 0; | |
130 congestion_control_index < arraysize(congestion_control_tags); | |
131 congestion_control_index++) { | |
132 QuicTag congestion_control_tag = | |
133 congestion_control_tags[congestion_control_index]; | |
134 for (int use_fec = 0; use_fec < 2; ++use_fec) { | |
135 for (int use_pacing = 0; use_pacing < 2; ++use_pacing) { | |
136 for (int spdy_version = 3; spdy_version <= 4; ++spdy_version) { | |
137 const QuicVersionVector* client_versions = | |
138 spdy_version == 3 ? &spdy3_versions : &spdy4_versions; | |
139 // Add an entry for server and client supporting all versions. | |
140 params.push_back(TestParams(*client_versions, all_supported_versions, | |
141 (*client_versions)[0], use_pacing != 0, | |
142 use_fec != 0, congestion_control_tag)); | |
143 | |
144 // Test client supporting all versions and server supporting 1 | |
145 // version. Simulate an old server and exercise version downgrade in | |
146 // the client. Protocol negotiation should occur. Skip the i = 0 case | |
147 // because it is essentially the same as the default case. | |
148 for (QuicVersion version : *client_versions) { | |
149 QuicVersionVector server_supported_versions; | |
150 server_supported_versions.push_back(version); | |
151 params.push_back( | |
152 TestParams(*client_versions, server_supported_versions, | |
153 server_supported_versions[0], use_pacing != 0, | |
154 use_fec != 0, congestion_control_tag)); | |
155 } | |
156 } | |
157 } | |
158 } | |
159 } | |
160 return params; | |
161 } | |
162 | |
163 class ServerDelegate : public PacketDroppingTestWriter::Delegate { | |
164 public: | |
165 ServerDelegate(TestWriterFactory* writer_factory, | |
166 QuicDispatcher* dispatcher) | |
167 : writer_factory_(writer_factory), | |
168 dispatcher_(dispatcher) {} | |
169 ~ServerDelegate() override {} | |
170 void OnPacketSent(WriteResult result) override { | |
171 writer_factory_->OnPacketSent(result); | |
172 } | |
173 void OnCanWrite() override { dispatcher_->OnCanWrite(); } | |
174 | |
175 private: | |
176 TestWriterFactory* writer_factory_; | |
177 QuicDispatcher* dispatcher_; | |
178 }; | |
179 | |
180 class ClientDelegate : public PacketDroppingTestWriter::Delegate { | |
181 public: | |
182 explicit ClientDelegate(QuicClient* client) : client_(client) {} | |
183 ~ClientDelegate() override {} | |
184 void OnPacketSent(WriteResult result) override {} | |
185 void OnCanWrite() override { | |
186 EpollEvent event(EPOLLOUT, false); | |
187 client_->OnEvent(client_->fd(), &event); | |
188 } | |
189 | |
190 private: | |
191 QuicClient* client_; | |
192 }; | |
193 | |
194 class EndToEndTest : public ::testing::TestWithParam<TestParams> { | |
195 protected: | |
196 EndToEndTest() | |
197 : server_hostname_("example.com"), | |
198 server_started_(false), | |
199 strike_register_no_startup_period_(false) { | |
200 net::IPAddressNumber ip; | |
201 CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip)); | |
202 server_address_ = IPEndPoint(ip, 0); | |
203 | |
204 client_supported_versions_ = GetParam().client_supported_versions; | |
205 server_supported_versions_ = GetParam().server_supported_versions; | |
206 negotiated_version_ = GetParam().negotiated_version; | |
207 FLAGS_enable_quic_fec = GetParam().use_fec; | |
208 | |
209 VLOG(1) << "Using Configuration: " << GetParam(); | |
210 | |
211 // Use different flow control windows for client/server. | |
212 client_config_.SetInitialStreamFlowControlWindowToSend( | |
213 2 * kInitialStreamFlowControlWindowForTest); | |
214 client_config_.SetInitialSessionFlowControlWindowToSend( | |
215 2 * kInitialSessionFlowControlWindowForTest); | |
216 server_config_.SetInitialStreamFlowControlWindowToSend( | |
217 3 * kInitialStreamFlowControlWindowForTest); | |
218 server_config_.SetInitialSessionFlowControlWindowToSend( | |
219 3 * kInitialSessionFlowControlWindowForTest); | |
220 | |
221 QuicInMemoryCachePeer::ResetForTests(); | |
222 AddToCache("GET", "https://www.google.com/foo", | |
223 "HTTP/1.1", "200", "OK", kFooResponseBody); | |
224 AddToCache("GET", "https://www.google.com/bar", | |
225 "HTTP/1.1", "200", "OK", kBarResponseBody); | |
226 } | |
227 | |
228 ~EndToEndTest() override { | |
229 // TODO(rtenneti): port RecycleUnusedPort if needed. | |
230 // RecycleUnusedPort(server_address_.port()); | |
231 QuicInMemoryCachePeer::ResetForTests(); | |
232 } | |
233 | |
234 QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) { | |
235 QuicTestClient* client = new QuicTestClient( | |
236 server_address_, | |
237 server_hostname_, | |
238 false, // not secure | |
239 client_config_, | |
240 client_supported_versions_); | |
241 client->UseWriter(writer); | |
242 client->Connect(); | |
243 return client; | |
244 } | |
245 | |
246 void set_client_initial_stream_flow_control_receive_window(uint32 window) { | |
247 CHECK(client_.get() == nullptr); | |
248 DVLOG(1) << "Setting client initial stream flow control window: " << window; | |
249 client_config_.SetInitialStreamFlowControlWindowToSend(window); | |
250 } | |
251 | |
252 void set_client_initial_session_flow_control_receive_window(uint32 window) { | |
253 CHECK(client_.get() == nullptr); | |
254 DVLOG(1) << "Setting client initial session flow control window: " | |
255 << window; | |
256 client_config_.SetInitialSessionFlowControlWindowToSend(window); | |
257 } | |
258 | |
259 void set_server_initial_stream_flow_control_receive_window(uint32 window) { | |
260 CHECK(server_thread_.get() == nullptr); | |
261 DVLOG(1) << "Setting server initial stream flow control window: " | |
262 << window; | |
263 server_config_.SetInitialStreamFlowControlWindowToSend(window); | |
264 } | |
265 | |
266 void set_server_initial_session_flow_control_receive_window(uint32 window) { | |
267 CHECK(server_thread_.get() == nullptr); | |
268 DVLOG(1) << "Setting server initial session flow control window: " | |
269 << window; | |
270 server_config_.SetInitialSessionFlowControlWindowToSend(window); | |
271 } | |
272 | |
273 const QuicSentPacketManager * | |
274 GetSentPacketManagerFromFirstServerSession() const { | |
275 QuicDispatcher* dispatcher = | |
276 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
277 QuicSession* session = dispatcher->session_map().begin()->second; | |
278 return &session->connection()->sent_packet_manager(); | |
279 } | |
280 | |
281 bool Initialize() { | |
282 QuicTagVector copt; | |
283 | |
284 if (GetParam().use_pacing) { | |
285 copt.push_back(kPACE); | |
286 } | |
287 server_config_.SetConnectionOptionsToSend(copt); | |
288 | |
289 // TODO(nimia): Consider setting the congestion control algorithm for the | |
290 // client as well according to the test parameter. | |
291 copt.push_back(GetParam().congestion_control_tag); | |
292 | |
293 if (GetParam().use_fec) { | |
294 // Set FEC config in client's connection options and in client session. | |
295 copt.push_back(kFHDR); | |
296 } | |
297 | |
298 client_config_.SetConnectionOptionsToSend(copt); | |
299 | |
300 // Start the server first, because CreateQuicClient() attempts | |
301 // to connect to the server. | |
302 StartServer(); | |
303 client_.reset(CreateQuicClient(client_writer_)); | |
304 if (GetParam().use_fec) { | |
305 // Set FecPolicy to always protect data on all streams. | |
306 client_->SetFecPolicy(FEC_PROTECT_ALWAYS); | |
307 } | |
308 static EpollEvent event(EPOLLOUT, false); | |
309 client_writer_->Initialize( | |
310 reinterpret_cast<QuicEpollConnectionHelper*>( | |
311 QuicConnectionPeer::GetHelper( | |
312 client_->client()->session()->connection())), | |
313 new ClientDelegate(client_->client())); | |
314 return client_->client()->connected(); | |
315 } | |
316 | |
317 void SetUp() override { | |
318 // The ownership of these gets transferred to the QuicPacketWriterWrapper | |
319 // and TestWriterFactory when Initialize() is executed. | |
320 client_writer_ = new PacketDroppingTestWriter(); | |
321 server_writer_ = new PacketDroppingTestWriter(); | |
322 // TODO(ianswett): Remove this once it's fully rolled out. | |
323 FLAGS_quic_enable_pacing = false; | |
324 } | |
325 | |
326 void TearDown() override { StopServer(); } | |
327 | |
328 void StartServer() { | |
329 server_thread_.reset( | |
330 new ServerThread( | |
331 new QuicServer(server_config_, server_supported_versions_), | |
332 server_address_, | |
333 strike_register_no_startup_period_)); | |
334 server_thread_->Initialize(); | |
335 server_address_ = IPEndPoint(server_address_.address(), | |
336 server_thread_->GetPort()); | |
337 QuicDispatcher* dispatcher = | |
338 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
339 TestWriterFactory* packet_writer_factory = new TestWriterFactory(); | |
340 QuicDispatcherPeer::SetPacketWriterFactory(dispatcher, | |
341 packet_writer_factory); | |
342 QuicDispatcherPeer::UseWriter(dispatcher, server_writer_); | |
343 server_writer_->Initialize( | |
344 QuicDispatcherPeer::GetHelper(dispatcher), | |
345 new ServerDelegate(packet_writer_factory, dispatcher)); | |
346 server_thread_->Start(); | |
347 server_started_ = true; | |
348 } | |
349 | |
350 void StopServer() { | |
351 if (!server_started_) | |
352 return; | |
353 if (server_thread_.get()) { | |
354 server_thread_->Quit(); | |
355 server_thread_->Join(); | |
356 } | |
357 } | |
358 | |
359 void AddToCache(StringPiece method, | |
360 StringPiece path, | |
361 StringPiece version, | |
362 StringPiece response_code, | |
363 StringPiece response_detail, | |
364 StringPiece body) { | |
365 QuicInMemoryCache::GetInstance()->AddSimpleResponse( | |
366 method, path, version, response_code, response_detail, body); | |
367 } | |
368 | |
369 void SetPacketLossPercentage(int32 loss) { | |
370 // TODO(rtenneti): enable when we can do random packet loss tests in | |
371 // chrome's tree. | |
372 if (loss != 0 && loss != 100) | |
373 return; | |
374 client_writer_->set_fake_packet_loss_percentage(loss); | |
375 server_writer_->set_fake_packet_loss_percentage(loss); | |
376 } | |
377 | |
378 void SetPacketSendDelay(QuicTime::Delta delay) { | |
379 // TODO(rtenneti): enable when we can do random packet send delay tests in | |
380 // chrome's tree. | |
381 // client_writer_->set_fake_packet_delay(delay); | |
382 // server_writer_->set_fake_packet_delay(delay); | |
383 } | |
384 | |
385 void SetReorderPercentage(int32 reorder) { | |
386 // TODO(rtenneti): enable when we can do random packet reorder tests in | |
387 // chrome's tree. | |
388 // client_writer_->set_fake_reorder_percentage(reorder); | |
389 // server_writer_->set_fake_reorder_percentage(reorder); | |
390 } | |
391 | |
392 // Verifies that the client and server connections were both free of packets | |
393 // being discarded, based on connection stats. | |
394 // Calls server_thread_ Pause() and Resume(), which may only be called once | |
395 // per test. | |
396 void VerifyCleanConnection(bool had_packet_loss) { | |
397 QuicConnectionStats client_stats = | |
398 client_->client()->session()->connection()->GetStats(); | |
399 if (!had_packet_loss) { | |
400 EXPECT_EQ(0u, client_stats.packets_lost); | |
401 } | |
402 EXPECT_EQ(0u, client_stats.packets_discarded); | |
403 EXPECT_EQ(0u, client_stats.packets_dropped); | |
404 EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed); | |
405 | |
406 server_thread_->Pause(); | |
407 QuicDispatcher* dispatcher = | |
408 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
409 ASSERT_EQ(1u, dispatcher->session_map().size()); | |
410 QuicSession* session = dispatcher->session_map().begin()->second; | |
411 QuicConnectionStats server_stats = session->connection()->GetStats(); | |
412 if (!had_packet_loss) { | |
413 EXPECT_EQ(0u, server_stats.packets_lost); | |
414 } | |
415 EXPECT_EQ(0u, server_stats.packets_discarded); | |
416 // TODO(ianswett): Restore the check for packets_dropped equals 0. | |
417 // The expect for packets received is equal to packets processed fails | |
418 // due to version negotiation packets. | |
419 server_thread_->Resume(); | |
420 } | |
421 | |
422 IPEndPoint server_address_; | |
423 string server_hostname_; | |
424 scoped_ptr<ServerThread> server_thread_; | |
425 scoped_ptr<QuicTestClient> client_; | |
426 PacketDroppingTestWriter* client_writer_; | |
427 PacketDroppingTestWriter* server_writer_; | |
428 bool server_started_; | |
429 QuicConfig client_config_; | |
430 QuicConfig server_config_; | |
431 QuicVersionVector client_supported_versions_; | |
432 QuicVersionVector server_supported_versions_; | |
433 QuicVersion negotiated_version_; | |
434 bool strike_register_no_startup_period_; | |
435 }; | |
436 | |
437 // Run all end to end tests with all supported versions. | |
438 INSTANTIATE_TEST_CASE_P(EndToEndTests, | |
439 EndToEndTest, | |
440 ::testing::ValuesIn(GetTestParams())); | |
441 | |
442 TEST_P(EndToEndTest, SimpleRequestResponse) { | |
443 ASSERT_TRUE(Initialize()); | |
444 | |
445 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
446 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
447 } | |
448 | |
449 // TODO(rch): figure out how to detect missing v6 supprt (like on the linux | |
450 // try bots) and selectively disable this test. | |
451 TEST_P(EndToEndTest, DISABLED_SimpleRequestResponsev6) { | |
452 IPAddressNumber ip; | |
453 CHECK(net::ParseIPLiteralToNumber("::1", &ip)); | |
454 server_address_ = IPEndPoint(ip, server_address_.port()); | |
455 ASSERT_TRUE(Initialize()); | |
456 | |
457 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
458 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
459 } | |
460 | |
461 TEST_P(EndToEndTest, SeparateFinPacket) { | |
462 ASSERT_TRUE(Initialize()); | |
463 | |
464 HTTPMessage request(HttpConstants::HTTP_1_1, | |
465 HttpConstants::POST, "/foo"); | |
466 request.set_has_complete_message(false); | |
467 | |
468 // Send a request in two parts: the request and then an empty packet with FIN. | |
469 client_->SendMessage(request); | |
470 client_->SendData("", true); | |
471 client_->WaitForResponse(); | |
472 EXPECT_EQ(kFooResponseBody, client_->response_body()); | |
473 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
474 | |
475 // Now do the same thing but with a content length. | |
476 request.AddBody("foo", true); | |
477 client_->SendMessage(request); | |
478 client_->SendData("", true); | |
479 client_->WaitForResponse(); | |
480 EXPECT_EQ(kFooResponseBody, client_->response_body()); | |
481 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
482 } | |
483 | |
484 TEST_P(EndToEndTest, MultipleRequestResponse) { | |
485 ASSERT_TRUE(Initialize()); | |
486 | |
487 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
488 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
489 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar")); | |
490 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
491 } | |
492 | |
493 TEST_P(EndToEndTest, MultipleClients) { | |
494 ASSERT_TRUE(Initialize()); | |
495 scoped_ptr<QuicTestClient> client2(CreateQuicClient(nullptr)); | |
496 | |
497 HTTPMessage request(HttpConstants::HTTP_1_1, | |
498 HttpConstants::POST, "/foo"); | |
499 request.AddHeader("content-length", "3"); | |
500 request.set_has_complete_message(false); | |
501 | |
502 client_->SendMessage(request); | |
503 client2->SendMessage(request); | |
504 | |
505 client_->SendData("bar", true); | |
506 client_->WaitForResponse(); | |
507 EXPECT_EQ(kFooResponseBody, client_->response_body()); | |
508 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
509 | |
510 client2->SendData("eep", true); | |
511 client2->WaitForResponse(); | |
512 EXPECT_EQ(kFooResponseBody, client2->response_body()); | |
513 EXPECT_EQ(200u, client2->response_headers()->parsed_response_code()); | |
514 } | |
515 | |
516 TEST_P(EndToEndTest, RequestOverMultiplePackets) { | |
517 // Send a large enough request to guarantee fragmentation. | |
518 string huge_request = | |
519 "https://www.google.com/some/path?query=" + string(kMaxPacketSize, '.'); | |
520 AddToCache("GET", huge_request, "HTTP/1.1", "200", "OK", kBarResponseBody); | |
521 | |
522 ASSERT_TRUE(Initialize()); | |
523 | |
524 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request)); | |
525 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
526 } | |
527 | |
528 TEST_P(EndToEndTest, MultiplePacketsRandomOrder) { | |
529 // Send a large enough request to guarantee fragmentation. | |
530 string huge_request = | |
531 "https://www.google.com/some/path?query=" + string(kMaxPacketSize, '.'); | |
532 AddToCache("GET", huge_request, "HTTP/1.1", "200", "OK", kBarResponseBody); | |
533 | |
534 ASSERT_TRUE(Initialize()); | |
535 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2)); | |
536 SetReorderPercentage(50); | |
537 | |
538 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request)); | |
539 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
540 } | |
541 | |
542 TEST_P(EndToEndTest, PostMissingBytes) { | |
543 ASSERT_TRUE(Initialize()); | |
544 | |
545 // Add a content length header with no body. | |
546 HTTPMessage request(HttpConstants::HTTP_1_1, | |
547 HttpConstants::POST, "/foo"); | |
548 request.AddHeader("content-length", "3"); | |
549 request.set_skip_message_validation(true); | |
550 | |
551 // This should be detected as stream fin without complete request, | |
552 // triggering an error response. | |
553 client_->SendCustomSynchronousRequest(request); | |
554 EXPECT_EQ("bad", client_->response_body()); | |
555 EXPECT_EQ(500u, client_->response_headers()->parsed_response_code()); | |
556 } | |
557 | |
558 // TODO(rtenneti): DISABLED_LargePostNoPacketLoss seems to be flaky. | |
559 // http://crbug.com/297040. | |
560 TEST_P(EndToEndTest, DISABLED_LargePostNoPacketLoss) { | |
561 ASSERT_TRUE(Initialize()); | |
562 | |
563 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
564 | |
565 // 1 MB body. | |
566 string body; | |
567 GenerateBody(&body, 1024 * 1024); | |
568 | |
569 HTTPMessage request(HttpConstants::HTTP_1_1, | |
570 HttpConstants::POST, "/foo"); | |
571 request.AddBody(body, true); | |
572 | |
573 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
574 VerifyCleanConnection(false); | |
575 } | |
576 | |
577 TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) { | |
578 ASSERT_TRUE(Initialize()); | |
579 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000)); | |
580 | |
581 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
582 | |
583 // 100 KB body. | |
584 string body; | |
585 GenerateBody(&body, 100 * 1024); | |
586 | |
587 HTTPMessage request(HttpConstants::HTTP_1_1, | |
588 HttpConstants::POST, "/foo"); | |
589 request.AddBody(body, true); | |
590 | |
591 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
592 VerifyCleanConnection(false); | |
593 } | |
594 | |
595 TEST_P(EndToEndTest, LargePostWithPacketLoss) { | |
596 // Connect with lower fake packet loss than we'd like to test. Until | |
597 // b/10126687 is fixed, losing handshake packets is pretty brutal. | |
598 SetPacketLossPercentage(5); | |
599 ASSERT_TRUE(Initialize()); | |
600 | |
601 // Wait for the server SHLO before upping the packet loss. | |
602 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
603 SetPacketLossPercentage(30); | |
604 | |
605 // 10 KB body. | |
606 string body; | |
607 GenerateBody(&body, 1024 * 10); | |
608 | |
609 HTTPMessage request(HttpConstants::HTTP_1_1, | |
610 HttpConstants::POST, "/foo"); | |
611 request.AddBody(body, true); | |
612 | |
613 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
614 VerifyCleanConnection(true); | |
615 } | |
616 | |
617 TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) { | |
618 // Connect with lower fake packet loss than we'd like to test. Until | |
619 // b/10126687 is fixed, losing handshake packets is pretty brutal. | |
620 SetPacketLossPercentage(5); | |
621 ASSERT_TRUE(Initialize()); | |
622 | |
623 // Wait for the server SHLO before upping the packet loss. | |
624 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
625 SetPacketLossPercentage(10); | |
626 client_writer_->set_fake_blocked_socket_percentage(10); | |
627 | |
628 // 10 KB body. | |
629 string body; | |
630 GenerateBody(&body, 1024 * 10); | |
631 | |
632 HTTPMessage request(HttpConstants::HTTP_1_1, | |
633 HttpConstants::POST, "/foo"); | |
634 request.AddBody(body, true); | |
635 | |
636 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
637 } | |
638 | |
639 TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) { | |
640 ASSERT_TRUE(Initialize()); | |
641 | |
642 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
643 // Both of these must be called when the writer is not actively used. | |
644 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2)); | |
645 SetReorderPercentage(30); | |
646 | |
647 // 1 MB body. | |
648 string body; | |
649 GenerateBody(&body, 1024 * 1024); | |
650 | |
651 HTTPMessage request(HttpConstants::HTTP_1_1, | |
652 HttpConstants::POST, "/foo"); | |
653 request.AddBody(body, true); | |
654 | |
655 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
656 } | |
657 | |
658 TEST_P(EndToEndTest, LargePostZeroRTTFailure) { | |
659 // Have the server accept 0-RTT without waiting a startup period. | |
660 strike_register_no_startup_period_ = true; | |
661 | |
662 // Send a request and then disconnect. This prepares the client to attempt | |
663 // a 0-RTT handshake for the next request. | |
664 ASSERT_TRUE(Initialize()); | |
665 | |
666 string body; | |
667 GenerateBody(&body, 20480); | |
668 | |
669 HTTPMessage request(HttpConstants::HTTP_1_1, | |
670 HttpConstants::POST, "/foo"); | |
671 request.AddBody(body, true); | |
672 | |
673 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
674 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos()); | |
675 | |
676 client_->Disconnect(); | |
677 | |
678 // The 0-RTT handshake should succeed. | |
679 client_->Connect(); | |
680 client_->WaitForResponseForMs(-1); | |
681 ASSERT_TRUE(client_->client()->connected()); | |
682 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
683 EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos()); | |
684 | |
685 client_->Disconnect(); | |
686 | |
687 // Restart the server so that the 0-RTT handshake will take 1 RTT. | |
688 StopServer(); | |
689 server_writer_ = new PacketDroppingTestWriter(); | |
690 StartServer(); | |
691 | |
692 client_->Connect(); | |
693 ASSERT_TRUE(client_->client()->connected()); | |
694 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
695 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos()); | |
696 VerifyCleanConnection(false); | |
697 } | |
698 | |
699 TEST_P(EndToEndTest, CorrectlyConfiguredFec) { | |
700 ASSERT_TRUE(Initialize()); | |
701 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
702 server_thread_->WaitForCryptoHandshakeConfirmed(); | |
703 | |
704 FecPolicy expected_policy = | |
705 GetParam().use_fec ? FEC_PROTECT_ALWAYS : FEC_PROTECT_OPTIONAL; | |
706 | |
707 // Verify that server's FEC configuration is correct. | |
708 server_thread_->Pause(); | |
709 QuicDispatcher* dispatcher = | |
710 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
711 ASSERT_EQ(1u, dispatcher->session_map().size()); | |
712 QuicSession* session = dispatcher->session_map().begin()->second; | |
713 EXPECT_EQ(expected_policy, | |
714 QuicSessionPeer::GetHeadersStream(session)->fec_policy()); | |
715 server_thread_->Resume(); | |
716 | |
717 // Verify that client's FEC configuration is correct. | |
718 EXPECT_EQ(expected_policy, | |
719 QuicSessionPeer::GetHeadersStream( | |
720 client_->client()->session())->fec_policy()); | |
721 EXPECT_EQ(expected_policy, | |
722 client_->GetOrCreateStream()->fec_policy()); | |
723 } | |
724 | |
725 // TODO(shess): This is flaky on ChromiumOS bots. | |
726 // http://crbug.com/374871 | |
727 TEST_P(EndToEndTest, DISABLED_LargePostSmallBandwidthLargeBuffer) { | |
728 ASSERT_TRUE(Initialize()); | |
729 SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1)); | |
730 // 256KB per second with a 256KB buffer from server to client. Wireless | |
731 // clients commonly have larger buffers, but our max CWND is 200. | |
732 server_writer_->set_max_bandwidth_and_buffer_size( | |
733 QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024); | |
734 | |
735 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
736 | |
737 // 1 MB body. | |
738 string body; | |
739 GenerateBody(&body, 1024 * 1024); | |
740 | |
741 HTTPMessage request(HttpConstants::HTTP_1_1, | |
742 HttpConstants::POST, "/foo"); | |
743 request.AddBody(body, true); | |
744 | |
745 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); | |
746 // This connection will not drop packets, because the buffer size is larger | |
747 // than the default receive window. | |
748 VerifyCleanConnection(false); | |
749 } | |
750 | |
751 TEST_P(EndToEndTest, DoNotSetResumeWriteAlarmIfConnectionFlowControlBlocked) { | |
752 // Regression test for b/14677858. | |
753 // Test that the resume write alarm is not set in QuicConnection::OnCanWrite | |
754 // if currently connection level flow control blocked. If set, this results in | |
755 // an infinite loop in the EpollServer, as the alarm fires and is immediately | |
756 // rescheduled. | |
757 ASSERT_TRUE(Initialize()); | |
758 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
759 | |
760 // Ensure both stream and connection level are flow control blocked by setting | |
761 // the send window offset to 0. | |
762 const uint64 kFlowControlWindow = | |
763 server_config_.GetInitialStreamFlowControlWindowToSend(); | |
764 QuicSpdyClientStream* stream = client_->GetOrCreateStream(); | |
765 QuicSession* session = client_->client()->session(); | |
766 QuicFlowControllerPeer::SetSendWindowOffset(stream->flow_controller(), 0); | |
767 QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0); | |
768 EXPECT_TRUE(stream->flow_controller()->IsBlocked()); | |
769 EXPECT_TRUE(session->flow_controller()->IsBlocked()); | |
770 | |
771 // Make sure that the stream has data pending so that it will be marked as | |
772 // write blocked when it receives a stream level WINDOW_UPDATE. | |
773 stream->SendBody("hello", false); | |
774 | |
775 // The stream now attempts to write, fails because it is still connection | |
776 // level flow control blocked, and is added to the write blocked list. | |
777 QuicWindowUpdateFrame window_update(stream->id(), 2 * kFlowControlWindow); | |
778 stream->OnWindowUpdateFrame(window_update); | |
779 | |
780 // Prior to fixing b/14677858 this call would result in an infinite loop in | |
781 // Chromium. As a proxy for detecting this, we now check whether the | |
782 // resume_writes_alarm is set after OnCanWrite. It should not be, as the | |
783 // connection is still flow control blocked. | |
784 session->connection()->OnCanWrite(); | |
785 | |
786 QuicAlarm* resume_writes_alarm = | |
787 QuicConnectionPeer::GetResumeWritesAlarm(session->connection()); | |
788 EXPECT_FALSE(resume_writes_alarm->IsSet()); | |
789 } | |
790 | |
791 TEST_P(EndToEndTest, InvalidStream) { | |
792 ASSERT_TRUE(Initialize()); | |
793 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
794 | |
795 string body; | |
796 GenerateBody(&body, kMaxPacketSize); | |
797 | |
798 HTTPMessage request(HttpConstants::HTTP_1_1, | |
799 HttpConstants::POST, "/foo"); | |
800 request.AddBody(body, true); | |
801 // Force the client to write with a stream ID belonging to a nonexistent | |
802 // server-side stream. | |
803 QuicSessionPeer::SetNextStreamId(client_->client()->session(), 2); | |
804 | |
805 client_->SendCustomSynchronousRequest(request); | |
806 // EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); | |
807 EXPECT_EQ(QUIC_PACKET_FOR_NONEXISTENT_STREAM, client_->connection_error()); | |
808 } | |
809 | |
810 // TODO(rch): this test seems to cause net_unittests timeouts :| | |
811 TEST_P(EndToEndTest, DISABLED_MultipleTermination) { | |
812 ASSERT_TRUE(Initialize()); | |
813 | |
814 HTTPMessage request(HttpConstants::HTTP_1_1, | |
815 HttpConstants::POST, "/foo"); | |
816 request.AddHeader("content-length", "3"); | |
817 request.set_has_complete_message(false); | |
818 | |
819 // Set the offset so we won't frame. Otherwise when we pick up termination | |
820 // before HTTP framing is complete, we send an error and close the stream, | |
821 // and the second write is picked up as writing on a closed stream. | |
822 QuicSpdyClientStream* stream = client_->GetOrCreateStream(); | |
823 ASSERT_TRUE(stream != nullptr); | |
824 ReliableQuicStreamPeer::SetStreamBytesWritten(3, stream); | |
825 | |
826 client_->SendData("bar", true); | |
827 client_->WaitForWriteToFlush(); | |
828 | |
829 // By default the stream protects itself from writes after terminte is set. | |
830 // Override this to test the server handling buggy clients. | |
831 ReliableQuicStreamPeer::SetWriteSideClosed( | |
832 false, client_->GetOrCreateStream()); | |
833 | |
834 EXPECT_DFATAL(client_->SendData("eep", true), "Fin already buffered"); | |
835 } | |
836 | |
837 TEST_P(EndToEndTest, Timeout) { | |
838 client_config_.SetIdleConnectionStateLifetime( | |
839 QuicTime::Delta::FromMicroseconds(500), | |
840 QuicTime::Delta::FromMicroseconds(500)); | |
841 // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake: | |
842 // that's enough to validate timeout in this case. | |
843 Initialize(); | |
844 while (client_->client()->connected()) { | |
845 client_->client()->WaitForEvents(); | |
846 } | |
847 } | |
848 | |
849 TEST_P(EndToEndTest, NegotiateMaxOpenStreams) { | |
850 // Negotiate 1 max open stream. | |
851 client_config_.SetMaxStreamsPerConnection(1, 1); | |
852 ASSERT_TRUE(Initialize()); | |
853 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
854 | |
855 // Make the client misbehave after negotiation. | |
856 const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1; | |
857 QuicSessionPeer::SetMaxOpenStreams(client_->client()->session(), | |
858 kServerMaxStreams + 1); | |
859 | |
860 HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/foo"); | |
861 request.AddHeader("content-length", "3"); | |
862 request.set_has_complete_message(false); | |
863 | |
864 // The server supports a small number of additional streams beyond the | |
865 // negotiated limit. Open enough streams to go beyond that limit. | |
866 for (int i = 0; i < kServerMaxStreams + 1; ++i) { | |
867 client_->SendMessage(request); | |
868 } | |
869 client_->WaitForResponse(); | |
870 | |
871 EXPECT_FALSE(client_->connected()); | |
872 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); | |
873 EXPECT_EQ(QUIC_TOO_MANY_OPEN_STREAMS, client_->connection_error()); | |
874 } | |
875 | |
876 TEST_P(EndToEndTest, NegotiateCongestionControl) { | |
877 ValueRestore<bool> old_flag(&FLAGS_quic_allow_bbr, true); | |
878 ASSERT_TRUE(Initialize()); | |
879 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
880 | |
881 CongestionControlType expected_congestion_control_type = kReno; | |
882 switch (GetParam().congestion_control_tag) { | |
883 case kRENO: | |
884 expected_congestion_control_type = kReno; | |
885 break; | |
886 case kTBBR: | |
887 expected_congestion_control_type = kBBR; | |
888 break; | |
889 case kQBIC: | |
890 expected_congestion_control_type = kCubic; | |
891 break; | |
892 default: | |
893 DLOG(FATAL) << "Unexpected congestion control tag"; | |
894 } | |
895 | |
896 EXPECT_EQ(expected_congestion_control_type, | |
897 QuicSentPacketManagerPeer::GetSendAlgorithm( | |
898 *GetSentPacketManagerFromFirstServerSession()) | |
899 ->GetCongestionControlType()); | |
900 } | |
901 | |
902 TEST_P(EndToEndTest, LimitMaxOpenStreams) { | |
903 // Server limits the number of max streams to 2. | |
904 server_config_.SetMaxStreamsPerConnection(2, 2); | |
905 // Client tries to negotiate for 10. | |
906 client_config_.SetMaxStreamsPerConnection(10, 5); | |
907 | |
908 ASSERT_TRUE(Initialize()); | |
909 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
910 QuicConfig* client_negotiated_config = client_->client()->session()->config(); | |
911 EXPECT_EQ(2u, client_negotiated_config->MaxStreamsPerConnection()); | |
912 } | |
913 | |
914 TEST_P(EndToEndTest, ClientSuggestsRTT) { | |
915 // Client suggests initial RTT, verify it is used. | |
916 const uint32 kInitialRTT = 20000; | |
917 client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT); | |
918 | |
919 ASSERT_TRUE(Initialize()); | |
920 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
921 server_thread_->WaitForCryptoHandshakeConfirmed(); | |
922 | |
923 // Pause the server so we can access the server's internals without races. | |
924 server_thread_->Pause(); | |
925 QuicDispatcher* dispatcher = | |
926 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
927 ASSERT_EQ(1u, dispatcher->session_map().size()); | |
928 const QuicSentPacketManager& client_sent_packet_manager = | |
929 client_->client()->session()->connection()->sent_packet_manager(); | |
930 const QuicSentPacketManager& server_sent_packet_manager = | |
931 *GetSentPacketManagerFromFirstServerSession(); | |
932 | |
933 // BBR automatically enables pacing. | |
934 EXPECT_EQ(GetParam().use_pacing || | |
935 (FLAGS_quic_allow_bbr && | |
936 GetParam().congestion_control_tag == kTBBR), | |
937 server_sent_packet_manager.using_pacing()); | |
938 EXPECT_EQ(GetParam().use_pacing || | |
939 (FLAGS_quic_allow_bbr && | |
940 GetParam().congestion_control_tag == kTBBR), | |
941 client_sent_packet_manager.using_pacing()); | |
942 | |
943 EXPECT_EQ(kInitialRTT, | |
944 client_sent_packet_manager.GetRttStats()->initial_rtt_us()); | |
945 EXPECT_EQ(kInitialRTT, | |
946 server_sent_packet_manager.GetRttStats()->initial_rtt_us()); | |
947 server_thread_->Resume(); | |
948 } | |
949 | |
950 TEST_P(EndToEndTest, MaxInitialRTT) { | |
951 // Client tries to suggest twice the server's max initial rtt and the server | |
952 // uses the max. | |
953 client_config_.SetInitialRoundTripTimeUsToSend( | |
954 2 * kMaxInitialRoundTripTimeUs); | |
955 | |
956 ASSERT_TRUE(Initialize()); | |
957 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
958 server_thread_->WaitForCryptoHandshakeConfirmed(); | |
959 | |
960 // Pause the server so we can access the server's internals without races. | |
961 server_thread_->Pause(); | |
962 QuicDispatcher* dispatcher = | |
963 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
964 ASSERT_EQ(1u, dispatcher->session_map().size()); | |
965 QuicSession* session = dispatcher->session_map().begin()->second; | |
966 const QuicSentPacketManager& client_sent_packet_manager = | |
967 client_->client()->session()->connection()->sent_packet_manager(); | |
968 | |
969 // Now that acks have been exchanged, the RTT estimate has decreased on the | |
970 // server and is not infinite on the client. | |
971 EXPECT_FALSE( | |
972 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite()); | |
973 const RttStats& server_rtt_stats = | |
974 *session->connection()->sent_packet_manager().GetRttStats(); | |
975 EXPECT_EQ(static_cast<int64>(kMaxInitialRoundTripTimeUs), | |
976 server_rtt_stats.initial_rtt_us()); | |
977 EXPECT_GE(static_cast<int64>(kMaxInitialRoundTripTimeUs), | |
978 server_rtt_stats.smoothed_rtt().ToMicroseconds()); | |
979 server_thread_->Resume(); | |
980 } | |
981 | |
982 TEST_P(EndToEndTest, MinInitialRTT) { | |
983 // Client tries to suggest 0 and the server uses the default. | |
984 client_config_.SetInitialRoundTripTimeUsToSend(0); | |
985 | |
986 ASSERT_TRUE(Initialize()); | |
987 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
988 server_thread_->WaitForCryptoHandshakeConfirmed(); | |
989 | |
990 // Pause the server so we can access the server's internals without races. | |
991 server_thread_->Pause(); | |
992 QuicDispatcher* dispatcher = | |
993 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
994 ASSERT_EQ(1u, dispatcher->session_map().size()); | |
995 QuicSession* session = dispatcher->session_map().begin()->second; | |
996 const QuicSentPacketManager& client_sent_packet_manager = | |
997 client_->client()->session()->connection()->sent_packet_manager(); | |
998 const QuicSentPacketManager& server_sent_packet_manager = | |
999 session->connection()->sent_packet_manager(); | |
1000 | |
1001 // Now that acks have been exchanged, the RTT estimate has decreased on the | |
1002 // server and is not infinite on the client. | |
1003 EXPECT_FALSE( | |
1004 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite()); | |
1005 // Expect the default rtt of 100ms. | |
1006 EXPECT_EQ(static_cast<int64>(100 * kNumMicrosPerMilli), | |
1007 server_sent_packet_manager.GetRttStats()->initial_rtt_us()); | |
1008 // Ensure the bandwidth is valid. | |
1009 client_sent_packet_manager.BandwidthEstimate(); | |
1010 server_sent_packet_manager.BandwidthEstimate(); | |
1011 server_thread_->Resume(); | |
1012 } | |
1013 | |
1014 TEST_P(EndToEndTest, 0ByteConnectionId) { | |
1015 client_config_.SetBytesForConnectionIdToSend(0); | |
1016 ASSERT_TRUE(Initialize()); | |
1017 | |
1018 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1019 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1020 | |
1021 QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader( | |
1022 client_->client()->session()->connection()); | |
1023 EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, | |
1024 header->public_header.connection_id_length); | |
1025 } | |
1026 | |
1027 TEST_P(EndToEndTest, 1ByteConnectionId) { | |
1028 client_config_.SetBytesForConnectionIdToSend(1); | |
1029 ASSERT_TRUE(Initialize()); | |
1030 | |
1031 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1032 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1033 QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader( | |
1034 client_->client()->session()->connection()); | |
1035 EXPECT_EQ(PACKET_1BYTE_CONNECTION_ID, | |
1036 header->public_header.connection_id_length); | |
1037 } | |
1038 | |
1039 TEST_P(EndToEndTest, 4ByteConnectionId) { | |
1040 client_config_.SetBytesForConnectionIdToSend(4); | |
1041 ASSERT_TRUE(Initialize()); | |
1042 | |
1043 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1044 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1045 QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader( | |
1046 client_->client()->session()->connection()); | |
1047 EXPECT_EQ(PACKET_4BYTE_CONNECTION_ID, | |
1048 header->public_header.connection_id_length); | |
1049 } | |
1050 | |
1051 TEST_P(EndToEndTest, 8ByteConnectionId) { | |
1052 client_config_.SetBytesForConnectionIdToSend(8); | |
1053 ASSERT_TRUE(Initialize()); | |
1054 | |
1055 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1056 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1057 QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader( | |
1058 client_->client()->session()->connection()); | |
1059 EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, | |
1060 header->public_header.connection_id_length); | |
1061 } | |
1062 | |
1063 TEST_P(EndToEndTest, 15ByteConnectionId) { | |
1064 client_config_.SetBytesForConnectionIdToSend(15); | |
1065 ASSERT_TRUE(Initialize()); | |
1066 | |
1067 // Our server is permissive and allows for out of bounds values. | |
1068 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1069 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1070 QuicPacketHeader* header = QuicConnectionPeer::GetLastHeader( | |
1071 client_->client()->session()->connection()); | |
1072 EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, | |
1073 header->public_header.connection_id_length); | |
1074 } | |
1075 | |
1076 TEST_P(EndToEndTest, ResetConnection) { | |
1077 ASSERT_TRUE(Initialize()); | |
1078 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
1079 | |
1080 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1081 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1082 client_->ResetConnection(); | |
1083 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar")); | |
1084 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1085 } | |
1086 | |
1087 TEST_P(EndToEndTest, MaxStreamsUberTest) { | |
1088 SetPacketLossPercentage(1); | |
1089 ASSERT_TRUE(Initialize()); | |
1090 string large_body; | |
1091 GenerateBody(&large_body, 10240); | |
1092 int max_streams = 100; | |
1093 | |
1094 AddToCache("GET", "/large_response", "HTTP/1.1", "200", "OK", large_body);; | |
1095 | |
1096 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
1097 SetPacketLossPercentage(10); | |
1098 | |
1099 for (int i = 0; i < max_streams; ++i) { | |
1100 EXPECT_LT(0, client_->SendRequest("/large_response")); | |
1101 } | |
1102 | |
1103 // WaitForEvents waits 50ms and returns true if there are outstanding | |
1104 // requests. | |
1105 while (client_->client()->WaitForEvents() == true) { | |
1106 } | |
1107 } | |
1108 | |
1109 TEST_P(EndToEndTest, StreamCancelErrorTest) { | |
1110 ASSERT_TRUE(Initialize()); | |
1111 string small_body; | |
1112 GenerateBody(&small_body, 256); | |
1113 | |
1114 AddToCache("GET", "/small_response", "HTTP/1.1", "200", "OK", small_body); | |
1115 | |
1116 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
1117 | |
1118 QuicSession* session = client_->client()->session(); | |
1119 // Lose the request. | |
1120 SetPacketLossPercentage(100); | |
1121 EXPECT_LT(0, client_->SendRequest("/small_response")); | |
1122 client_->client()->WaitForEvents(); | |
1123 // Transmit the cancel, and ensure the connection is torn down properly. | |
1124 SetPacketLossPercentage(0); | |
1125 QuicStreamId stream_id = kClientDataStreamId1; | |
1126 session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0); | |
1127 | |
1128 // WaitForEvents waits 50ms and returns true if there are outstanding | |
1129 // requests. | |
1130 while (client_->client()->WaitForEvents() == true) { | |
1131 } | |
1132 // It should be completely fine to RST a stream before any data has been | |
1133 // received for that stream. | |
1134 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error()); | |
1135 } | |
1136 | |
1137 class WrongAddressWriter : public QuicPacketWriterWrapper { | |
1138 public: | |
1139 WrongAddressWriter() { | |
1140 IPAddressNumber ip; | |
1141 CHECK(net::ParseIPLiteralToNumber("127.0.0.2", &ip)); | |
1142 self_address_ = IPEndPoint(ip, 0); | |
1143 } | |
1144 | |
1145 WriteResult WritePacket(const char* buffer, | |
1146 size_t buf_len, | |
1147 const IPAddressNumber& real_self_address, | |
1148 const IPEndPoint& peer_address) override { | |
1149 // Use wrong address! | |
1150 return QuicPacketWriterWrapper::WritePacket( | |
1151 buffer, buf_len, self_address_.address(), peer_address); | |
1152 } | |
1153 | |
1154 bool IsWriteBlockedDataBuffered() const override { return false; } | |
1155 | |
1156 IPEndPoint self_address_; | |
1157 }; | |
1158 | |
1159 TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) { | |
1160 // Tests that the client's IP can not change during an established QUIC | |
1161 // connection. If it changes, the connection is closed by the server as we do | |
1162 // not yet support IP migration. | |
1163 ASSERT_TRUE(Initialize()); | |
1164 | |
1165 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1166 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1167 | |
1168 WrongAddressWriter* writer = new WrongAddressWriter(); | |
1169 | |
1170 writer->set_writer(new QuicDefaultPacketWriter(client_->client()->fd())); | |
1171 QuicConnectionPeer::SetWriter(client_->client()->session()->connection(), | |
1172 writer, | |
1173 /* owns_writer= */ true); | |
1174 | |
1175 client_->SendSynchronousRequest("/bar"); | |
1176 | |
1177 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); | |
1178 EXPECT_EQ(QUIC_ERROR_MIGRATING_ADDRESS, client_->connection_error()); | |
1179 } | |
1180 | |
1181 TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) { | |
1182 // Tests that the client's port can change during an established QUIC | |
1183 // connection, and that doing so does not result in the connection being | |
1184 // closed by the server. | |
1185 ASSERT_TRUE(Initialize()); | |
1186 | |
1187 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1188 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1189 | |
1190 // Store the client address which was used to send the first request. | |
1191 IPEndPoint old_address = client_->client()->client_address(); | |
1192 | |
1193 // Stop listening on the old FD. | |
1194 EpollServer* eps = client_->epoll_server(); | |
1195 int old_fd = client_->client()->fd(); | |
1196 eps->UnregisterFD(old_fd); | |
1197 // Create a new socket before closing the old one, which will result in a new | |
1198 // ephemeral port. | |
1199 QuicClientPeer::CreateUDPSocket(client_->client()); | |
1200 close(old_fd); | |
1201 | |
1202 // The packet writer needs to be updated to use the new FD. | |
1203 client_->client()->CreateQuicPacketWriter(); | |
1204 | |
1205 // Change the internal state of the client and connection to use the new port, | |
1206 // this is done because in a real NAT rebinding the client wouldn't see any | |
1207 // port change, and so expects no change to incoming port. | |
1208 // This is kind of ugly, but needed as we are simply swapping out the client | |
1209 // FD rather than any more complex NAT rebinding simulation. | |
1210 int new_port = client_->client()->client_address().port(); | |
1211 QuicClientPeer::SetClientPort(client_->client(), new_port); | |
1212 QuicConnectionPeer::SetSelfAddress( | |
1213 client_->client()->session()->connection(), | |
1214 IPEndPoint( | |
1215 client_->client()->session()->connection()->self_address().address(), | |
1216 new_port)); | |
1217 | |
1218 // Register the new FD for epoll events. | |
1219 int new_fd = client_->client()->fd(); | |
1220 eps->RegisterFD(new_fd, client_->client(), EPOLLIN | EPOLLOUT | EPOLLET); | |
1221 | |
1222 // Send a second request, using the new FD. | |
1223 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar")); | |
1224 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1225 | |
1226 // Verify that the client's ephemeral port is different. | |
1227 IPEndPoint new_address = client_->client()->client_address(); | |
1228 EXPECT_EQ(old_address.address(), new_address.address()); | |
1229 EXPECT_NE(old_address.port(), new_address.port()); | |
1230 } | |
1231 | |
1232 TEST_P(EndToEndTest, DifferentFlowControlWindows) { | |
1233 // Client and server can set different initial flow control receive windows. | |
1234 // These are sent in CHLO/SHLO. Tests that these values are exchanged properly | |
1235 // in the crypto handshake. | |
1236 const uint32 kClientStreamIFCW = 123456; | |
1237 const uint32 kClientSessionIFCW = 234567; | |
1238 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW); | |
1239 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW); | |
1240 | |
1241 const uint32 kServerStreamIFCW = 654321; | |
1242 const uint32 kServerSessionIFCW = 765432; | |
1243 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW); | |
1244 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW); | |
1245 | |
1246 ASSERT_TRUE(Initialize()); | |
1247 | |
1248 // Values are exchanged during crypto handshake, so wait for that to finish. | |
1249 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
1250 server_thread_->WaitForCryptoHandshakeConfirmed(); | |
1251 | |
1252 // Open a data stream to make sure the stream level flow control is updated. | |
1253 QuicSpdyClientStream* stream = client_->GetOrCreateStream(); | |
1254 stream->SendBody("hello", false); | |
1255 | |
1256 // Client should have the right values for server's receive window. | |
1257 EXPECT_EQ(kServerStreamIFCW, | |
1258 client_->client() | |
1259 ->session() | |
1260 ->config() | |
1261 ->ReceivedInitialStreamFlowControlWindowBytes()); | |
1262 EXPECT_EQ(kServerSessionIFCW, | |
1263 client_->client() | |
1264 ->session() | |
1265 ->config() | |
1266 ->ReceivedInitialSessionFlowControlWindowBytes()); | |
1267 EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset( | |
1268 stream->flow_controller())); | |
1269 EXPECT_EQ(kServerSessionIFCW, | |
1270 QuicFlowControllerPeer::SendWindowOffset( | |
1271 client_->client()->session()->flow_controller())); | |
1272 | |
1273 // Server should have the right values for client's receive window. | |
1274 server_thread_->Pause(); | |
1275 QuicDispatcher* dispatcher = | |
1276 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
1277 QuicSession* session = dispatcher->session_map().begin()->second; | |
1278 EXPECT_EQ(kClientStreamIFCW, | |
1279 session->config()->ReceivedInitialStreamFlowControlWindowBytes()); | |
1280 EXPECT_EQ(kClientSessionIFCW, | |
1281 session->config()->ReceivedInitialSessionFlowControlWindowBytes()); | |
1282 EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset( | |
1283 session->flow_controller())); | |
1284 server_thread_->Resume(); | |
1285 } | |
1286 | |
1287 TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) { | |
1288 // The special headers and crypto streams should be subject to per-stream flow | |
1289 // control limits, but should not be subject to connection level flow control. | |
1290 const uint32 kStreamIFCW = 123456; | |
1291 const uint32 kSessionIFCW = 234567; | |
1292 set_client_initial_stream_flow_control_receive_window(kStreamIFCW); | |
1293 set_client_initial_session_flow_control_receive_window(kSessionIFCW); | |
1294 set_server_initial_stream_flow_control_receive_window(kStreamIFCW); | |
1295 set_server_initial_session_flow_control_receive_window(kSessionIFCW); | |
1296 | |
1297 ASSERT_TRUE(Initialize()); | |
1298 | |
1299 // Wait for crypto handshake to finish. This should have contributed to the | |
1300 // crypto stream flow control window, but not affected the session flow | |
1301 // control window. | |
1302 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
1303 server_thread_->WaitForCryptoHandshakeConfirmed(); | |
1304 | |
1305 QuicCryptoStream* crypto_stream = | |
1306 QuicSessionPeer::GetCryptoStream(client_->client()->session()); | |
1307 EXPECT_LT( | |
1308 QuicFlowControllerPeer::SendWindowSize(crypto_stream->flow_controller()), | |
1309 kStreamIFCW); | |
1310 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize( | |
1311 client_->client()->session()->flow_controller())); | |
1312 | |
1313 // Send a request with no body, and verify that the connection level window | |
1314 // has not been affected. | |
1315 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1316 | |
1317 QuicHeadersStream* headers_stream = | |
1318 QuicSessionPeer::GetHeadersStream(client_->client()->session()); | |
1319 EXPECT_LT( | |
1320 QuicFlowControllerPeer::SendWindowSize(headers_stream->flow_controller()), | |
1321 kStreamIFCW); | |
1322 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize( | |
1323 client_->client()->session()->flow_controller())); | |
1324 | |
1325 // Server should be in a similar state: connection flow control window should | |
1326 // not have any bytes marked as received. | |
1327 server_thread_->Pause(); | |
1328 QuicDispatcher* dispatcher = | |
1329 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
1330 QuicSession* session = dispatcher->session_map().begin()->second; | |
1331 QuicFlowController* server_connection_flow_controller = | |
1332 session->flow_controller(); | |
1333 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize( | |
1334 server_connection_flow_controller)); | |
1335 server_thread_->Resume(); | |
1336 } | |
1337 | |
1338 TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) { | |
1339 // Regression test for b/16010251. | |
1340 // A stream created on receipt of a simple request with no body will never get | |
1341 // a stream frame with a FIN. Verify that we don't keep track of the stream in | |
1342 // the locally closed streams map: it will never be removed if so. | |
1343 ASSERT_TRUE(Initialize()); | |
1344 | |
1345 // Send a simple headers only request, and receive response. | |
1346 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | |
1347 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1348 | |
1349 // Now verify that the server is not waiting for a final FIN or RST. | |
1350 server_thread_->Pause(); | |
1351 QuicDispatcher* dispatcher = | |
1352 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
1353 QuicSession* session = dispatcher->session_map().begin()->second; | |
1354 EXPECT_EQ(0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset( | |
1355 session).size()); | |
1356 server_thread_->Resume(); | |
1357 } | |
1358 | |
1359 TEST_P(EndToEndTest, EnablePacingViaFlag) { | |
1360 // When pacing is enabled via command-line flag, it will always be enabled, | |
1361 // regardless of the config. or the specific congestion-control algorithm. | |
1362 ValueRestore<bool> old_flag(&FLAGS_quic_enable_pacing, true); | |
1363 ASSERT_TRUE(Initialize()); | |
1364 | |
1365 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
1366 server_thread_->WaitForCryptoHandshakeConfirmed(); | |
1367 | |
1368 // Pause the server so we can access the server's internals without races. | |
1369 server_thread_->Pause(); | |
1370 QuicDispatcher* dispatcher = | |
1371 QuicServerPeer::GetDispatcher(server_thread_->server()); | |
1372 ASSERT_EQ(1u, dispatcher->session_map().size()); | |
1373 const QuicSentPacketManager& client_sent_packet_manager = | |
1374 client_->client()->session()->connection()->sent_packet_manager(); | |
1375 const QuicSentPacketManager& server_sent_packet_manager = | |
1376 *GetSentPacketManagerFromFirstServerSession(); | |
1377 EXPECT_TRUE(server_sent_packet_manager.using_pacing()); | |
1378 EXPECT_TRUE(client_sent_packet_manager.using_pacing()); | |
1379 } | |
1380 | |
1381 // A TestAckNotifierDelegate verifies that its OnAckNotification method has been | |
1382 // called exactly once on destruction. | |
1383 class TestAckNotifierDelegate : public QuicAckNotifier::DelegateInterface { | |
1384 public: | |
1385 TestAckNotifierDelegate() {} | |
1386 | |
1387 void OnAckNotification(int /*num_retransmitted_packets*/, | |
1388 int /*num_retransmitted_bytes*/, | |
1389 QuicTime::Delta /*delta_largest_observed*/) override { | |
1390 ASSERT_FALSE(has_been_notified_); | |
1391 has_been_notified_ = true; | |
1392 } | |
1393 | |
1394 bool has_been_notified() const { return has_been_notified_; } | |
1395 | |
1396 protected: | |
1397 // Object is ref counted. | |
1398 ~TestAckNotifierDelegate() override { EXPECT_TRUE(has_been_notified_); } | |
1399 | |
1400 private: | |
1401 bool has_been_notified_ = false; | |
1402 }; | |
1403 | |
1404 TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) { | |
1405 // Verify that even in the presence of packet loss and occasionally blocked | |
1406 // socket, an AckNotifierDelegate will get informed that the data it is | |
1407 // interested in has been ACKed. This tests end-to-end ACK notification, and | |
1408 // demonstrates that retransmissions do not break this functionality. | |
1409 ValueRestore<bool> old_flag(&FLAGS_quic_attach_ack_notifiers_to_packets, | |
1410 true); | |
1411 | |
1412 SetPacketLossPercentage(5); | |
1413 ASSERT_TRUE(Initialize()); | |
1414 | |
1415 // Wait for the server SHLO before upping the packet loss. | |
1416 client_->client()->WaitForCryptoHandshakeConfirmed(); | |
1417 SetPacketLossPercentage(30); | |
1418 client_writer_->set_fake_blocked_socket_percentage(10); | |
1419 | |
1420 // Create a POST request and send the headers only. | |
1421 HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/foo"); | |
1422 request.set_has_complete_message(false); | |
1423 client_->SendMessage(request); | |
1424 | |
1425 // The TestAckNotifierDelegate will cause a failure if not notified. | |
1426 scoped_refptr<TestAckNotifierDelegate> delegate(new TestAckNotifierDelegate); | |
1427 | |
1428 // Test the AckNotifier's ability to track multiple packets by making the | |
1429 // request body exceed the size of a single packet. | |
1430 string request_string = | |
1431 "a request body bigger than one packet" + string(kMaxPacketSize, '.'); | |
1432 | |
1433 // Send the request, and register the delegate for ACKs. | |
1434 client_->SendData(request_string, true, delegate.get()); | |
1435 client_->WaitForResponse(); | |
1436 EXPECT_EQ(kFooResponseBody, client_->response_body()); | |
1437 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | |
1438 | |
1439 // Send another request to flush out any pending ACKs on the server. | |
1440 client_->SendSynchronousRequest(request_string); | |
1441 | |
1442 // Pause the server to avoid races. | |
1443 server_thread_->Pause(); | |
1444 // Make sure the delegate does get the notification it expects. | |
1445 while (!delegate->has_been_notified()) { | |
1446 // Waits for up to 50 ms. | |
1447 client_->client()->WaitForEvents(); | |
1448 } | |
1449 server_thread_->Resume(); | |
1450 } | |
1451 | |
1452 } // namespace | |
1453 } // namespace test | |
1454 } // namespace tools | |
1455 } // namespace net | |
OLD | NEW |