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 <vector>
8
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/singleton.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "net/base/ip_endpoint.h"
14 #include "net/quic/congestion_control/tcp_cubic_sender.h"
15 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
16 #include "net/quic/crypto/null_encrypter.h"
17 #include "net/quic/quic_framer.h"
18 #include "net/quic/quic_packet_creator.h"
19 #include "net/quic/quic_protocol.h"
20 #include "net/quic/quic_sent_packet_manager.h"
21 #include "net/quic/test_tools/quic_connection_peer.h"
22 #include "net/quic/test_tools/quic_session_peer.h"
23 #include "net/quic/test_tools/quic_test_writer.h"
24 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
25 #include "net/tools/quic/quic_epoll_connection_helper.h"
26 #include "net/tools/quic/quic_in_memory_cache.h"
27 #include "net/tools/quic/quic_server.h"
28 #include "net/tools/quic/quic_socket_utils.h"
29 #include "net/tools/quic/quic_spdy_client_stream.h"
30 #include "net/tools/quic/test_tools/http_message_test_utils.h"
31 #include "net/tools/quic/test_tools/packet_dropping_test_writer.h"
32 #include "net/tools/quic/test_tools/quic_client_peer.h"
33 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h"
34 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
35 #include "net/tools/quic/test_tools/quic_server_peer.h"
36 #include "net/tools/quic/test_tools/quic_test_client.h"
37 #include "net/tools/quic/test_tools/server_thread.h"
38 #include "testing/gtest/include/gtest/gtest.h"
39
40 using base::StringPiece;
41 using base::WaitableEvent;
42 using net::test::QuicConnectionPeer;
43 using net::test::QuicSessionPeer;
44 using net::test::QuicTestWriter;
45 using net::test::ReliableQuicStreamPeer;
46 using net::tools::test::PacketDroppingTestWriter;
47 using net::tools::test::QuicDispatcherPeer;
48 using net::tools::test::QuicServerPeer;
49 using std::ostream;
50 using std::string;
51 using std::vector;
52
53 namespace net {
54 namespace tools {
55 namespace test {
56 namespace {
57
58 const char* kFooResponseBody = "Artichoke hearts make me happy.";
59 const char* kBarResponseBody = "Palm hearts are pretty delicious, also.";
60
GenerateBody(string * body,int length)61 void GenerateBody(string* body, int length) {
62 body->clear();
63 body->reserve(length);
64 for (int i = 0; i < length; ++i) {
65 body->append(1, static_cast<char>(32 + i % (126 - 32)));
66 }
67 }
68
69 // Run all tests with the cross products of all versions.
70 struct TestParams {
TestParamsnet::tools::test::__anonef09232e0111::TestParams71 TestParams(const QuicVersionVector& client_supported_versions,
72 const QuicVersionVector& server_supported_versions,
73 QuicVersion negotiated_version,
74 bool use_pacing)
75 : client_supported_versions(client_supported_versions),
76 server_supported_versions(server_supported_versions),
77 negotiated_version(negotiated_version),
78 use_pacing(use_pacing) {
79 }
80
operator <<(ostream & os,const TestParams & p)81 friend ostream& operator<<(ostream& os, const TestParams& p) {
82 os << "{ server_supported_versions: "
83 << QuicVersionVectorToString(p.server_supported_versions);
84 os << " client_supported_versions: "
85 << QuicVersionVectorToString(p.client_supported_versions);
86 os << " negotiated_version: " << QuicVersionToString(p.negotiated_version);
87 os << " use_pacing: " << p.use_pacing << " }";
88 return os;
89 }
90
91 QuicVersionVector client_supported_versions;
92 QuicVersionVector server_supported_versions;
93 QuicVersion negotiated_version;
94 bool use_pacing;
95 };
96
97 // Constructs various test permutations.
GetTestParams()98 vector<TestParams> GetTestParams() {
99 vector<TestParams> params;
100 QuicVersionVector all_supported_versions = QuicSupportedVersions();
101
102 for (int use_pacing = 0; use_pacing < 2; ++use_pacing) {
103 // Add an entry for server and client supporting all versions.
104 params.push_back(TestParams(all_supported_versions,
105 all_supported_versions,
106 all_supported_versions[0],
107 use_pacing != 0));
108
109 // Test client supporting 1 version and server supporting all versions.
110 // Simulate an old client and exercise version downgrade in the server.
111 // No protocol negotiation should occur. Skip the i = 0 case because it
112 // is essentially the same as the default case.
113 for (size_t i = 1; i < all_supported_versions.size(); ++i) {
114 QuicVersionVector client_supported_versions;
115 client_supported_versions.push_back(all_supported_versions[i]);
116 params.push_back(TestParams(client_supported_versions,
117 all_supported_versions,
118 client_supported_versions[0],
119 use_pacing != 0));
120 }
121
122 // Test client supporting all versions and server supporting 1 version.
123 // Simulate an old server and exercise version downgrade in the client.
124 // Protocol negotiation should occur. Skip the i = 0 case because it is
125 // essentially the same as the default case.
126 for (size_t i = 1; i < all_supported_versions.size(); ++i) {
127 QuicVersionVector server_supported_versions;
128 server_supported_versions.push_back(all_supported_versions[i]);
129 params.push_back(TestParams(all_supported_versions,
130 server_supported_versions,
131 server_supported_versions[0],
132 use_pacing != 0));
133 }
134 }
135 return params;
136 }
137
138 class EndToEndTest : public ::testing::TestWithParam<TestParams> {
139 protected:
EndToEndTest()140 EndToEndTest()
141 : server_hostname_("example.com"),
142 server_started_(false),
143 strike_register_no_startup_period_(false) {
144 net::IPAddressNumber ip;
145 CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip));
146 server_address_ = IPEndPoint(ip, 0);
147
148 client_supported_versions_ = GetParam().client_supported_versions;
149 server_supported_versions_ = GetParam().server_supported_versions;
150 negotiated_version_ = GetParam().negotiated_version;
151 FLAGS_limit_rto_increase_for_tests = true;
152 FLAGS_enable_quic_pacing = GetParam().use_pacing;
153 LOG(INFO) << "Using Configuration: " << GetParam();
154
155 client_config_.SetDefaults();
156 server_config_.SetDefaults();
157 server_config_.set_initial_round_trip_time_us(kMaxInitialRoundTripTimeUs,
158 0);
159
160 QuicInMemoryCachePeer::ResetForTests();
161 AddToCache("GET", "https://www.google.com/foo",
162 "HTTP/1.1", "200", "OK", kFooResponseBody);
163 AddToCache("GET", "https://www.google.com/bar",
164 "HTTP/1.1", "200", "OK", kBarResponseBody);
165 }
166
~EndToEndTest()167 virtual ~EndToEndTest() {
168 // TODO(rtenneti): port RecycleUnusedPort if needed.
169 // RecycleUnusedPort(server_address_.port());
170 QuicInMemoryCachePeer::ResetForTests();
171 }
172
CreateQuicClient(QuicTestWriter * writer)173 virtual QuicTestClient* CreateQuicClient(QuicTestWriter* writer) {
174 QuicTestClient* client = new QuicTestClient(server_address_,
175 server_hostname_,
176 false, // not secure
177 client_config_,
178 client_supported_versions_);
179 client->UseWriter(writer);
180 client->Connect();
181 return client;
182 }
183
Initialize()184 virtual bool Initialize() {
185 // Start the server first, because CreateQuicClient() attempts
186 // to connect to the server.
187 StartServer();
188 client_.reset(CreateQuicClient(client_writer_));
189 QuicEpollConnectionHelper* helper =
190 reinterpret_cast<QuicEpollConnectionHelper*>(
191 QuicConnectionPeer::GetHelper(
192 client_->client()->session()->connection()));
193 client_writer_->SetConnectionHelper(helper);
194 return client_->client()->connected();
195 }
196
SetUp()197 virtual void SetUp() {
198 // The ownership of these gets transferred to the QuicTestWriter and
199 // QuicDispatcher when Initialize() is executed.
200 client_writer_ = new PacketDroppingTestWriter();
201 server_writer_ = new PacketDroppingTestWriter();
202 }
203
TearDown()204 virtual void TearDown() {
205 StopServer();
206 }
207
StartServer()208 void StartServer() {
209 server_thread_.reset(new ServerThread(server_address_, server_config_,
210 server_supported_versions_,
211 strike_register_no_startup_period_));
212 server_thread_->Start();
213 server_thread_->WaitForServerStartup();
214 server_address_ = IPEndPoint(server_address_.address(),
215 server_thread_->GetPort());
216 QuicDispatcher* dispatcher =
217 QuicServerPeer::GetDispatcher(server_thread_->server());
218 server_writer_->SetConnectionHelper(
219 QuicDispatcherPeer::GetHelper(dispatcher));
220 QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
221 server_started_ = true;
222 }
223
StopServer()224 void StopServer() {
225 if (!server_started_)
226 return;
227 if (server_thread_.get()) {
228 server_thread_->Quit();
229 server_thread_->Join();
230 }
231 }
232
AddToCache(StringPiece method,StringPiece path,StringPiece version,StringPiece response_code,StringPiece response_detail,StringPiece body)233 void AddToCache(StringPiece method,
234 StringPiece path,
235 StringPiece version,
236 StringPiece response_code,
237 StringPiece response_detail,
238 StringPiece body) {
239 QuicInMemoryCache::GetInstance()->AddSimpleResponse(
240 method, path, version, response_code, response_detail, body);
241 }
242
SetPacketLossPercentage(int32 loss)243 void SetPacketLossPercentage(int32 loss) {
244 // TODO(rtenneti): enable when we can do random packet loss tests in
245 // chrome's tree.
246 // client_writer_->set_fake_packet_loss_percentage(loss);
247 // server_writer_->set_fake_packet_loss_percentage(loss);
248 }
249
SetPacketSendDelay(QuicTime::Delta delay)250 void SetPacketSendDelay(QuicTime::Delta delay) {
251 // TODO(rtenneti): enable when we can do random packet send delay tests in
252 // chrome's tree.
253 // client_writer_->set_fake_packet_delay(delay);
254 // server_writer_->set_fake_packet_delay(delay);
255 }
256
SetReorderPercentage(int32 reorder)257 void SetReorderPercentage(int32 reorder) {
258 // TODO(rtenneti): enable when we can do random packet reorder tests in
259 // chrome's tree.
260 // client_writer_->set_fake_reorder_percentage(reorder);
261 // server_writer_->set_fake_reorder_percentage(reorder);
262 }
263
264 IPEndPoint server_address_;
265 string server_hostname_;
266 scoped_ptr<ServerThread> server_thread_;
267 scoped_ptr<QuicTestClient> client_;
268 PacketDroppingTestWriter* client_writer_;
269 PacketDroppingTestWriter* server_writer_;
270 bool server_started_;
271 QuicConfig client_config_;
272 QuicConfig server_config_;
273 QuicVersionVector client_supported_versions_;
274 QuicVersionVector server_supported_versions_;
275 QuicVersion negotiated_version_;
276 bool strike_register_no_startup_period_;
277 };
278
279 // Run all end to end tests with all supported versions.
280 INSTANTIATE_TEST_CASE_P(EndToEndTests,
281 EndToEndTest,
282 ::testing::ValuesIn(GetTestParams()));
283
TEST_P(EndToEndTest,SimpleRequestResponse)284 TEST_P(EndToEndTest, SimpleRequestResponse) {
285 ASSERT_TRUE(Initialize());
286
287 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
288 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
289 }
290
291 // TODO(rch): figure out how to detect missing v6 supprt (like on the linux
292 // try bots) and selectively disable this test.
TEST_P(EndToEndTest,DISABLED_SimpleRequestResponsev6)293 TEST_P(EndToEndTest, DISABLED_SimpleRequestResponsev6) {
294 IPAddressNumber ip;
295 CHECK(net::ParseIPLiteralToNumber("::1", &ip));
296 server_address_ = IPEndPoint(ip, server_address_.port());
297 ASSERT_TRUE(Initialize());
298
299 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
300 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
301 }
302
TEST_P(EndToEndTest,SeparateFinPacket)303 TEST_P(EndToEndTest, SeparateFinPacket) {
304 ASSERT_TRUE(Initialize());
305
306 HTTPMessage request(HttpConstants::HTTP_1_1,
307 HttpConstants::POST, "/foo");
308 request.set_has_complete_message(false);
309
310 client_->SendMessage(request);
311
312 client_->SendData(string(), true);
313
314 client_->WaitForResponse();
315 EXPECT_EQ(kFooResponseBody, client_->response_body());
316 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
317
318 request.AddBody("foo", true);
319
320 client_->SendMessage(request);
321 client_->SendData(string(), true);
322 client_->WaitForResponse();
323 EXPECT_EQ(kFooResponseBody, client_->response_body());
324 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
325 }
326
TEST_P(EndToEndTest,MultipleRequestResponse)327 TEST_P(EndToEndTest, MultipleRequestResponse) {
328 ASSERT_TRUE(Initialize());
329
330 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
331 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
332 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
333 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
334 }
335
TEST_P(EndToEndTest,MultipleClients)336 TEST_P(EndToEndTest, MultipleClients) {
337 ASSERT_TRUE(Initialize());
338 scoped_ptr<QuicTestClient> client2(CreateQuicClient(NULL));
339
340 HTTPMessage request(HttpConstants::HTTP_1_1,
341 HttpConstants::POST, "/foo");
342 request.AddHeader("content-length", "3");
343 request.set_has_complete_message(false);
344
345 client_->SendMessage(request);
346 client2->SendMessage(request);
347
348 client_->SendData("bar", true);
349 client_->WaitForResponse();
350 EXPECT_EQ(kFooResponseBody, client_->response_body());
351 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
352
353 client2->SendData("eep", true);
354 client2->WaitForResponse();
355 EXPECT_EQ(kFooResponseBody, client2->response_body());
356 EXPECT_EQ(200u, client2->response_headers()->parsed_response_code());
357 }
358
TEST_P(EndToEndTest,RequestOverMultiplePackets)359 TEST_P(EndToEndTest, RequestOverMultiplePackets) {
360 // Send a large enough request to guarantee fragmentation.
361 string huge_request =
362 "https://www.google.com/some/path?query=" + string(kMaxPacketSize, '.');
363 AddToCache("GET", huge_request, "HTTP/1.1", "200", "OK", kBarResponseBody);
364
365 ASSERT_TRUE(Initialize());
366
367 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
368 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
369 }
370
TEST_P(EndToEndTest,MultiplePacketsRandomOrder)371 TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
372 // Send a large enough request to guarantee fragmentation.
373 string huge_request =
374 "https://www.google.com/some/path?query=" + string(kMaxPacketSize, '.');
375 AddToCache("GET", huge_request, "HTTP/1.1", "200", "OK", kBarResponseBody);
376
377 ASSERT_TRUE(Initialize());
378 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
379 SetReorderPercentage(50);
380
381 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
382 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
383 }
384
TEST_P(EndToEndTest,PostMissingBytes)385 TEST_P(EndToEndTest, PostMissingBytes) {
386 ASSERT_TRUE(Initialize());
387
388 // Add a content length header with no body.
389 HTTPMessage request(HttpConstants::HTTP_1_1,
390 HttpConstants::POST, "/foo");
391 request.AddHeader("content-length", "3");
392 request.set_skip_message_validation(true);
393
394 // This should be detected as stream fin without complete request,
395 // triggering an error response.
396 client_->SendCustomSynchronousRequest(request);
397 EXPECT_EQ("bad", client_->response_body());
398 EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
399 }
400
TEST_P(EndToEndTest,LargePostNoPacketLoss)401 TEST_P(EndToEndTest, LargePostNoPacketLoss) {
402 ASSERT_TRUE(Initialize());
403
404 client_->client()->WaitForCryptoHandshakeConfirmed();
405
406 // 1 Mb body.
407 string body;
408 GenerateBody(&body, 1024 * 1024);
409
410 HTTPMessage request(HttpConstants::HTTP_1_1,
411 HttpConstants::POST, "/foo");
412 request.AddBody(body, true);
413
414 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
415 }
416
TEST_P(EndToEndTest,LargePostWithPacketLoss)417 TEST_P(EndToEndTest, LargePostWithPacketLoss) {
418 // Connect with lower fake packet loss than we'd like to test. Until
419 // b/10126687 is fixed, losing handshake packets is pretty brutal.
420 SetPacketLossPercentage(5);
421 ASSERT_TRUE(Initialize());
422
423 // Wait for the server SHLO before upping the packet loss.
424 client_->client()->WaitForCryptoHandshakeConfirmed();
425 SetPacketLossPercentage(30);
426
427 // 10 Kb body.
428 string body;
429 GenerateBody(&body, 1024 * 10);
430
431 HTTPMessage request(HttpConstants::HTTP_1_1,
432 HttpConstants::POST, "/foo");
433 request.AddBody(body, true);
434
435 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
436 }
437
TEST_P(EndToEndTest,LargePostNoPacketLossWithDelayAndReordering)438 TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
439 ASSERT_TRUE(Initialize());
440
441 client_->client()->WaitForCryptoHandshakeConfirmed();
442 // Both of these must be called when the writer is not actively used.
443 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
444 SetReorderPercentage(30);
445
446 // 1 Mb body.
447 string body;
448 GenerateBody(&body, 1024 * 1024);
449
450 HTTPMessage request(HttpConstants::HTTP_1_1,
451 HttpConstants::POST, "/foo");
452 request.AddBody(body, true);
453
454 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
455 }
456
TEST_P(EndToEndTest,LargePostWithPacketLossAndBlocketSocket)457 TEST_P(EndToEndTest, LargePostWithPacketLossAndBlocketSocket) {
458 // Connect with lower fake packet loss than we'd like to test. Until
459 // b/10126687 is fixed, losing handshake packets is pretty brutal.
460 SetPacketLossPercentage(5);
461 ASSERT_TRUE(Initialize());
462
463 // Wait for the server SHLO before upping the packet loss.
464 client_->client()->WaitForCryptoHandshakeConfirmed();
465 SetPacketLossPercentage(30);
466 client_writer_->set_fake_blocked_socket_percentage(10);
467
468 // 10 Kb body.
469 string body;
470 GenerateBody(&body, 1024 * 10);
471
472 HTTPMessage request(HttpConstants::HTTP_1_1,
473 HttpConstants::POST, "/foo");
474 request.AddBody(body, true);
475
476 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
477 }
478
479 // TODO(rtenneti): rch is investigating the root cause. Will enable after we
480 // find the bug.
TEST_P(EndToEndTest,DISABLED_LargePostZeroRTTFailure)481 TEST_P(EndToEndTest, DISABLED_LargePostZeroRTTFailure) {
482 // Have the server accept 0-RTT without waiting a startup period.
483 strike_register_no_startup_period_ = true;
484
485 // Send a request and then disconnect. This prepares the client to attempt
486 // a 0-RTT handshake for the next request.
487 ASSERT_TRUE(Initialize());
488
489 string body;
490 GenerateBody(&body, 20480);
491
492 HTTPMessage request(HttpConstants::HTTP_1_1,
493 HttpConstants::POST, "/foo");
494 request.AddBody(body, true);
495
496 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
497 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos());
498
499 client_->Disconnect();
500
501 // The 0-RTT handshake should succeed.
502 client_->Connect();
503 client_->WaitForResponseForMs(-1);
504 ASSERT_TRUE(client_->client()->connected());
505 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
506 EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
507
508 client_->Disconnect();
509
510 // Restart the server so that the 0-RTT handshake will take 1 RTT.
511 StopServer();
512 server_writer_ = new PacketDroppingTestWriter();
513 StartServer();
514
515 client_->Connect();
516 ASSERT_TRUE(client_->client()->connected());
517 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
518 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos());
519 }
520
521 // TODO(ianswett): Enable once b/9295090 is fixed.
TEST_P(EndToEndTest,DISABLED_LargePostFEC)522 TEST_P(EndToEndTest, DISABLED_LargePostFEC) {
523 SetPacketLossPercentage(30);
524 ASSERT_TRUE(Initialize());
525 client_->options()->max_packets_per_fec_group = 6;
526
527 string body;
528 GenerateBody(&body, 10240);
529
530 HTTPMessage request(HttpConstants::HTTP_1_1,
531 HttpConstants::POST, "/foo");
532 request.AddBody(body, true);
533
534 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
535 }
536
TEST_P(EndToEndTest,LargePostLargeBuffer)537 TEST_P(EndToEndTest, LargePostLargeBuffer) {
538 ASSERT_TRUE(Initialize());
539 SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
540 // 1Mbit per second with a 128k buffer from server to client. Wireless
541 // clients commonly have larger buffers, but our max CWND is 200.
542 server_writer_->set_max_bandwidth_and_buffer_size(
543 QuicBandwidth::FromBytesPerSecond(256 * 1024), 128 * 1024);
544
545 client_->client()->WaitForCryptoHandshakeConfirmed();
546
547 // 1 Mb body.
548 string body;
549 GenerateBody(&body, 1024 * 1024);
550
551 HTTPMessage request(HttpConstants::HTTP_1_1,
552 HttpConstants::POST, "/foo");
553 request.AddBody(body, true);
554
555 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
556 }
557
TEST_P(EndToEndTest,InvalidStream)558 TEST_P(EndToEndTest, InvalidStream) {
559 ASSERT_TRUE(Initialize());
560 client_->client()->WaitForCryptoHandshakeConfirmed();
561
562 string body;
563 GenerateBody(&body, kMaxPacketSize);
564
565 HTTPMessage request(HttpConstants::HTTP_1_1,
566 HttpConstants::POST, "/foo");
567 request.AddBody(body, true);
568 // Force the client to write with a stream ID belonging to a nonexistent
569 // server-side stream.
570 QuicSessionPeer::SetNextStreamId(client_->client()->session(), 2);
571
572 client_->SendCustomSynchronousRequest(request);
573 // EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
574 EXPECT_EQ(QUIC_PACKET_FOR_NONEXISTENT_STREAM, client_->connection_error());
575 }
576
577 // TODO(rch): this test seems to cause net_unittests timeouts :|
TEST_P(EndToEndTest,DISABLED_MultipleTermination)578 TEST_P(EndToEndTest, DISABLED_MultipleTermination) {
579 ASSERT_TRUE(Initialize());
580
581 HTTPMessage request(HttpConstants::HTTP_1_1,
582 HttpConstants::POST, "/foo");
583 request.AddHeader("content-length", "3");
584 request.set_has_complete_message(false);
585
586 // Set the offset so we won't frame. Otherwise when we pick up termination
587 // before HTTP framing is complete, we send an error and close the stream,
588 // and the second write is picked up as writing on a closed stream.
589 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
590 ASSERT_TRUE(stream != NULL);
591 ReliableQuicStreamPeer::SetStreamBytesWritten(3, stream);
592
593 client_->SendData("bar", true);
594 client_->WaitForWriteToFlush();
595
596 // By default the stream protects itself from writes after terminte is set.
597 // Override this to test the server handling buggy clients.
598 ReliableQuicStreamPeer::SetWriteSideClosed(
599 false, client_->GetOrCreateStream());
600
601 #if !defined(WIN32) && defined(GTEST_HAS_DEATH_TEST)
602 #if !defined(DCHECK_ALWAYS_ON)
603 EXPECT_DEBUG_DEATH({
604 client_->SendData("eep", true);
605 client_->WaitForResponse();
606 EXPECT_EQ(QUIC_MULTIPLE_TERMINATION_OFFSETS, client_->stream_error());
607 },
608 "Check failed: !fin_buffered_");
609 #else
610 EXPECT_DEATH({
611 client_->SendData("eep", true);
612 client_->WaitForResponse();
613 EXPECT_EQ(QUIC_MULTIPLE_TERMINATION_OFFSETS, client_->stream_error());
614 },
615 "Check failed: !fin_buffered_");
616 #endif
617 #endif
618 }
619
TEST_P(EndToEndTest,Timeout)620 TEST_P(EndToEndTest, Timeout) {
621 client_config_.set_idle_connection_state_lifetime(
622 QuicTime::Delta::FromMicroseconds(500),
623 QuicTime::Delta::FromMicroseconds(500));
624 // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
625 // that's enough to validate timeout in this case.
626 Initialize();
627 while (client_->client()->connected()) {
628 client_->client()->WaitForEvents();
629 }
630 }
631
TEST_P(EndToEndTest,LimitMaxOpenStreams)632 TEST_P(EndToEndTest, LimitMaxOpenStreams) {
633 // Server limits the number of max streams to 2.
634 server_config_.set_max_streams_per_connection(2, 2);
635 // Client tries to negotiate for 10.
636 client_config_.set_max_streams_per_connection(10, 5);
637
638 ASSERT_TRUE(Initialize());
639 client_->client()->WaitForCryptoHandshakeConfirmed();
640 QuicConfig* client_negotiated_config = client_->client()->session()->config();
641 EXPECT_EQ(2u, client_negotiated_config->max_streams_per_connection());
642 }
643
644 // TODO(rtenneti): DISABLED_LimitCongestionWindowAndRTT seems to be flaky.
645 // http://crbug.com/321870.
TEST_P(EndToEndTest,DISABLED_LimitCongestionWindowAndRTT)646 TEST_P(EndToEndTest, DISABLED_LimitCongestionWindowAndRTT) {
647 server_config_.set_server_initial_congestion_window(kMaxInitialWindow,
648 kDefaultInitialWindow);
649 // Client tries to negotiate twice the server's max and negotiation settles
650 // on the max.
651 client_config_.set_server_initial_congestion_window(2 * kMaxInitialWindow,
652 kDefaultInitialWindow);
653 client_config_.set_initial_round_trip_time_us(1, 1);
654
655 ASSERT_TRUE(Initialize());
656 client_->client()->WaitForCryptoHandshakeConfirmed();
657 server_thread_->WaitForCryptoHandshakeConfirmed();
658
659 // Pause the server so we can access the server's internals without races.
660 server_thread_->Pause();
661 QuicDispatcher* dispatcher =
662 QuicServerPeer::GetDispatcher(server_thread_->server());
663 ASSERT_EQ(1u, dispatcher->session_map().size());
664 QuicSession* session = dispatcher->session_map().begin()->second;
665 QuicConfig* client_negotiated_config = client_->client()->session()->config();
666 QuicConfig* server_negotiated_config = session->config();
667 const QuicSentPacketManager& client_sent_packet_manager =
668 client_->client()->session()->connection()->sent_packet_manager();
669 const QuicSentPacketManager& server_sent_packet_manager =
670 session->connection()->sent_packet_manager();
671
672 EXPECT_EQ(kMaxInitialWindow,
673 client_negotiated_config->server_initial_congestion_window());
674 EXPECT_EQ(kMaxInitialWindow,
675 server_negotiated_config->server_initial_congestion_window());
676 // The client shouldn't set it's initial window based on the negotiated value.
677 EXPECT_EQ(kDefaultInitialWindow * kDefaultTCPMSS,
678 client_sent_packet_manager.GetCongestionWindow());
679 EXPECT_EQ(kMaxInitialWindow * kDefaultTCPMSS,
680 server_sent_packet_manager.GetCongestionWindow());
681
682 EXPECT_EQ(FLAGS_enable_quic_pacing,
683 server_sent_packet_manager.using_pacing());
684 EXPECT_EQ(FLAGS_enable_quic_pacing,
685 client_sent_packet_manager.using_pacing());
686
687 EXPECT_EQ(1u, client_negotiated_config->initial_round_trip_time_us());
688 EXPECT_EQ(1u, server_negotiated_config->initial_round_trip_time_us());
689
690 // Now use the negotiated limits with packet loss.
691 SetPacketLossPercentage(30);
692
693 // 10 Kb body.
694 string body;
695 GenerateBody(&body, 1024 * 10);
696
697 HTTPMessage request(HttpConstants::HTTP_1_1,
698 HttpConstants::POST, "/foo");
699 request.AddBody(body, true);
700
701 server_thread_->Resume();
702
703 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
704 }
705
TEST_P(EndToEndTest,InitialRTT)706 TEST_P(EndToEndTest, InitialRTT) {
707 // Client tries to negotiate twice the server's max and negotiation settles
708 // on the max.
709 client_config_.set_initial_round_trip_time_us(2 * kMaxInitialRoundTripTimeUs,
710 0);
711
712 ASSERT_TRUE(Initialize());
713 client_->client()->WaitForCryptoHandshakeConfirmed();
714 server_thread_->WaitForCryptoHandshakeConfirmed();
715
716 // Pause the server so we can access the server's internals without races.
717 server_thread_->Pause();
718 QuicDispatcher* dispatcher =
719 QuicServerPeer::GetDispatcher(server_thread_->server());
720 ASSERT_EQ(1u, dispatcher->session_map().size());
721 QuicSession* session = dispatcher->session_map().begin()->second;
722 QuicConfig* client_negotiated_config = client_->client()->session()->config();
723 QuicConfig* server_negotiated_config = session->config();
724 const QuicSentPacketManager& client_sent_packet_manager =
725 client_->client()->session()->connection()->sent_packet_manager();
726 const QuicSentPacketManager& server_sent_packet_manager =
727 session->connection()->sent_packet_manager();
728
729 EXPECT_EQ(kMaxInitialRoundTripTimeUs,
730 client_negotiated_config->initial_round_trip_time_us());
731 EXPECT_EQ(kMaxInitialRoundTripTimeUs,
732 server_negotiated_config->initial_round_trip_time_us());
733 // Now that acks have been exchanged, the RTT estimate has decreased on the
734 // server and is not infinite on the client.
735 EXPECT_FALSE(client_sent_packet_manager.SmoothedRtt().IsInfinite());
736 EXPECT_GE(static_cast<int64>(kMaxInitialRoundTripTimeUs),
737 server_sent_packet_manager.SmoothedRtt().ToMicroseconds());
738 }
739
TEST_P(EndToEndTest,ResetConnection)740 TEST_P(EndToEndTest, ResetConnection) {
741 ASSERT_TRUE(Initialize());
742 client_->client()->WaitForCryptoHandshakeConfirmed();
743
744 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
745 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
746 client_->ResetConnection();
747 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
748 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
749 }
750
TEST_P(EndToEndTest,MaxStreamsUberTest)751 TEST_P(EndToEndTest, MaxStreamsUberTest) {
752 SetPacketLossPercentage(1);
753 ASSERT_TRUE(Initialize());
754 string large_body;
755 GenerateBody(&large_body, 10240);
756 int max_streams = 100;
757
758 AddToCache("GET", "/large_response", "HTTP/1.1", "200", "OK", large_body);;
759
760 client_->client()->WaitForCryptoHandshakeConfirmed();
761 SetPacketLossPercentage(10);
762
763 for (int i = 0; i < max_streams; ++i) {
764 EXPECT_LT(0, client_->SendRequest("/large_response"));
765 }
766
767 // WaitForEvents waits 50ms and returns true if there are outstanding
768 // requests.
769 while (client_->client()->WaitForEvents() == true) {
770 }
771 }
772
773 class WrongAddressWriter : public QuicTestWriter {
774 public:
WrongAddressWriter()775 WrongAddressWriter() {
776 IPAddressNumber ip;
777 CHECK(net::ParseIPLiteralToNumber("127.0.0.2", &ip));
778 self_address_ = IPEndPoint(ip, 0);
779 }
780
WritePacket(const char * buffer,size_t buf_len,const IPAddressNumber & real_self_address,const IPEndPoint & peer_address,QuicBlockedWriterInterface * blocked_writer)781 virtual WriteResult WritePacket(
782 const char* buffer, size_t buf_len,
783 const IPAddressNumber& real_self_address,
784 const IPEndPoint& peer_address,
785 QuicBlockedWriterInterface* blocked_writer) OVERRIDE {
786 return writer()->WritePacket(buffer, buf_len, self_address_.address(),
787 peer_address, blocked_writer);
788 }
789
IsWriteBlockedDataBuffered() const790 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE {
791 return false;
792 }
793
794 IPEndPoint self_address_;
795 };
796
TEST_P(EndToEndTest,ConnectionMigration)797 TEST_P(EndToEndTest, ConnectionMigration) {
798 ASSERT_TRUE(Initialize());
799
800 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
801 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
802
803 scoped_ptr<WrongAddressWriter> writer(new WrongAddressWriter());
804
805 writer->set_writer(new QuicDefaultPacketWriter(
806 QuicClientPeer::GetFd(client_->client())));
807 QuicConnectionPeer::SetWriter(client_->client()->session()->connection(),
808 writer.get());
809
810 client_->SendSynchronousRequest("/bar");
811
812 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
813 EXPECT_EQ(QUIC_ERROR_MIGRATING_ADDRESS, client_->connection_error());
814 }
815
816 } // namespace
817 } // namespace test
818 } // namespace tools
819 } // namespace net
820