Index: net/spdy/spdy_network_transaction_unittest.cc |
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc |
index 019cc4c8bee9ea10258d4e7cace3b140f6d69ea0..84e19d642b79b23d7c31a7bf391421377e323ef5 100644 |
--- a/net/spdy/spdy_network_transaction_unittest.cc |
+++ b/net/spdy/spdy_network_transaction_unittest.cc |
@@ -579,9 +579,10 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) { |
scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false)); |
scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true)); |
- MockWrite writes[] = { CreateMockWrite(*req), |
- CreateMockWrite(*req2), |
- CreateMockWrite(*req3), |
+ MockWrite writes[] = { |
+ CreateMockWrite(*req), |
+ CreateMockWrite(*req2), |
+ CreateMockWrite(*req3), |
}; |
MockRead reads[] = { |
CreateMockRead(*resp, 1), |
@@ -657,6 +658,193 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) { |
EXPECT_EQ("hello!hello!", out.response_data); |
} |
+TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { |
+ scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); |
+ scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); |
+ scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); |
+ scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); |
+ |
+ scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); |
+ scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); |
+ scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); |
+ scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); |
+ |
+ MockWrite writes[] = { |
+ CreateMockWrite(*req), |
+ CreateMockWrite(*req2), |
+ }; |
+ MockRead reads[] = { |
+ CreateMockRead(*resp, 1), |
+ CreateMockRead(*body), |
+ CreateMockRead(*resp2, 4), |
+ CreateMockRead(*body2), |
+ CreateMockRead(*fbody), |
+ CreateMockRead(*fbody2), |
+ MockRead(true, 0, 0), // EOF |
+ }; |
+ scoped_refptr<OrderedSocketData> data( |
+ new OrderedSocketData(reads, arraysize(reads), |
+ writes, arraysize(writes))); |
+ |
+ MockConnect never_finishing_connect(true, ERR_IO_PENDING); |
+ |
+ scoped_refptr<OrderedSocketData> data_placeholder( |
+ new OrderedSocketData(NULL, 0, NULL, 0)); |
+ data_placeholder->set_connect_data(never_finishing_connect); |
+ |
+ BoundNetLog log; |
+ TransactionHelperResult out; |
+ NormalSpdyTransactionHelper helper(CreateGetRequest(), |
+ BoundNetLog(), GetParam()); |
+ helper.RunPreTestSetup(); |
+ helper.AddData(data.get()); |
+ // We require placeholder data because two get requests are sent out, so |
+ // there needs to be two sets of SSL connection data. |
+ helper.AddData(data_placeholder.get()); |
+ scoped_ptr<HttpNetworkTransaction> trans1( |
+ new HttpNetworkTransaction(helper.session())); |
+ scoped_ptr<HttpNetworkTransaction> trans2( |
+ new HttpNetworkTransaction(helper.session())); |
+ |
+ TestCompletionCallback callback1; |
+ TestCompletionCallback callback2; |
+ |
+ HttpRequestInfo httpreq1 = CreateGetRequest(); |
+ HttpRequestInfo httpreq2 = CreateGetRequest(); |
+ |
+ out.rv = trans1->Start(&httpreq1, &callback1, log); |
+ ASSERT_EQ(ERR_IO_PENDING, out.rv); |
+ out.rv = trans2->Start(&httpreq2, &callback2, log); |
+ ASSERT_EQ(ERR_IO_PENDING, out.rv); |
+ |
+ out.rv = callback1.WaitForResult(); |
+ ASSERT_EQ(OK, out.rv); |
+ out.rv = callback2.WaitForResult(); |
+ ASSERT_EQ(OK, out.rv); |
+ |
+ const HttpResponseInfo* response1 = trans1->GetResponseInfo(); |
+ EXPECT_TRUE(response1->headers != NULL); |
+ EXPECT_TRUE(response1->was_fetched_via_spdy); |
+ out.status_line = response1->headers->GetStatusLine(); |
+ out.response_info = *response1; |
+ out.rv = ReadTransaction(trans1.get(), &out.response_data); |
+ EXPECT_EQ(OK, out.rv); |
+ EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); |
+ EXPECT_EQ("hello!hello!", out.response_data); |
+ |
+ const HttpResponseInfo* response2 = trans2->GetResponseInfo(); |
+ EXPECT_TRUE(response2->headers != NULL); |
+ EXPECT_TRUE(response2->was_fetched_via_spdy); |
+ out.status_line = response2->headers->GetStatusLine(); |
+ out.response_info = *response2; |
+ out.rv = ReadTransaction(trans2.get(), &out.response_data); |
+ EXPECT_EQ(OK, out.rv); |
+ EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); |
+ EXPECT_EQ("hello!hello!", out.response_data); |
+ |
+ helper.VerifyDataConsumed(); |
+} |
+ |
+TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { |
+ scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); |
+ scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); |
+ scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); |
+ scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); |
+ |
+ scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); |
+ scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); |
+ scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); |
+ scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); |
+ |
+ MockWrite writes[] = { |
+ CreateMockWrite(*req), |
+ CreateMockWrite(*req2), |
+ }; |
+ MockRead reads[] = { |
+ CreateMockRead(*resp, 1), |
+ CreateMockRead(*body), |
+ CreateMockRead(*resp2, 4), |
+ CreateMockRead(*body2), |
+ CreateMockRead(*fbody), |
+ CreateMockRead(*fbody2), |
+ MockRead(true, 0, 0), // EOF |
+ }; |
+ scoped_refptr<OrderedSocketData> preconnect_data( |
+ new OrderedSocketData(reads, arraysize(reads), |
+ writes, arraysize(writes))); |
+ |
+ MockConnect never_finishing_connect(true, ERR_IO_PENDING); |
+ |
+ scoped_refptr<OrderedSocketData> data_placeholder( |
+ new OrderedSocketData(NULL, 0, NULL, 0)); |
+ data_placeholder->set_connect_data(never_finishing_connect); |
+ |
+ BoundNetLog log; |
+ TransactionHelperResult out; |
+ NormalSpdyTransactionHelper helper(CreateGetRequest(), |
+ BoundNetLog(), GetParam()); |
+ helper.RunPreTestSetup(); |
+ helper.AddData(preconnect_data.get()); |
+ // We require placeholder data because 3 connections are attempted (first is |
+ // the preconnect, 2nd and 3rd are the never finished connections. |
+ helper.AddData(data_placeholder.get()); |
+ helper.AddData(data_placeholder.get()); |
+ |
+ scoped_ptr<HttpNetworkTransaction> trans1( |
+ new HttpNetworkTransaction(helper.session())); |
+ scoped_ptr<HttpNetworkTransaction> trans2( |
+ new HttpNetworkTransaction(helper.session())); |
+ |
+ TestCompletionCallback callback1; |
+ TestCompletionCallback callback2; |
+ |
+ HttpRequestInfo httpreq = CreateGetRequest(); |
+ |
+ // Preconnect the first. |
+ SSLConfig preconnect_ssl_config; |
+ helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config); |
+ HttpStreamFactory* http_stream_factory = |
+ helper.session()->http_stream_factory(); |
+ if (http_stream_factory->next_protos()) { |
+ preconnect_ssl_config.next_protos = *http_stream_factory->next_protos(); |
+ } |
+ |
+ http_stream_factory->PreconnectStreams( |
+ 1, httpreq, preconnect_ssl_config, log); |
+ |
+ out.rv = trans1->Start(&httpreq, &callback1, log); |
+ ASSERT_EQ(ERR_IO_PENDING, out.rv); |
+ out.rv = trans2->Start(&httpreq, &callback2, log); |
+ ASSERT_EQ(ERR_IO_PENDING, out.rv); |
+ |
+ out.rv = callback1.WaitForResult(); |
+ ASSERT_EQ(OK, out.rv); |
+ out.rv = callback2.WaitForResult(); |
+ ASSERT_EQ(OK, out.rv); |
+ |
+ const HttpResponseInfo* response1 = trans1->GetResponseInfo(); |
+ EXPECT_TRUE(response1->headers != NULL); |
+ EXPECT_TRUE(response1->was_fetched_via_spdy); |
+ out.status_line = response1->headers->GetStatusLine(); |
+ out.response_info = *response1; |
+ out.rv = ReadTransaction(trans1.get(), &out.response_data); |
+ EXPECT_EQ(OK, out.rv); |
+ EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); |
+ EXPECT_EQ("hello!hello!", out.response_data); |
+ |
+ const HttpResponseInfo* response2 = trans2->GetResponseInfo(); |
+ EXPECT_TRUE(response2->headers != NULL); |
+ EXPECT_TRUE(response2->was_fetched_via_spdy); |
+ out.status_line = response2->headers->GetStatusLine(); |
+ out.response_info = *response2; |
+ out.rv = ReadTransaction(trans2.get(), &out.response_data); |
+ EXPECT_EQ(OK, out.rv); |
+ EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); |
+ EXPECT_EQ("hello!hello!", out.response_data); |
+ |
+ helper.VerifyDataConsumed(); |
+} |
+ |
// Similar to ThreeGets above, however this test adds a SETTINGS |
// frame. The SETTINGS frame is read during the IO loop waiting on |
// the first transaction completion, and sets a maximum concurrent |