Add signalSyncPoint to the WebGraphicsContext3D command buffer impls.
[chromium-blink-merge.git] / net / quic / quic_network_transaction_unittest.cc
blob240728bf530e932443b1140859afdb2039d66fcf
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 "base/basictypes.h"
6 #include "base/compiler_specific.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "net/base/test_completion_callback.h"
9 #include "net/cert/mock_cert_verifier.h"
10 #include "net/dns/mock_host_resolver.h"
11 #include "net/http/http_auth_handler_factory.h"
12 #include "net/http/http_network_session.h"
13 #include "net/http/http_network_transaction.h"
14 #include "net/http/http_server_properties_impl.h"
15 #include "net/http/http_stream.h"
16 #include "net/http/http_stream_factory.h"
17 #include "net/http/http_transaction_unittest.h"
18 #include "net/proxy/proxy_config_service_fixed.h"
19 #include "net/proxy/proxy_resolver.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/quic/crypto/quic_decrypter.h"
22 #include "net/quic/crypto/quic_encrypter.h"
23 #include "net/quic/quic_framer.h"
24 #include "net/quic/test_tools/crypto_test_utils.h"
25 #include "net/quic/test_tools/mock_clock.h"
26 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
27 #include "net/quic/test_tools/mock_random.h"
28 #include "net/quic/test_tools/quic_test_utils.h"
29 #include "net/socket/client_socket_factory.h"
30 #include "net/socket/mock_client_socket_pool_manager.h"
31 #include "net/socket/socket_test_util.h"
32 #include "net/socket/ssl_client_socket.h"
33 #include "net/spdy/spdy_frame_builder.h"
34 #include "net/spdy/spdy_framer.h"
35 #include "net/ssl/ssl_config_service_defaults.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "testing/platform_test.h"
39 //-----------------------------------------------------------------------------
41 namespace {
43 // This is the expected return from a current server advertising QUIC.
44 static const char kQuicAlternateProtocolHttpHeader[] =
45 "Alternate-Protocol: 443:quic\r\n\r\n";
47 // Returns a vector of NPN protocol strings for negotiating QUIC.
48 std::vector<std::string> QuicNextProtos() {
49 std::vector<std::string> protos;
50 protos.push_back("http/1.1");
51 protos.push_back("quic");
52 return protos;
55 } // namespace
57 namespace net {
58 namespace test {
60 class QuicNetworkTransactionTest : public PlatformTest {
61 protected:
62 QuicNetworkTransactionTest()
63 : clock_(new MockClock),
64 ssl_config_service_(new SSLConfigServiceDefaults),
65 proxy_service_(ProxyService::CreateDirect()),
66 auth_handler_factory_(
67 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)) {
70 virtual void SetUp() {
71 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
72 MessageLoop::current()->RunUntilIdle();
75 virtual void TearDown() {
76 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
77 // Empty the current queue.
78 MessageLoop::current()->RunUntilIdle();
79 PlatformTest::TearDown();
80 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
81 MessageLoop::current()->RunUntilIdle();
82 HttpStreamFactory::set_use_alternate_protocols(false);
83 HttpStreamFactory::SetNextProtos(std::vector<std::string>());
86 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
87 QuicPacketSequenceNumber num,
88 QuicStreamId stream_id) {
89 QuicPacketHeader header;
90 header.public_header.guid = 0xDEADBEEF;
91 header.public_header.reset_flag = false;
92 header.public_header.version_flag = false;
93 header.packet_sequence_number = num;
94 header.entropy_flag = false;
95 header.fec_flag = false;
96 header.fec_entropy_flag = false;
97 header.fec_group = 0;
99 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
100 return scoped_ptr<QuicEncryptedPacket>(
101 ConstructPacket(header, QuicFrame(&rst)));
104 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
105 QuicPacketSequenceNumber largest_received,
106 QuicPacketSequenceNumber least_unacked) {
107 QuicPacketHeader header;
108 header.public_header.guid = 0xDEADBEEF;
109 header.public_header.reset_flag = false;
110 header.public_header.version_flag = false;
111 header.packet_sequence_number = 2;
112 header.entropy_flag = false;
113 header.fec_flag = false;
114 header.fec_entropy_flag = false;
115 header.fec_group = 0;
117 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
119 QuicCongestionFeedbackFrame feedback;
120 feedback.type = kTCP;
121 feedback.tcp.accumulated_number_of_lost_packets = 0;
122 feedback.tcp.receive_window = 256000;
124 QuicFramer framer(kQuicVersion1,
125 QuicDecrypter::Create(kNULL),
126 QuicEncrypter::Create(kNULL),
127 QuicTime::Zero(),
128 false);
129 QuicFrames frames;
130 frames.push_back(QuicFrame(&ack));
131 frames.push_back(QuicFrame(&feedback));
132 scoped_ptr<QuicPacket> packet(
133 framer.ConstructFrameDataPacket(header, frames).packet);
134 return scoped_ptr<QuicEncryptedPacket>(
135 framer.EncryptPacket(header.packet_sequence_number, *packet));
138 std::string GetRequestString(const std::string& method,
139 const std::string& path) {
140 SpdyHeaderBlock headers;
141 headers[":method"] = method;
142 headers[":host"] = "www.google.com";
143 headers[":path"] = path;
144 headers[":scheme"] = "http";
145 headers[":version"] = "HTTP/1.1";
146 return SerializeHeaderBlock(headers);
149 std::string GetResponseString(const std::string& status,
150 const std::string& body) {
151 SpdyHeaderBlock headers;
152 headers[":status"] = status;
153 headers[":version"] = "HTTP/1.1";
154 headers["content-type"] = "text/plain";
155 return SerializeHeaderBlock(headers) + body;
158 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
159 size_t len = SpdyFramer::GetSerializedLength(3, &headers);
160 SpdyFrameBuilder builder(len);
161 SpdyFramer::WriteHeaderBlock(&builder, 3, &headers);
162 scoped_ptr<SpdyFrame> frame(builder.take());
163 return std::string(frame->data(), len);
166 // Returns a newly created packet to send kData on stream 1.
167 QuicEncryptedPacket* ConstructDataPacket(
168 QuicPacketSequenceNumber sequence_number,
169 bool should_include_version,
170 bool fin,
171 QuicStreamOffset offset,
172 base::StringPiece data) {
173 InitializeHeader(sequence_number, should_include_version);
174 QuicStreamFrame frame(3, fin, offset, data);
175 return ConstructPacket(header_, QuicFrame(&frame)).release();
178 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
179 const QuicPacketHeader& header,
180 const QuicFrame& frame) {
181 QuicFramer framer(kQuicVersion1,
182 QuicDecrypter::Create(kNULL),
183 QuicEncrypter::Create(kNULL),
184 QuicTime::Zero(),
185 false);
186 QuicFrames frames;
187 frames.push_back(frame);
188 scoped_ptr<QuicPacket> packet(
189 framer.ConstructFrameDataPacket(header, frames).packet);
190 return scoped_ptr<QuicEncryptedPacket>(
191 framer.EncryptPacket(header.packet_sequence_number, *packet));
194 void InitializeHeader(QuicPacketSequenceNumber sequence_number,
195 bool should_include_version) {
196 header_.public_header.guid = random_generator_.RandUint64();
197 header_.public_header.reset_flag = false;
198 header_.public_header.version_flag = should_include_version;
199 header_.packet_sequence_number = sequence_number;
200 header_.fec_group = 0;
201 header_.entropy_flag = false;
202 header_.fec_flag = false;
203 header_.fec_entropy_flag = false;
206 void CreateSession() {
207 params_.enable_quic = true;
208 params_.quic_clock = clock_;
209 params_.quic_random = &random_generator_;
210 params_.client_socket_factory = &socket_factory_;
211 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
212 params_.host_resolver = &host_resolver_;
213 params_.cert_verifier = &cert_verifier_;
214 params_.proxy_service = proxy_service_.get();
215 params_.ssl_config_service = ssl_config_service_.get();
216 params_.http_auth_handler_factory = auth_handler_factory_.get();
217 params_.http_server_properties = &http_server_properties;
219 session_ = new HttpNetworkSession(params_);
222 QuicPacketHeader header_;
223 scoped_refptr<HttpNetworkSession> session_;
224 MockClientSocketFactory socket_factory_;
225 MockCryptoClientStreamFactory crypto_client_stream_factory_;
226 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
227 MockHostResolver host_resolver_;
228 MockCertVerifier cert_verifier_;
229 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
230 scoped_ptr<ProxyService> proxy_service_;
231 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
232 MockRandom random_generator_;
233 HttpServerPropertiesImpl http_server_properties;
234 HttpNetworkSession::Params params_;
237 TEST_F(QuicNetworkTransactionTest, ForceQuic) {
238 params_.origin_port_to_force_quic_on = 80;
240 HttpRequestInfo request;
241 request.method = "GET";
242 request.url = GURL("http://www.google.com/");
243 request.load_flags = 0;
245 scoped_ptr<QuicEncryptedPacket> data(
246 ConstructDataPacket(1, true, true, 0, GetRequestString("GET", "/")));
247 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
249 MockWrite quic_writes[] = {
250 MockWrite(SYNCHRONOUS, data->data(), data->length()),
251 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
254 scoped_ptr<QuicEncryptedPacket> resp(
255 ConstructDataPacket(
256 1, false, true, 0, GetResponseString("200 OK", "hello!")));
257 MockRead quic_reads[] = {
258 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
259 MockRead(ASYNC, OK), // EOF
262 DelayedSocketData quic_data(
263 1, // wait for one write to finish before reading.
264 quic_reads, arraysize(quic_reads),
265 quic_writes, arraysize(quic_writes));
267 socket_factory_.AddSocketDataProvider(&quic_data);
269 // The non-alternate protocol job needs to hang in order to guarantee that the
270 // alternate-protocol job will "win".
271 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
272 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
273 NULL, 0, NULL, 0);
274 hanging_non_alternate_protocol_socket.set_connect_data(
275 never_finishing_connect);
276 socket_factory_.AddSocketDataProvider(
277 &hanging_non_alternate_protocol_socket);
279 TestCompletionCallback callback;
281 CreateSession();
282 scoped_ptr<HttpNetworkTransaction> trans(
283 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
285 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
286 EXPECT_EQ(ERR_IO_PENDING, rv);
287 EXPECT_EQ(OK, callback.WaitForResult());
289 const HttpResponseInfo* response = trans->GetResponseInfo();
290 ASSERT_TRUE(response != NULL);
291 ASSERT_TRUE(response->headers != NULL);
292 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
293 EXPECT_TRUE(response->was_fetched_via_spdy);
294 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
295 response->connection_info);
297 std::string response_data;
298 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
299 EXPECT_EQ("hello!", response_data);
302 TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
303 // Attempt to "force" quic on 443, which will not be honored.
304 params_.origin_port_to_force_quic_on = 443;
306 HttpRequestInfo request;
307 request.method = "GET";
308 request.url = GURL("https://www.google.com/");
309 request.load_flags = 0;
311 MockRead data_reads[] = {
312 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
313 MockRead("hello world"),
314 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
315 MockRead(ASYNC, OK)
318 StaticSocketDataProvider data(
319 data_reads, arraysize(data_reads), NULL, 0);
320 socket_factory_.AddSocketDataProvider(&data);
321 SSLSocketDataProvider ssl(ASYNC, OK);
322 socket_factory_.AddSSLSocketDataProvider(&ssl);
324 TestCompletionCallback callback;
326 CreateSession();
327 scoped_ptr<HttpNetworkTransaction> trans(
328 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
330 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
331 EXPECT_EQ(ERR_IO_PENDING, rv);
332 EXPECT_EQ(OK, callback.WaitForResult());
334 const HttpResponseInfo* response = trans->GetResponseInfo();
335 ASSERT_TRUE(response != NULL);
336 ASSERT_TRUE(response->headers != NULL);
337 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
339 std::string response_data;
340 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
341 EXPECT_EQ("hello world", response_data);
344 TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
345 HttpStreamFactory::set_use_alternate_protocols(true);
346 HttpStreamFactory::SetNextProtos(QuicNextProtos());
348 HttpRequestInfo request;
349 request.method = "GET";
350 request.url = GURL("http://www.google.com/");
351 request.load_flags = 0;
353 MockRead data_reads[] = {
354 MockRead("HTTP/1.1 200 OK\r\n"),
355 MockRead(kQuicAlternateProtocolHttpHeader),
356 MockRead("hello world"),
357 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
358 MockRead(ASYNC, OK)
361 StaticSocketDataProvider first_transaction(
362 data_reads, arraysize(data_reads), NULL, 0);
363 socket_factory_.AddSocketDataProvider(&first_transaction);
366 scoped_ptr<QuicEncryptedPacket> data(
367 ConstructDataPacket(1, true, true, 0, GetRequestString("GET", "/")));
368 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
370 MockWrite quic_writes[] = {
371 MockWrite(SYNCHRONOUS, data->data(), data->length()),
372 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
375 scoped_ptr<QuicEncryptedPacket> resp(
376 ConstructDataPacket(
377 1, false, true, 0, GetResponseString("200 OK", "hello!")));
378 MockRead quic_reads[] = {
379 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
380 MockRead(ASYNC, OK), // EOF
383 DelayedSocketData quic_data(
384 1, // wait for one write to finish before reading.
385 quic_reads, arraysize(quic_reads),
386 quic_writes, arraysize(quic_writes));
388 socket_factory_.AddSocketDataProvider(&quic_data);
390 // The non-alternate protocol job needs to hang in order to guarantee that the
391 // alternate-protocol job will "win".
392 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
393 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
394 NULL, 0, NULL, 0);
395 hanging_non_alternate_protocol_socket.set_connect_data(
396 never_finishing_connect);
397 socket_factory_.AddSocketDataProvider(
398 &hanging_non_alternate_protocol_socket);
400 TestCompletionCallback callback;
402 CreateSession();
403 scoped_ptr<HttpNetworkTransaction> trans(
404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
406 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
407 EXPECT_EQ(ERR_IO_PENDING, rv);
408 EXPECT_EQ(OK, callback.WaitForResult());
410 const HttpResponseInfo* response = trans->GetResponseInfo();
411 ASSERT_TRUE(response != NULL);
412 ASSERT_TRUE(response->headers != NULL);
413 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
415 std::string response_data;
416 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
417 EXPECT_EQ("hello world", response_data);
419 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
421 rv = trans->Start(&request, callback.callback(), BoundNetLog());
422 EXPECT_EQ(ERR_IO_PENDING, rv);
423 EXPECT_EQ(OK, callback.WaitForResult());
425 response = trans->GetResponseInfo();
426 ASSERT_TRUE(response != NULL);
427 ASSERT_TRUE(response->headers != NULL);
428 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
429 EXPECT_TRUE(response->was_fetched_via_spdy);
430 EXPECT_TRUE(response->was_npn_negotiated);
431 EXPECT_EQ("quic/1+spdy/3", response->npn_negotiated_protocol);
433 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
434 EXPECT_EQ("hello!", response_data);
437 TEST_F(QuicNetworkTransactionTest, DontUseAlternateProtocolForQuicHttps) {
438 HttpStreamFactory::set_use_alternate_protocols(true);
439 HttpStreamFactory::SetNextProtos(QuicNextProtos());
441 HttpRequestInfo request;
442 request.method = "GET";
443 request.url = GURL("https://www.google.com/");
444 request.load_flags = 0;
446 MockRead data_reads[] = {
447 MockRead("HTTP/1.1 200 OK\r\n"),
448 MockRead("Content-length: 11\r\n"),
449 MockRead(kQuicAlternateProtocolHttpHeader),
450 MockRead("hello world"),
452 MockRead("HTTP/1.1 200 OK\r\n"),
453 MockRead("Content-length: 6\r\n"),
454 MockRead(kQuicAlternateProtocolHttpHeader),
455 MockRead("hello!"),
458 StaticSocketDataProvider first_transaction(
459 data_reads, arraysize(data_reads), NULL, 0);
460 socket_factory_.AddSocketDataProvider(&first_transaction);
461 SSLSocketDataProvider ssl(ASYNC, OK);
462 socket_factory_.AddSSLSocketDataProvider(&ssl);
464 TestCompletionCallback callback;
466 CreateSession();
467 scoped_ptr<HttpNetworkTransaction> trans(
468 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
470 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
471 EXPECT_EQ(ERR_IO_PENDING, rv);
472 EXPECT_EQ(OK, callback.WaitForResult());
474 const HttpResponseInfo* response = trans->GetResponseInfo();
475 ASSERT_TRUE(response != NULL);
476 ASSERT_TRUE(response->headers != NULL);
477 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
479 std::string response_data;
480 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
481 EXPECT_EQ("hello world", response_data);
483 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
485 rv = trans->Start(&request, callback.callback(), BoundNetLog());
486 EXPECT_EQ(ERR_IO_PENDING, rv);
487 EXPECT_EQ(OK, callback.WaitForResult());
489 response = trans->GetResponseInfo();
490 ASSERT_TRUE(response != NULL);
491 ASSERT_TRUE(response->headers != NULL);
492 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
493 EXPECT_FALSE(response->was_fetched_via_spdy);
495 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
496 EXPECT_EQ("hello!", response_data);
499 } // namespace test
500 } // namespace net