| 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 |