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.
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 "net/base/ip_endpoint.h"
16 #include "net/quic/congestion_control/tcp_cubic_sender.h"
17 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
18 #include "net/quic/crypto/null_encrypter.h"
19 #include "net/quic/quic_framer.h"
20 #include "net/quic/quic_packet_creator.h"
21 #include "net/quic/quic_protocol.h"
22 #include "net/quic/quic_sent_packet_manager.h"
23 #include "net/quic/test_tools/quic_connection_peer.h"
24 #include "net/quic/test_tools/quic_session_peer.h"
25 #include "net/quic/test_tools/quic_test_utils.h"
26 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
27 #include "net/test/gtest_util.h"
28 #include "net/tools/quic/quic_epoll_connection_helper.h"
29 #include "net/tools/quic/quic_in_memory_cache.h"
30 #include "net/tools/quic/quic_packet_writer_wrapper.h"
31 #include "net/tools/quic/quic_server.h"
32 #include "net/tools/quic/quic_socket_utils.h"
33 #include "net/tools/quic/quic_spdy_client_stream.h"
34 #include "net/tools/quic/test_tools/http_message_test_utils.h"
35 #include "net/tools/quic/test_tools/packet_dropping_test_writer.h"
36 #include "net/tools/quic/test_tools/quic_client_peer.h"
37 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h"
38 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
39 #include "net/tools/quic/test_tools/quic_server_peer.h"
40 #include "net/tools/quic/test_tools/quic_test_client.h"
41 #include "net/tools/quic/test_tools/server_thread.h"
42 #include "testing/gtest/include/gtest/gtest.h"
44 using base::StringPiece;
45 using base::WaitableEvent;
46 using net::test::QuicConnectionPeer;
47 using net::test::QuicSessionPeer;
48 using net::test::ReliableQuicStreamPeer;
49 using net::tools::test::PacketDroppingTestWriter;
50 using net::tools::test::QuicDispatcherPeer;
51 using net::tools::test::QuicServerPeer;
61 const char* kFooResponseBody = "Artichoke hearts make me happy.";
62 const char* kBarResponseBody = "Palm hearts are pretty delicious, also.";
64 void GenerateBody(string* body, int length) {
66 body->reserve(length);
67 for (int i = 0; i < length; ++i) {
68 body->append(1, static_cast<char>(32 + i % (126 - 32)));
72 // Run all tests with the cross products of all versions.
74 TestParams(const QuicVersionVector& client_supported_versions,
75 const QuicVersionVector& server_supported_versions,
76 QuicVersion negotiated_version,
78 : client_supported_versions(client_supported_versions),
79 server_supported_versions(server_supported_versions),
80 negotiated_version(negotiated_version),
81 use_pacing(use_pacing) {
84 friend ostream& operator<<(ostream& os, const TestParams& p) {
85 os << "{ server_supported_versions: "
86 << QuicVersionVectorToString(p.server_supported_versions);
87 os << " client_supported_versions: "
88 << QuicVersionVectorToString(p.client_supported_versions);
89 os << " negotiated_version: " << QuicVersionToString(p.negotiated_version);
90 os << " use_pacing: " << p.use_pacing << " }";
94 QuicVersionVector client_supported_versions;
95 QuicVersionVector server_supported_versions;
96 QuicVersion negotiated_version;
100 // Constructs various test permutations.
101 vector<TestParams> GetTestParams() {
102 vector<TestParams> params;
103 QuicVersionVector all_supported_versions = QuicSupportedVersions();
104 for (int use_pacing = 0; use_pacing < 2; ++use_pacing) {
105 // TODO(rch): since 13 is not 0-RTT compatible with 12, we can not
106 // have the client support both at the same time.
108 // Add an entry for server and client supporting all versions.
109 params.push_back(TestParams(all_supported_versions,
110 all_supported_versions,
111 all_supported_versions[0],
115 // Test client supporting 1 version and server supporting all versions.
116 // Simulate an old client and exercise version downgrade in the server.
117 // No protocol negotiation should occur. Skip the i = 0 case because it
118 // is essentially the same as the default case.
119 // TODO(rch): When QUIC_VERSION_12 is removed, change the intialization
120 // of i from 0 back to 1.
121 for (size_t i = 0; i < all_supported_versions.size(); ++i) {
122 QuicVersionVector client_supported_versions;
123 client_supported_versions.push_back(all_supported_versions[i]);
124 params.push_back(TestParams(client_supported_versions,
125 all_supported_versions,
126 client_supported_versions[0],
130 // TODO(rch): since 13 is not 0-RTT compatible with 12, we can not
131 // have the client support both at the same time.
133 // Test client supporting all versions and server supporting 1 version.
134 // Simulate an old server and exercise version downgrade in the client.
135 // Protocol negotiation should occur. Skip the i = 0 case because it is
136 // essentially the same as the default case.
137 for (size_t i = 1; i < all_supported_versions.size(); ++i) {
138 QuicVersionVector server_supported_versions;
139 server_supported_versions.push_back(all_supported_versions[i]);
140 params.push_back(TestParams(all_supported_versions,
141 server_supported_versions,
142 server_supported_versions[0],
150 class ServerDelegate : public PacketDroppingTestWriter::Delegate {
152 explicit ServerDelegate(QuicDispatcher* dispatcher)
153 : dispatcher_(dispatcher) {}
154 virtual ~ServerDelegate() {}
155 virtual void OnCanWrite() OVERRIDE { dispatcher_->OnCanWrite(); }
157 QuicDispatcher* dispatcher_;
160 class ClientDelegate : public PacketDroppingTestWriter::Delegate {
162 explicit ClientDelegate(QuicClient* client) : client_(client) {}
163 virtual ~ClientDelegate() {}
164 virtual void OnCanWrite() OVERRIDE {
165 EpollEvent event(EPOLLOUT, false);
166 client_->OnEvent(client_->fd(), &event);
172 class EndToEndTest : public ::testing::TestWithParam<TestParams> {
175 : server_hostname_("example.com"),
176 server_started_(false),
177 strike_register_no_startup_period_(false) {
178 net::IPAddressNumber ip;
179 CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip));
180 server_address_ = IPEndPoint(ip, 0);
182 client_supported_versions_ = GetParam().client_supported_versions;
183 server_supported_versions_ = GetParam().server_supported_versions;
184 negotiated_version_ = GetParam().negotiated_version;
185 FLAGS_enable_quic_pacing = GetParam().use_pacing;
186 VLOG(1) << "Using Configuration: " << GetParam();
188 client_config_.SetDefaults();
189 server_config_.SetDefaults();
190 server_config_.set_initial_round_trip_time_us(kMaxInitialRoundTripTimeUs,
193 QuicInMemoryCachePeer::ResetForTests();
194 AddToCache("GET", "https://www.google.com/foo",
195 "HTTP/1.1", "200", "OK", kFooResponseBody);
196 AddToCache("GET", "https://www.google.com/bar",
197 "HTTP/1.1", "200", "OK", kBarResponseBody);
200 virtual ~EndToEndTest() {
201 // TODO(rtenneti): port RecycleUnusedPort if needed.
202 // RecycleUnusedPort(server_address_.port());
203 QuicInMemoryCachePeer::ResetForTests();
206 QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
207 QuicTestClient* client = new QuicTestClient(server_address_,
211 client_supported_versions_);
212 client->UseWriter(writer);
218 // Start the server first, because CreateQuicClient() attempts
219 // to connect to the server.
221 client_.reset(CreateQuicClient(client_writer_));
222 static EpollEvent event(EPOLLOUT, false);
223 client_writer_->Initialize(
224 reinterpret_cast<QuicEpollConnectionHelper*>(
225 QuicConnectionPeer::GetHelper(
226 client_->client()->session()->connection())),
227 new ClientDelegate(client_->client()));
228 return client_->client()->connected();
231 virtual void SetUp() OVERRIDE {
232 // The ownership of these gets transferred to the QuicPacketWriterWrapper
233 // and QuicDispatcher when Initialize() is executed.
234 client_writer_ = new PacketDroppingTestWriter();
235 server_writer_ = new PacketDroppingTestWriter();
238 virtual void TearDown() OVERRIDE {
243 server_thread_.reset(new ServerThread(server_address_, server_config_,
244 server_supported_versions_,
245 strike_register_no_startup_period_));
246 server_thread_->Initialize();
247 server_address_ = IPEndPoint(server_address_.address(),
248 server_thread_->GetPort());
249 QuicDispatcher* dispatcher =
250 QuicServerPeer::GetDispatcher(server_thread_->server());
251 QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
252 server_writer_->Initialize(
253 QuicDispatcherPeer::GetHelper(dispatcher),
254 new ServerDelegate(dispatcher));
255 server_thread_->Start();
256 server_started_ = true;
260 if (!server_started_)
262 if (server_thread_.get()) {
263 server_thread_->Quit();
264 server_thread_->Join();
268 void AddToCache(StringPiece method,
271 StringPiece response_code,
272 StringPiece response_detail,
274 QuicInMemoryCache::GetInstance()->AddSimpleResponse(
275 method, path, version, response_code, response_detail, body);
278 void SetPacketLossPercentage(int32 loss) {
279 // TODO(rtenneti): enable when we can do random packet loss tests in
281 if (loss != 0 && loss != 100)
283 client_writer_->set_fake_packet_loss_percentage(loss);
284 server_writer_->set_fake_packet_loss_percentage(loss);
287 void SetPacketSendDelay(QuicTime::Delta delay) {
288 // TODO(rtenneti): enable when we can do random packet send delay tests in
290 // client_writer_->set_fake_packet_delay(delay);
291 // server_writer_->set_fake_packet_delay(delay);
294 void SetReorderPercentage(int32 reorder) {
295 // TODO(rtenneti): enable when we can do random packet reorder tests in
297 // client_writer_->set_fake_reorder_percentage(reorder);
298 // server_writer_->set_fake_reorder_percentage(reorder);
301 IPEndPoint server_address_;
302 string server_hostname_;
303 scoped_ptr<ServerThread> server_thread_;
304 scoped_ptr<QuicTestClient> client_;
305 PacketDroppingTestWriter* client_writer_;
306 PacketDroppingTestWriter* server_writer_;
307 bool server_started_;
308 QuicConfig client_config_;
309 QuicConfig server_config_;
310 QuicVersionVector client_supported_versions_;
311 QuicVersionVector server_supported_versions_;
312 QuicVersion negotiated_version_;
313 bool strike_register_no_startup_period_;
316 // Run all end to end tests with all supported versions.
317 INSTANTIATE_TEST_CASE_P(EndToEndTests,
319 ::testing::ValuesIn(GetTestParams()));
321 TEST_P(EndToEndTest, SimpleRequestResponse) {
322 ASSERT_TRUE(Initialize());
324 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
325 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
328 // TODO(rch): figure out how to detect missing v6 supprt (like on the linux
329 // try bots) and selectively disable this test.
330 TEST_P(EndToEndTest, DISABLED_SimpleRequestResponsev6) {
332 CHECK(net::ParseIPLiteralToNumber("::1", &ip));
333 server_address_ = IPEndPoint(ip, server_address_.port());
334 ASSERT_TRUE(Initialize());
336 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
337 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
340 TEST_P(EndToEndTest, SeparateFinPacket) {
341 ASSERT_TRUE(Initialize());
343 HTTPMessage request(HttpConstants::HTTP_1_1,
344 HttpConstants::POST, "/foo");
345 request.set_has_complete_message(false);
347 client_->SendMessage(request);
349 client_->SendData(string(), true);
351 client_->WaitForResponse();
352 EXPECT_EQ(kFooResponseBody, client_->response_body());
353 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
355 request.AddBody("foo", true);
357 client_->SendMessage(request);
358 client_->SendData(string(), true);
359 client_->WaitForResponse();
360 EXPECT_EQ(kFooResponseBody, client_->response_body());
361 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
364 TEST_P(EndToEndTest, MultipleRequestResponse) {
365 ASSERT_TRUE(Initialize());
367 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
368 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
369 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
370 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
373 TEST_P(EndToEndTest, MultipleClients) {
374 ASSERT_TRUE(Initialize());
375 scoped_ptr<QuicTestClient> client2(CreateQuicClient(NULL));
377 HTTPMessage request(HttpConstants::HTTP_1_1,
378 HttpConstants::POST, "/foo");
379 request.AddHeader("content-length", "3");
380 request.set_has_complete_message(false);
382 client_->SendMessage(request);
383 client2->SendMessage(request);
385 client_->SendData("bar", true);
386 client_->WaitForResponse();
387 EXPECT_EQ(kFooResponseBody, client_->response_body());
388 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
390 client2->SendData("eep", true);
391 client2->WaitForResponse();
392 EXPECT_EQ(kFooResponseBody, client2->response_body());
393 EXPECT_EQ(200u, client2->response_headers()->parsed_response_code());
396 TEST_P(EndToEndTest, RequestOverMultiplePackets) {
397 // Send a large enough request to guarantee fragmentation.
398 string huge_request =
399 "https://www.google.com/some/path?query=" + string(kMaxPacketSize, '.');
400 AddToCache("GET", huge_request, "HTTP/1.1", "200", "OK", kBarResponseBody);
402 ASSERT_TRUE(Initialize());
404 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
405 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
408 TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
409 // Send a large enough request to guarantee fragmentation.
410 string huge_request =
411 "https://www.google.com/some/path?query=" + string(kMaxPacketSize, '.');
412 AddToCache("GET", huge_request, "HTTP/1.1", "200", "OK", kBarResponseBody);
414 ASSERT_TRUE(Initialize());
415 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
416 SetReorderPercentage(50);
418 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
419 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
422 TEST_P(EndToEndTest, PostMissingBytes) {
423 ASSERT_TRUE(Initialize());
425 // Add a content length header with no body.
426 HTTPMessage request(HttpConstants::HTTP_1_1,
427 HttpConstants::POST, "/foo");
428 request.AddHeader("content-length", "3");
429 request.set_skip_message_validation(true);
431 // This should be detected as stream fin without complete request,
432 // triggering an error response.
433 client_->SendCustomSynchronousRequest(request);
434 EXPECT_EQ("bad", client_->response_body());
435 EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
438 TEST_P(EndToEndTest, LargePostNoPacketLoss) {
439 ASSERT_TRUE(Initialize());
441 client_->client()->WaitForCryptoHandshakeConfirmed();
445 GenerateBody(&body, 1024 * 1024);
447 HTTPMessage request(HttpConstants::HTTP_1_1,
448 HttpConstants::POST, "/foo");
449 request.AddBody(body, true);
451 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
452 QuicConnectionStats stats =
453 client_->client()->session()->connection()->GetStats();
454 // TODO(ianswett): Restore the packets_lost expectation when fixing b/12887145
455 // EXPECT_EQ(0u, stats.packets_lost);
456 EXPECT_EQ(0u, stats.rto_count);
459 TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
460 ASSERT_TRUE(Initialize());
461 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
463 client_->client()->WaitForCryptoHandshakeConfirmed();
467 GenerateBody(&body, 100 * 1024);
469 HTTPMessage request(HttpConstants::HTTP_1_1,
470 HttpConstants::POST, "/foo");
471 request.AddBody(body, true);
473 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
474 QuicConnectionStats stats =
475 client_->client()->session()->connection()->GetStats();
476 EXPECT_EQ(0u, stats.packets_lost);
479 TEST_P(EndToEndTest, LargePostWithPacketLoss) {
480 // Connect with lower fake packet loss than we'd like to test. Until
481 // b/10126687 is fixed, losing handshake packets is pretty brutal.
482 SetPacketLossPercentage(5);
483 ASSERT_TRUE(Initialize());
485 // Wait for the server SHLO before upping the packet loss.
486 client_->client()->WaitForCryptoHandshakeConfirmed();
487 SetPacketLossPercentage(30);
491 GenerateBody(&body, 1024 * 10);
493 HTTPMessage request(HttpConstants::HTTP_1_1,
494 HttpConstants::POST, "/foo");
495 request.AddBody(body, true);
497 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
500 TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
501 ASSERT_TRUE(Initialize());
503 client_->client()->WaitForCryptoHandshakeConfirmed();
504 // Both of these must be called when the writer is not actively used.
505 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
506 SetReorderPercentage(30);
510 GenerateBody(&body, 1024 * 1024);
512 HTTPMessage request(HttpConstants::HTTP_1_1,
513 HttpConstants::POST, "/foo");
514 request.AddBody(body, true);
516 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
519 TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
520 // Connect with lower fake packet loss than we'd like to test. Until
521 // b/10126687 is fixed, losing handshake packets is pretty brutal.
522 SetPacketLossPercentage(5);
523 ASSERT_TRUE(Initialize());
525 // Wait for the server SHLO before upping the packet loss.
526 client_->client()->WaitForCryptoHandshakeConfirmed();
527 SetPacketLossPercentage(10);
528 client_writer_->set_fake_blocked_socket_percentage(10);
532 GenerateBody(&body, 1024 * 10);
534 HTTPMessage request(HttpConstants::HTTP_1_1,
535 HttpConstants::POST, "/foo");
536 request.AddBody(body, true);
538 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
541 // TODO(rtenneti): rch is investigating the root cause. Will enable after we
543 TEST_P(EndToEndTest, DISABLED_LargePostZeroRTTFailure) {
544 // Have the server accept 0-RTT without waiting a startup period.
545 strike_register_no_startup_period_ = true;
547 // Send a request and then disconnect. This prepares the client to attempt
548 // a 0-RTT handshake for the next request.
549 ASSERT_TRUE(Initialize());
552 GenerateBody(&body, 20480);
554 HTTPMessage request(HttpConstants::HTTP_1_1,
555 HttpConstants::POST, "/foo");
556 request.AddBody(body, true);
558 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
559 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos());
561 client_->Disconnect();
563 // The 0-RTT handshake should succeed.
565 client_->WaitForResponseForMs(-1);
566 ASSERT_TRUE(client_->client()->connected());
567 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
568 EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
570 client_->Disconnect();
572 // Restart the server so that the 0-RTT handshake will take 1 RTT.
574 server_writer_ = new PacketDroppingTestWriter();
578 ASSERT_TRUE(client_->client()->connected());
579 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
580 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos());
583 // TODO(ianswett): Enable once b/9295090 is fixed.
584 TEST_P(EndToEndTest, DISABLED_LargePostFEC) {
585 SetPacketLossPercentage(30);
586 ASSERT_TRUE(Initialize());
587 client_->options()->max_packets_per_fec_group = 6;
590 GenerateBody(&body, 10240);
592 HTTPMessage request(HttpConstants::HTTP_1_1,
593 HttpConstants::POST, "/foo");
594 request.AddBody(body, true);
596 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
599 TEST_P(EndToEndTest, LargePostLargeBuffer) {
600 ASSERT_TRUE(Initialize());
601 SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
602 // 1Mbit per second with a 128k buffer from server to client. Wireless
603 // clients commonly have larger buffers, but our max CWND is 200.
604 server_writer_->set_max_bandwidth_and_buffer_size(
605 QuicBandwidth::FromBytesPerSecond(256 * 1024), 128 * 1024);
607 client_->client()->WaitForCryptoHandshakeConfirmed();
611 GenerateBody(&body, 1024 * 1024);
613 HTTPMessage request(HttpConstants::HTTP_1_1,
614 HttpConstants::POST, "/foo");
615 request.AddBody(body, true);
617 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
620 TEST_P(EndToEndTest, InvalidStream) {
621 ASSERT_TRUE(Initialize());
622 client_->client()->WaitForCryptoHandshakeConfirmed();
625 GenerateBody(&body, kMaxPacketSize);
627 HTTPMessage request(HttpConstants::HTTP_1_1,
628 HttpConstants::POST, "/foo");
629 request.AddBody(body, true);
630 // Force the client to write with a stream ID belonging to a nonexistent
631 // server-side stream.
632 QuicSessionPeer::SetNextStreamId(client_->client()->session(), 2);
634 client_->SendCustomSynchronousRequest(request);
635 // EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
636 EXPECT_EQ(QUIC_PACKET_FOR_NONEXISTENT_STREAM, client_->connection_error());
639 // TODO(rch): this test seems to cause net_unittests timeouts :|
640 TEST_P(EndToEndTest, DISABLED_MultipleTermination) {
641 ASSERT_TRUE(Initialize());
643 HTTPMessage request(HttpConstants::HTTP_1_1,
644 HttpConstants::POST, "/foo");
645 request.AddHeader("content-length", "3");
646 request.set_has_complete_message(false);
648 // Set the offset so we won't frame. Otherwise when we pick up termination
649 // before HTTP framing is complete, we send an error and close the stream,
650 // and the second write is picked up as writing on a closed stream.
651 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
652 ASSERT_TRUE(stream != NULL);
653 ReliableQuicStreamPeer::SetStreamBytesWritten(3, stream);
655 client_->SendData("bar", true);
656 client_->WaitForWriteToFlush();
658 // By default the stream protects itself from writes after terminte is set.
659 // Override this to test the server handling buggy clients.
660 ReliableQuicStreamPeer::SetWriteSideClosed(
661 false, client_->GetOrCreateStream());
663 EXPECT_DFATAL(client_->SendData("eep", true), "Fin already buffered");
666 TEST_P(EndToEndTest, Timeout) {
667 client_config_.set_idle_connection_state_lifetime(
668 QuicTime::Delta::FromMicroseconds(500),
669 QuicTime::Delta::FromMicroseconds(500));
670 // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
671 // that's enough to validate timeout in this case.
673 while (client_->client()->connected()) {
674 client_->client()->WaitForEvents();
678 TEST_P(EndToEndTest, LimitMaxOpenStreams) {
679 // Server limits the number of max streams to 2.
680 server_config_.set_max_streams_per_connection(2, 2);
681 // Client tries to negotiate for 10.
682 client_config_.set_max_streams_per_connection(10, 5);
684 ASSERT_TRUE(Initialize());
685 client_->client()->WaitForCryptoHandshakeConfirmed();
686 QuicConfig* client_negotiated_config = client_->client()->session()->config();
687 EXPECT_EQ(2u, client_negotiated_config->max_streams_per_connection());
690 // TODO(rtenneti): DISABLED_LimitCongestionWindowAndRTT seems to be flaky.
691 // http://crbug.com/321870.
692 TEST_P(EndToEndTest, DISABLED_LimitCongestionWindowAndRTT) {
693 server_config_.set_server_initial_congestion_window(kMaxInitialWindow,
694 kDefaultInitialWindow);
695 // Client tries to negotiate twice the server's max and negotiation settles
697 client_config_.set_server_initial_congestion_window(2 * kMaxInitialWindow,
698 kDefaultInitialWindow);
699 client_config_.set_initial_round_trip_time_us(1, 1);
701 ASSERT_TRUE(Initialize());
702 client_->client()->WaitForCryptoHandshakeConfirmed();
703 server_thread_->WaitForCryptoHandshakeConfirmed();
705 // Pause the server so we can access the server's internals without races.
706 server_thread_->Pause();
707 QuicDispatcher* dispatcher =
708 QuicServerPeer::GetDispatcher(server_thread_->server());
709 ASSERT_EQ(1u, dispatcher->session_map().size());
710 QuicSession* session = dispatcher->session_map().begin()->second;
711 QuicConfig* client_negotiated_config = client_->client()->session()->config();
712 QuicConfig* server_negotiated_config = session->config();
713 const QuicSentPacketManager& client_sent_packet_manager =
714 client_->client()->session()->connection()->sent_packet_manager();
715 const QuicSentPacketManager& server_sent_packet_manager =
716 session->connection()->sent_packet_manager();
718 EXPECT_EQ(kMaxInitialWindow,
719 client_negotiated_config->server_initial_congestion_window());
720 EXPECT_EQ(kMaxInitialWindow,
721 server_negotiated_config->server_initial_congestion_window());
722 // The client shouldn't set it's initial window based on the negotiated value.
723 EXPECT_EQ(kDefaultInitialWindow * kDefaultTCPMSS,
724 client_sent_packet_manager.GetCongestionWindow());
725 EXPECT_EQ(kMaxInitialWindow * kDefaultTCPMSS,
726 server_sent_packet_manager.GetCongestionWindow());
728 EXPECT_EQ(FLAGS_enable_quic_pacing,
729 server_sent_packet_manager.using_pacing());
730 EXPECT_EQ(FLAGS_enable_quic_pacing,
731 client_sent_packet_manager.using_pacing());
733 EXPECT_EQ(1u, client_negotiated_config->initial_round_trip_time_us());
734 EXPECT_EQ(1u, server_negotiated_config->initial_round_trip_time_us());
736 // Now use the negotiated limits with packet loss.
737 SetPacketLossPercentage(30);
741 GenerateBody(&body, 1024 * 10);
743 HTTPMessage request(HttpConstants::HTTP_1_1,
744 HttpConstants::POST, "/foo");
745 request.AddBody(body, true);
747 server_thread_->Resume();
749 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
752 TEST_P(EndToEndTest, InitialRTT) {
753 // Client tries to negotiate twice the server's max and negotiation settles
755 client_config_.set_initial_round_trip_time_us(2 * kMaxInitialRoundTripTimeUs,
758 ASSERT_TRUE(Initialize());
759 client_->client()->WaitForCryptoHandshakeConfirmed();
760 server_thread_->WaitForCryptoHandshakeConfirmed();
762 server_thread_->Pause();
763 QuicDispatcher* dispatcher =
764 QuicServerPeer::GetDispatcher(server_thread_->server());
765 ASSERT_EQ(1u, dispatcher->session_map().size());
766 QuicSession* session = dispatcher->session_map().begin()->second;
767 QuicConfig* client_negotiated_config = client_->client()->session()->config();
768 QuicConfig* server_negotiated_config = session->config();
769 const QuicSentPacketManager& client_sent_packet_manager =
770 client_->client()->session()->connection()->sent_packet_manager();
771 const QuicSentPacketManager& server_sent_packet_manager =
772 session->connection()->sent_packet_manager();
774 EXPECT_EQ(kMaxInitialRoundTripTimeUs,
775 client_negotiated_config->initial_round_trip_time_us());
776 EXPECT_EQ(kMaxInitialRoundTripTimeUs,
777 server_negotiated_config->initial_round_trip_time_us());
778 // Now that acks have been exchanged, the RTT estimate has decreased on the
779 // server and is not infinite on the client.
780 EXPECT_FALSE(client_sent_packet_manager.SmoothedRtt().IsInfinite());
781 EXPECT_GE(static_cast<int64>(kMaxInitialRoundTripTimeUs),
782 server_sent_packet_manager.SmoothedRtt().ToMicroseconds());
783 server_thread_->Resume();
786 TEST_P(EndToEndTest, ResetConnection) {
787 ASSERT_TRUE(Initialize());
788 client_->client()->WaitForCryptoHandshakeConfirmed();
790 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
791 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
792 client_->ResetConnection();
793 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
794 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
797 TEST_P(EndToEndTest, MaxStreamsUberTest) {
798 SetPacketLossPercentage(1);
799 ASSERT_TRUE(Initialize());
801 GenerateBody(&large_body, 10240);
802 int max_streams = 100;
804 AddToCache("GET", "/large_response", "HTTP/1.1", "200", "OK", large_body);;
806 client_->client()->WaitForCryptoHandshakeConfirmed();
807 SetPacketLossPercentage(10);
809 for (int i = 0; i < max_streams; ++i) {
810 EXPECT_LT(0, client_->SendRequest("/large_response"));
813 // WaitForEvents waits 50ms and returns true if there are outstanding
815 while (client_->client()->WaitForEvents() == true) {
819 TEST_P(EndToEndTest, StreamCancelErrorTest) {
820 ASSERT_TRUE(Initialize());
822 GenerateBody(&small_body, 256);
824 AddToCache("GET", "/small_response", "HTTP/1.1", "200", "OK", small_body);
826 client_->client()->WaitForCryptoHandshakeConfirmed();
828 QuicSession* session = client_->client()->session();
830 SetPacketLossPercentage(100);
831 EXPECT_LT(0, client_->SendRequest("/small_response"));
832 client_->client()->WaitForEvents();
833 // Transmit the cancel, and ensure the connection is torn down properly.
834 SetPacketLossPercentage(0);
835 QuicStreamId stream_id = negotiated_version_ > QUIC_VERSION_12 ? 5 : 3;
836 session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0);
838 // WaitForEvents waits 50ms and returns true if there are outstanding
840 while (client_->client()->WaitForEvents() == true) {
842 if (negotiated_version_ > QUIC_VERSION_12) {
843 // It should be completely fine to RST a stream before any data has bee
844 // received for that stream.
845 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
847 // Check that the connection is always properly closed
848 // from a stream being RST before headers are decompressed.
849 EXPECT_EQ(QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED,
850 client_->connection_error());
854 class WrongAddressWriter : public QuicPacketWriterWrapper {
856 WrongAddressWriter() {
858 CHECK(net::ParseIPLiteralToNumber("127.0.0.2", &ip));
859 self_address_ = IPEndPoint(ip, 0);
862 virtual WriteResult WritePacket(
865 const IPAddressNumber& real_self_address,
866 const IPEndPoint& peer_address) OVERRIDE {
867 // Use wrong address!
868 return QuicPacketWriterWrapper::WritePacket(
869 buffer, buf_len, self_address_.address(), peer_address);
872 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE {
876 IPEndPoint self_address_;
879 TEST_P(EndToEndTest, ConnectionMigration) {
880 ASSERT_TRUE(Initialize());
882 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
883 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
885 scoped_ptr<WrongAddressWriter> writer(new WrongAddressWriter());
887 writer->set_writer(new QuicDefaultPacketWriter(
888 QuicClientPeer::GetFd(client_->client())));
889 QuicConnectionPeer::SetWriter(client_->client()->session()->connection(),
892 client_->SendSynchronousRequest("/bar");
894 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
895 EXPECT_EQ(QUIC_ERROR_MIGRATING_ADDRESS, client_->connection_error());