Land Recent QUIC changes.
[chromium-blink-merge.git] / net / tools / quic / end_to_end_test.cc
blobf29989a839f6af8c3072f6eb70c06a95d4833d8b
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.
5 #include <stddef.h>
6 #include <string>
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/singleton.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
14 #include "net/quic/crypto/null_encrypter.h"
15 #include "net/quic/quic_framer.h"
16 #include "net/quic/quic_packet_creator.h"
17 #include "net/quic/quic_protocol.h"
18 #include "net/quic/test_tools/quic_connection_peer.h"
19 #include "net/quic/test_tools/quic_session_peer.h"
20 #include "net/quic/test_tools/quic_test_writer.h"
21 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
22 #include "net/tools/quic/quic_epoll_connection_helper.h"
23 #include "net/tools/quic/quic_in_memory_cache.h"
24 #include "net/tools/quic/quic_server.h"
25 #include "net/tools/quic/quic_socket_utils.h"
26 #include "net/tools/quic/test_tools/http_message_test_utils.h"
27 #include "net/tools/quic/test_tools/packet_dropping_test_writer.h"
28 #include "net/tools/quic/test_tools/quic_client_peer.h"
29 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h"
30 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
31 #include "net/tools/quic/test_tools/quic_server_peer.h"
32 #include "net/tools/quic/test_tools/quic_test_client.h"
33 #include "net/tools/quic/test_tools/server_thread.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 using base::StringPiece;
37 using base::WaitableEvent;
38 using net::test::QuicConnectionPeer;
39 using net::test::QuicSessionPeer;
40 using net::test::QuicTestWriter;
41 using net::test::ReliableQuicStreamPeer;
42 using net::tools::test::PacketDroppingTestWriter;
43 using net::tools::test::QuicDispatcherPeer;
44 using net::tools::test::QuicServerPeer;
45 using std::string;
47 namespace net {
48 namespace tools {
49 namespace test {
50 namespace {
52 const char* kFooResponseBody = "Artichoke hearts make me happy.";
53 const char* kBarResponseBody = "Palm hearts are pretty delicious, also.";
54 const size_t kCongestionFeedbackFrameSize = 25;
55 // If kCongestionFeedbackFrameSize increase we need to expand this string
56 // accordingly.
57 const char* kLargeRequest =
58 "https://www.google.com/foo/test/a/request/string/longer/than/25/bytes";
60 void GenerateBody(string* body, int length) {
61 body->clear();
62 body->reserve(length);
63 for (int i = 0; i < length; ++i) {
64 body->append(1, static_cast<char>(32 + i % (126 - 32)));
68 class EndToEndTest : public ::testing::TestWithParam<QuicVersion> {
69 protected:
70 EndToEndTest()
71 : server_hostname_("example.com"),
72 server_started_(false),
73 strike_register_no_startup_period_(false) {
74 net::IPAddressNumber ip;
75 CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip));
76 server_address_ = IPEndPoint(ip, 0);
77 QuicConnection::g_acks_do_not_instigate_acks = true;
78 FLAGS_track_retransmission_history = true;
79 client_config_.SetDefaults();
80 server_config_.SetDefaults();
82 QuicInMemoryCachePeer::ResetForTests();
83 AddToCache("GET", kLargeRequest, "HTTP/1.1", "200", "OK", kFooResponseBody);
84 AddToCache("GET", "https://www.google.com/foo",
85 "HTTP/1.1", "200", "OK", kFooResponseBody);
86 AddToCache("GET", "https://www.google.com/bar",
87 "HTTP/1.1", "200", "OK", kBarResponseBody);
88 version_ = GetParam();
91 virtual ~EndToEndTest() {
92 QuicInMemoryCachePeer::ResetForTests();
95 virtual QuicTestClient* CreateQuicClient(QuicTestWriter* writer) {
96 QuicTestClient* client = new QuicTestClient(server_address_,
97 server_hostname_,
98 false, // not secure
99 client_config_,
100 version_);
101 client->UseWriter(writer);
102 client->Connect();
103 return client;
106 virtual bool Initialize() {
107 // Start the server first, because CreateQuicClient() attempts
108 // to connect to the server.
109 StartServer();
110 client_.reset(CreateQuicClient(client_writer_));
111 QuicEpollConnectionHelper* helper =
112 reinterpret_cast<QuicEpollConnectionHelper*>(
113 QuicConnectionPeer::GetHelper(
114 client_->client()->session()->connection()));
115 client_writer_->SetConnectionHelper(helper);
116 return client_->client()->connected();
119 virtual void SetUp() {
120 // The ownership of these gets transferred to the QuicTestWriter and
121 // QuicDispatcher when Initialize() is executed.
122 client_writer_ = new PacketDroppingTestWriter();
123 server_writer_ = new PacketDroppingTestWriter();
126 virtual void TearDown() {
127 StopServer();
130 void StartServer() {
131 server_thread_.reset(new ServerThread(server_address_, server_config_,
132 strike_register_no_startup_period_));
133 server_thread_->Start();
134 server_thread_->listening()->Wait();
135 server_address_ = IPEndPoint(server_address_.address(),
136 server_thread_->GetPort());
137 QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(
138 server_thread_->server());
139 QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
140 server_started_ = true;
143 void StopServer() {
144 if (!server_started_)
145 return;
146 if (server_thread_.get()) {
147 server_thread_->quit()->Signal();
148 server_thread_->Join();
152 void AddToCache(StringPiece method,
153 StringPiece path,
154 StringPiece version,
155 StringPiece response_code,
156 StringPiece response_detail,
157 StringPiece body) {
158 QuicInMemoryCache::GetInstance()->AddSimpleResponse(
159 method, path, version, response_code, response_detail, body);
162 void SetPacketLossPercentage(int32 loss) {
163 // TODO(rtenneti): enable when we can do random packet loss tests in
164 // chrome's tree.
165 // client_writer_->set_fake_packet_loss_percentage(loss);
166 // server_writer_->set_fake_packet_loss_percentage(loss);
169 IPEndPoint server_address_;
170 string server_hostname_;
171 scoped_ptr<ServerThread> server_thread_;
172 scoped_ptr<QuicTestClient> client_;
173 PacketDroppingTestWriter* client_writer_;
174 PacketDroppingTestWriter* server_writer_;
175 bool server_started_;
176 QuicConfig client_config_;
177 QuicConfig server_config_;
178 QuicVersion version_;
179 bool strike_register_no_startup_period_;
182 // Run all end to end tests with all supported versions.
183 INSTANTIATE_TEST_CASE_P(EndToEndTests,
184 EndToEndTest,
185 ::testing::ValuesIn(kSupportedQuicVersions));
187 TEST_P(EndToEndTest, SimpleRequestResponse) {
188 ASSERT_TRUE(Initialize());
190 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
191 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
194 // TODO(rch): figure out how to detect missing v6 supprt (like on the linux
195 // try bots) and selectively disable this test.
196 TEST_P(EndToEndTest, DISABLED_SimpleRequestResponsev6) {
197 IPAddressNumber ip;
198 CHECK(net::ParseIPLiteralToNumber("::1", &ip));
199 server_address_ = IPEndPoint(ip, server_address_.port());
200 ASSERT_TRUE(Initialize());
202 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
203 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
206 TEST_P(EndToEndTest, SeparateFinPacket) {
207 ASSERT_TRUE(Initialize());
209 HTTPMessage request(HttpConstants::HTTP_1_1,
210 HttpConstants::POST, "/foo");
211 request.set_has_complete_message(false);
213 client_->SendMessage(request);
215 client_->SendData(string(), true);
217 client_->WaitForResponse();
218 EXPECT_EQ(kFooResponseBody, client_->response_body());
219 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
221 request.AddBody("foo", true);
223 client_->SendMessage(request);
224 client_->SendData(string(), true);
225 client_->WaitForResponse();
226 EXPECT_EQ(kFooResponseBody, client_->response_body());
227 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
230 TEST_P(EndToEndTest, MultipleRequestResponse) {
231 ASSERT_TRUE(Initialize());
233 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
234 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
235 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
236 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
239 TEST_P(EndToEndTest, MultipleClients) {
240 ASSERT_TRUE(Initialize());
241 scoped_ptr<QuicTestClient> client2(CreateQuicClient(NULL));
243 HTTPMessage request(HttpConstants::HTTP_1_1,
244 HttpConstants::POST, "/foo");
245 request.AddHeader("content-length", "3");
246 request.set_has_complete_message(false);
248 client_->SendMessage(request);
249 client2->SendMessage(request);
251 client_->SendData("bar", true);
252 client_->WaitForResponse();
253 EXPECT_EQ(kFooResponseBody, client_->response_body());
254 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
256 client2->SendData("eep", true);
257 client2->WaitForResponse();
258 EXPECT_EQ(kFooResponseBody, client2->response_body());
259 EXPECT_EQ(200u, client2->response_headers()->parsed_response_code());
262 TEST_P(EndToEndTest, RequestOverMultiplePackets) {
263 ASSERT_TRUE(Initialize());
264 // Set things up so we have a small payload, to guarantee fragmentation.
265 // A congestion feedback frame can't be split into multiple packets, make sure
266 // that our packet have room for at least this amount after the normal headers
267 // are added.
269 // TODO(rch) handle this better when we have different encryption options.
270 const size_t kStreamDataLength = 3;
271 const QuicStreamId kStreamId = 1u;
272 const QuicStreamOffset kStreamOffset = 0u;
273 size_t stream_payload_size =
274 QuicFramer::GetMinStreamFrameSize(
275 GetParam(), kStreamId, kStreamOffset, true) + kStreamDataLength;
276 size_t min_payload_size =
277 std::max(kCongestionFeedbackFrameSize, stream_payload_size);
278 size_t ciphertext_size =
279 NullEncrypter(GetParam()).GetCiphertextSize(min_payload_size);
280 // TODO(satyashekhar): Fix this when versioning is implemented.
281 client_->options()->max_packet_length =
282 GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
283 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) +
284 ciphertext_size;
286 // Make sure our request is too large to fit in one packet.
287 EXPECT_GT(strlen(kLargeRequest), min_payload_size);
288 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest(kLargeRequest));
289 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
292 TEST_P(EndToEndTest, MultipleFramesRandomOrder) {
293 ASSERT_TRUE(Initialize());
294 // Set things up so we have a small payload, to guarantee fragmentation.
295 // A congestion feedback frame can't be split into multiple packets, make sure
296 // that our packet have room for at least this amount after the normal headers
297 // are added.
299 // TODO(rch) handle this better when we have different encryption options.
300 const size_t kStreamDataLength = 3;
301 const QuicStreamId kStreamId = 1u;
302 const QuicStreamOffset kStreamOffset = 0u;
303 size_t stream_payload_size =
304 QuicFramer::GetMinStreamFrameSize(
305 GetParam(), kStreamId, kStreamOffset, true) + kStreamDataLength;
306 size_t min_payload_size =
307 std::max(kCongestionFeedbackFrameSize, stream_payload_size);
308 size_t ciphertext_size =
309 NullEncrypter(GetParam()).GetCiphertextSize(min_payload_size);
310 // TODO(satyashekhar): Fix this when versioning is implemented.
311 client_->options()->max_packet_length =
312 GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion,
313 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) +
314 ciphertext_size;
315 client_->options()->random_reorder = true;
317 // Make sure our request is too large to fit in one packet.
318 EXPECT_GT(strlen(kLargeRequest), min_payload_size);
319 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest(kLargeRequest));
320 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
323 TEST_P(EndToEndTest, PostMissingBytes) {
324 ASSERT_TRUE(Initialize());
326 // Add a content length header with no body.
327 HTTPMessage request(HttpConstants::HTTP_1_1,
328 HttpConstants::POST, "/foo");
329 request.AddHeader("content-length", "3");
330 request.set_skip_message_validation(true);
332 // This should be detected as stream fin without complete request,
333 // triggering an error response.
334 client_->SendCustomSynchronousRequest(request);
335 EXPECT_EQ("bad", client_->response_body());
336 EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
339 TEST_P(EndToEndTest, LargePostNoPacketLoss) {
340 ASSERT_TRUE(Initialize());
342 client_->client()->WaitForCryptoHandshakeConfirmed();
344 // 1 Mb body.
345 string body;
346 GenerateBody(&body, 1024 * 1024);
348 HTTPMessage request(HttpConstants::HTTP_1_1,
349 HttpConstants::POST, "/foo");
350 request.AddBody(body, true);
352 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
355 TEST_P(EndToEndTest, LargePostWithPacketLoss) {
356 // Connect with lower fake packet loss than we'd like to test. Until
357 // b/10126687 is fixed, losing handshake packets is pretty brutal.
358 SetPacketLossPercentage(5);
359 ASSERT_TRUE(Initialize());
361 // Wait for the server SHLO before upping the packet loss.
362 client_->client()->WaitForCryptoHandshakeConfirmed();
363 SetPacketLossPercentage(30);
365 // 10 Kb body.
366 string body;
367 GenerateBody(&body, 1024 * 10);
369 HTTPMessage request(HttpConstants::HTTP_1_1,
370 HttpConstants::POST, "/foo");
371 request.AddBody(body, true);
373 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
376 TEST_P(EndToEndTest, LargePostWithPacketLossAndBlocketSocket) {
377 // Connect with lower fake packet loss than we'd like to test. Until
378 // b/10126687 is fixed, losing handshake packets is pretty brutal.
379 SetPacketLossPercentage(5);
380 ASSERT_TRUE(Initialize());
382 // Wait for the server SHLO before upping the packet loss.
383 client_->client()->WaitForCryptoHandshakeConfirmed();
384 SetPacketLossPercentage(30);
385 client_writer_->set_fake_blocked_socket_percentage(10);
387 // 10 Kb body.
388 string body;
389 GenerateBody(&body, 1024 * 10);
391 HTTPMessage request(HttpConstants::HTTP_1_1,
392 HttpConstants::POST, "/foo");
393 request.AddBody(body, true);
395 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
398 // TODO(rtenneti): rch is investigating the root cause. Will enable after we
399 // find the bug.
400 TEST_P(EndToEndTest, DISABLED_LargePostZeroRTTFailure) {
401 // Have the server accept 0-RTT without waiting a startup period.
402 strike_register_no_startup_period_ = true;
404 // Send a request and then disconnect. This prepares the client to attempt
405 // a 0-RTT handshake for the next request.
406 ASSERT_TRUE(Initialize());
408 string body;
409 GenerateBody(&body, 20480);
411 HTTPMessage request(HttpConstants::HTTP_1_1,
412 HttpConstants::POST, "/foo");
413 request.AddBody(body, true);
415 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
416 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos());
418 client_->Disconnect();
420 // The 0-RTT handshake should succeed.
421 client_->Connect();
422 ASSERT_TRUE(client_->client()->connected());
423 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
424 EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
426 client_->Disconnect();
428 // Restart the server so that the 0-RTT handshake will take 1 RTT.
429 StopServer();
430 server_writer_ = new PacketDroppingTestWriter();
431 StartServer();
433 client_->Connect();
434 ASSERT_TRUE(client_->client()->connected());
435 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
436 EXPECT_EQ(2, client_->client()->session()->GetNumSentClientHellos());
439 // TODO(ianswett): Enable once b/9295090 is fixed.
440 TEST_P(EndToEndTest, DISABLED_LargePostFEC) {
441 SetPacketLossPercentage(30);
442 ASSERT_TRUE(Initialize());
443 client_->options()->max_packets_per_fec_group = 6;
445 string body;
446 GenerateBody(&body, 10240);
448 HTTPMessage request(HttpConstants::HTTP_1_1,
449 HttpConstants::POST, "/foo");
450 request.AddBody(body, true);
452 EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
455 /*TEST_P(EndToEndTest, PacketTooLarge) {
456 FLAGS_quic_allow_oversized_packets_for_test = true;
457 ASSERT_TRUE(Initialize());
459 string body;
460 GenerateBody(&body, kMaxPacketSize);
462 HTTPMessage request(HttpConstants::HTTP_1_1,
463 HttpConstants::POST, "/foo");
464 request.AddBody(body, true);
465 client_->options()->max_packet_length = 20480;
467 EXPECT_EQ("", client_->SendCustomSynchronousRequest(request));
468 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
469 EXPECT_EQ(QUIC_PACKET_TOO_LARGE, client_->connection_error());
472 TEST_P(EndToEndTest, InvalidStream) {
473 ASSERT_TRUE(Initialize());
475 string body;
476 GenerateBody(&body, kMaxPacketSize);
478 HTTPMessage request(HttpConstants::HTTP_1_1,
479 HttpConstants::POST, "/foo");
480 request.AddBody(body, true);
481 // Force the client to write with a stream ID belonging to a nonexistent
482 // server-side stream.
483 QuicSessionPeer::SetNextStreamId(client_->client()->session(), 2);
485 client_->SendCustomSynchronousRequest(request);
486 // EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
487 EXPECT_EQ(QUIC_PACKET_FOR_NONEXISTENT_STREAM, client_->connection_error());
490 // TODO(rch): this test seems to cause net_unittests timeouts :|
491 TEST_P(EndToEndTest, DISABLED_MultipleTermination) {
492 ASSERT_TRUE(Initialize());
494 HTTPMessage request(HttpConstants::HTTP_1_1,
495 HttpConstants::POST, "/foo");
496 request.AddHeader("content-length", "3");
497 request.set_has_complete_message(false);
499 // Set the offset so we won't frame. Otherwise when we pick up termination
500 // before HTTP framing is complete, we send an error and close the stream,
501 // and the second write is picked up as writing on a closed stream.
502 QuicReliableClientStream* stream = client_->GetOrCreateStream();
503 ASSERT_TRUE(stream != NULL);
504 ReliableQuicStreamPeer::SetStreamBytesWritten(3, stream);
506 client_->SendData("bar", true);
508 // By default the stream protects itself from writes after terminte is set.
509 // Override this to test the server handling buggy clients.
510 ReliableQuicStreamPeer::SetWriteSideClosed(
511 false, client_->GetOrCreateStream());
513 #if !defined(WIN32) && defined(GTEST_HAS_DEATH_TEST)
514 #if !defined(DCHECK_ALWAYS_ON)
515 EXPECT_DEBUG_DEATH({
516 client_->SendData("eep", true);
517 client_->WaitForResponse();
518 EXPECT_EQ(QUIC_MULTIPLE_TERMINATION_OFFSETS, client_->stream_error());
520 "Check failed: !fin_buffered_");
521 #else
522 EXPECT_DEATH({
523 client_->SendData("eep", true);
524 client_->WaitForResponse();
525 EXPECT_EQ(QUIC_MULTIPLE_TERMINATION_OFFSETS, client_->stream_error());
527 "Check failed: !fin_buffered_");
528 #endif
529 #endif
532 TEST_P(EndToEndTest, Timeout) {
533 client_config_.set_idle_connection_state_lifetime(
534 QuicTime::Delta::FromMicroseconds(500),
535 QuicTime::Delta::FromMicroseconds(500));
536 // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
537 // that's enough to validate timeout in this case.
538 Initialize();
539 while (client_->client()->connected()) {
540 client_->client()->WaitForEvents();
544 TEST_P(EndToEndTest, LimitMaxOpenStreams) {
545 // Server limits the number of max streams to 2.
546 server_config_.set_max_streams_per_connection(2, 2);
547 // Client tries to negotiate for 10.
548 client_config_.set_max_streams_per_connection(10, 5);
550 ASSERT_TRUE(Initialize());
551 client_->client()->WaitForCryptoHandshakeConfirmed();
552 QuicConfig* client_negotiated_config = client_->client()->session()->config();
553 EXPECT_EQ(2u, client_negotiated_config->max_streams_per_connection());
556 TEST_P(EndToEndTest, ResetConnection) {
557 ASSERT_TRUE(Initialize());
559 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
560 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
561 client_->ResetConnection();
562 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
563 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
566 TEST_P(EndToEndTest, MaxStreamsUberTest) {
567 SetPacketLossPercentage(1);
568 ASSERT_TRUE(Initialize());
569 string large_body;
570 GenerateBody(&large_body, 10240);
571 int max_streams = 100;
573 AddToCache("GET", "/large_response", "HTTP/1.1", "200", "OK", large_body);;
575 client_->client()->WaitForCryptoHandshakeConfirmed();
576 SetPacketLossPercentage(10);
578 for (int i = 0; i < max_streams; ++i) {
579 EXPECT_LT(0, client_->SendRequest("/large_response"));
582 // WaitForEvents waits 50ms and returns true if there are outstanding
583 // requests.
584 while (client_->client()->WaitForEvents() == true) {
588 class WrongAddressWriter : public QuicTestWriter {
589 public:
590 WrongAddressWriter() {
591 IPAddressNumber ip;
592 CHECK(net::ParseIPLiteralToNumber("127.0.0.2", &ip));
593 self_address_ = IPEndPoint(ip, 0);
596 virtual WriteResult WritePacket(
597 const char* buffer, size_t buf_len,
598 const IPAddressNumber& real_self_address,
599 const IPEndPoint& peer_address,
600 QuicBlockedWriterInterface* blocked_writer) OVERRIDE {
601 return writer()->WritePacket(buffer, buf_len, self_address_.address(),
602 peer_address, blocked_writer);
605 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE {
606 return false;
609 IPEndPoint self_address_;
612 TEST_P(EndToEndTest, ConnectionMigration) {
613 ASSERT_TRUE(Initialize());
615 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
616 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
618 scoped_ptr<WrongAddressWriter> writer(new WrongAddressWriter());
620 writer->set_writer(new QuicDefaultPacketWriter(
621 QuicClientPeer::GetFd(client_->client())));
622 QuicConnectionPeer::SetWriter(
623 client_->client()->session()->connection(),
624 reinterpret_cast<QuicTestWriter*>(writer.get()));
626 client_->SendSynchronousRequest("/bar");
628 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
629 EXPECT_EQ(QUIC_ERROR_MIGRATING_ADDRESS, client_->connection_error());
632 } // namespace
633 } // namespace test
634 } // namespace tools
635 } // namespace net