Index: net/spdy/spdy_session_spdy2_unittest.cc |
=================================================================== |
--- net/spdy/spdy_session_spdy2_unittest.cc (revision 192196) |
+++ net/spdy/spdy_session_spdy2_unittest.cc (working copy) |
@@ -4,18 +4,13 @@ |
#include "net/spdy/spdy_session.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/memory/scoped_vector.h" |
#include "net/base/host_cache.h" |
-#include "net/base/io_buffer.h" |
#include "net/base/ip_endpoint.h" |
#include "net/base/net_log_unittest.h" |
#include "net/base/request_priority.h" |
#include "net/base/test_data_directory.h" |
-#include "net/base/test_data_stream.h" |
#include "net/spdy/spdy_io_buffer.h" |
#include "net/spdy/spdy_session_pool.h" |
-#include "net/spdy/spdy_session_test_util.h" |
#include "net/spdy/spdy_stream.h" |
#include "net/spdy/spdy_stream_test_util.h" |
#include "net/spdy/spdy_test_util_common.h" |
@@ -1585,376 +1580,6 @@ |
spdy_session_pool_->Remove(session); |
} |
-// Test that SpdySession::DoRead reads data from the socket without yielding. |
-// This test makes 32k - 1 bytes of data available on the socket for reading. It |
-// then verifies that it has read all the available data without yielding. |
-TEST_F(SpdySessionSpdy2Test, ReadDataWithoutYielding) { |
- MockConnect connect_data(SYNCHRONOUS, OK); |
- BufferedSpdyFramer framer(2, false); |
- |
- scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); |
- MockWrite writes[] = { |
- CreateMockWrite(*req1, 0), |
- }; |
- |
- // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size). |
- ASSERT_EQ(32 * 1024, kMaxReadBytes); |
- const int kPayloadSize = |
- kMaxReadBytes / 4 - framer.GetControlFrameHeaderSize(); |
- TestDataStream test_stream; |
- scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); |
- char* payload_data = payload->data(); |
- test_stream.GetBytes(payload_data, kPayloadSize); |
- |
- scoped_ptr<SpdyFrame> partial_data_frame( |
- framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); |
- scoped_ptr<SpdyFrame> finish_data_frame( |
- framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN)); |
- |
- scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); |
- |
- // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k |
- // bytes. |
- MockRead reads[] = { |
- CreateMockRead(*resp1, 1), |
- CreateMockRead(*partial_data_frame, 2), |
- CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), |
- CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), |
- CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS), |
- MockRead(ASYNC, 0, 6) // EOF |
- }; |
- |
- // Create SpdySession and SpdyStream and send the request. |
- DeterministicSocketData data(reads, arraysize(reads), |
- writes, arraysize(writes)); |
- data.set_connect_data(connect_data); |
- session_deps_.host_resolver->set_synchronous_mode(true); |
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); |
- |
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); |
- |
- CreateDeterministicNetworkSession(); |
- |
- scoped_refptr<SpdySession> session = CreateInitializedSession(); |
- |
- GURL url1("http://www.google.com"); |
- scoped_refptr<SpdyStream> spdy_stream1 = |
- CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog()); |
- ASSERT_TRUE(spdy_stream1.get() != NULL); |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- |
- scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
- (*headers)["method"] = "GET"; |
- (*headers)["scheme"] = url1.scheme(); |
- (*headers)["host"] = url1.host(); |
- (*headers)["url"] = url1.path(); |
- (*headers)["version"] = "HTTP/1.1"; |
- |
- spdy_stream1->set_spdy_headers(headers.Pass()); |
- EXPECT_TRUE(spdy_stream1->HasUrl()); |
- spdy_stream1->SendRequest(false); |
- |
- // Set up the TaskObserver to verify SpdySession::DoRead doesn't post a task. |
- SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead"); |
- |
- // Run until 1st read. |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- data.RunFor(2); |
- EXPECT_EQ(1u, spdy_stream1->stream_id()); |
- EXPECT_EQ(0u, observer.executed_count()); |
- |
- // Read all the data and verify SpdySession::DoRead has not posted a task. |
- data.RunFor(4); |
- |
- // Verify task observer's executed_count is zero, which indicates DoRead read |
- // all the available data. |
- EXPECT_EQ(0u, observer.executed_count()); |
- EXPECT_TRUE(data.at_write_eof()); |
- EXPECT_TRUE(data.at_read_eof()); |
-} |
- |
-// Test that SpdySession::DoRead yields while reading the data. This test makes |
-// 32k + 1 bytes of data available on the socket for reading. It then verifies |
-// that DoRead has yielded even though there is data available for it to read |
-// (i.e, socket()->Read didn't return ERR_IO_PENDING during socket reads). |
-TEST_F(SpdySessionSpdy2Test, TestYieldingDuringReadData) { |
- MockConnect connect_data(SYNCHRONOUS, OK); |
- BufferedSpdyFramer framer(2, false); |
- |
- scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); |
- MockWrite writes[] = { |
- CreateMockWrite(*req1, 0), |
- }; |
- |
- // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size). |
- ASSERT_EQ(32 * 1024, kMaxReadBytes); |
- const int kPayloadSize = |
- kMaxReadBytes / 4 - framer.GetControlFrameHeaderSize(); |
- TestDataStream test_stream; |
- scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); |
- char* payload_data = payload->data(); |
- test_stream.GetBytes(payload_data, kPayloadSize); |
- |
- scoped_ptr<SpdyFrame> partial_data_frame( |
- framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); |
- scoped_ptr<SpdyFrame> finish_data_frame( |
- framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN)); |
- |
- scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); |
- |
- // Write 1 byte more than kMaxReadBytes to check that DoRead yields. |
- MockRead reads[] = { |
- CreateMockRead(*resp1, 1), |
- CreateMockRead(*partial_data_frame, 2), |
- CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), |
- CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), |
- CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS), |
- CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS), |
- MockRead(ASYNC, 0, 7) // EOF |
- }; |
- |
- // Create SpdySession and SpdyStream and send the request. |
- DeterministicSocketData data(reads, arraysize(reads), |
- writes, arraysize(writes)); |
- data.set_connect_data(connect_data); |
- session_deps_.host_resolver->set_synchronous_mode(true); |
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); |
- |
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); |
- |
- CreateDeterministicNetworkSession(); |
- |
- scoped_refptr<SpdySession> session = CreateInitializedSession(); |
- |
- GURL url1("http://www.google.com"); |
- scoped_refptr<SpdyStream> spdy_stream1 = |
- CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog()); |
- ASSERT_TRUE(spdy_stream1.get() != NULL); |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- |
- scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
- (*headers)["method"] = "GET"; |
- (*headers)["scheme"] = url1.scheme(); |
- (*headers)["host"] = url1.host(); |
- (*headers)["url"] = url1.path(); |
- (*headers)["version"] = "HTTP/1.1"; |
- |
- spdy_stream1->set_spdy_headers(headers.Pass()); |
- EXPECT_TRUE(spdy_stream1->HasUrl()); |
- spdy_stream1->SendRequest(false); |
- |
- // Set up the TaskObserver to verify SpdySession::DoRead posts a task. |
- SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead"); |
- |
- // Run until 1st read. |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- data.RunFor(2); |
- EXPECT_EQ(1u, spdy_stream1->stream_id()); |
- EXPECT_EQ(0u, observer.executed_count()); |
- |
- // Read all the data and verify SpdySession::DoRead has posted a task. |
- data.RunFor(6); |
- |
- // Verify task observer's executed_count is 1, which indicates DoRead has |
- // posted only one task and thus yielded though there is data available for it |
- // to read. |
- EXPECT_EQ(1u, observer.executed_count()); |
- EXPECT_TRUE(data.at_write_eof()); |
- EXPECT_TRUE(data.at_read_eof()); |
-} |
- |
-// Test that SpdySession::DoRead() tests interactions of yielding + async, |
-// by doing the following MockReads. |
-// |
-// MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K |
-// ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K. |
-// |
-// The above reads 26K synchronously. Since that is less that 32K, we will |
-// attempt to read again. However, that DoRead() will return ERR_IO_PENDING |
-// (because of async read), so DoRead() will yield. When we come back, DoRead() |
-// will read the results from the async read, and rest of the data |
-// synchronously. |
-TEST_F(SpdySessionSpdy2Test, TestYieldingDuringAsyncReadData) { |
- MockConnect connect_data(SYNCHRONOUS, OK); |
- BufferedSpdyFramer framer(2, false); |
- |
- scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); |
- MockWrite writes[] = { |
- CreateMockWrite(*req1, 0), |
- }; |
- |
- // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size). |
- ASSERT_EQ(32 * 1024, kMaxReadBytes); |
- TestDataStream test_stream; |
- const int kEightKPayloadSize = |
- kMaxReadBytes / 4 - framer.GetControlFrameHeaderSize(); |
- scoped_refptr<net::IOBuffer> eightk_payload( |
- new net::IOBuffer(kEightKPayloadSize)); |
- char* eightk_payload_data = eightk_payload->data(); |
- test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize); |
- |
- // Build buffer of 2k size. |
- TestDataStream test_stream2; |
- const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024; |
- scoped_refptr<net::IOBuffer> twok_payload( |
- new net::IOBuffer(kTwoKPayloadSize)); |
- char* twok_payload_data = twok_payload->data(); |
- test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize); |
- |
- scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame( |
- 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE)); |
- scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame( |
- 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE)); |
- scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame( |
- 1, "h", 1, DATA_FLAG_FIN)); |
- |
- scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); |
- |
- MockRead reads[] = { |
- CreateMockRead(*resp1, 1), |
- CreateMockRead(*eightk_data_frame, 2), |
- CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS), |
- CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS), |
- CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS), |
- CreateMockRead(*eightk_data_frame, 6, ASYNC), |
- CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS), |
- CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS), |
- CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS), |
- CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS), |
- CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS), |
- MockRead(ASYNC, 0, 12) // EOF |
- }; |
- |
- // Create SpdySession and SpdyStream and send the request. |
- DeterministicSocketData data(reads, arraysize(reads), |
- writes, arraysize(writes)); |
- data.set_connect_data(connect_data); |
- session_deps_.host_resolver->set_synchronous_mode(true); |
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); |
- |
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); |
- |
- CreateDeterministicNetworkSession(); |
- |
- scoped_refptr<SpdySession> session = CreateInitializedSession(); |
- |
- GURL url1("http://www.google.com"); |
- scoped_refptr<SpdyStream> spdy_stream1 = |
- CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog()); |
- ASSERT_TRUE(spdy_stream1.get() != NULL); |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- |
- scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
- (*headers)["method"] = "GET"; |
- (*headers)["scheme"] = url1.scheme(); |
- (*headers)["host"] = url1.host(); |
- (*headers)["url"] = url1.path(); |
- (*headers)["version"] = "HTTP/1.1"; |
- |
- spdy_stream1->set_spdy_headers(headers.Pass()); |
- EXPECT_TRUE(spdy_stream1->HasUrl()); |
- spdy_stream1->SendRequest(false); |
- |
- // Set up the TaskObserver to monitor SpdySession::DoRead posting of tasks. |
- SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead"); |
- |
- // Run until 1st read. |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- data.RunFor(2); |
- EXPECT_EQ(1u, spdy_stream1->stream_id()); |
- EXPECT_EQ(0u, observer.executed_count()); |
- |
- // Read all the data and verify SpdySession::DoRead has posted a task. |
- data.RunFor(12); |
- |
- // Verify task observer's executed_count is 1, which indicates DoRead has |
- // posted only one task and thus yielded though there is data available for |
- // it to read. |
- EXPECT_EQ(1u, observer.executed_count()); |
- EXPECT_TRUE(data.at_write_eof()); |
- EXPECT_TRUE(data.at_read_eof()); |
-} |
- |
-// Send a GoAway frame when SpdySession is in DoLoop. If scoped_refptr to |
-// <SpdySession> is deleted from SpdySession::DoLoop(), we get a crash because |
-// GoAway could delete the SpdySession from the SpdySessionPool and the last |
-// reference to SpdySession. |
-TEST_F(SpdySessionSpdy2Test, GoAwayWhileInDoLoop) { |
- MockConnect connect_data(SYNCHRONOUS, OK); |
- BufferedSpdyFramer framer(2, false); |
- |
- scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); |
- MockWrite writes[] = { |
- CreateMockWrite(*req1, 0), |
- }; |
- |
- scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); |
- scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true)); |
- scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway()); |
- |
- MockRead reads[] = { |
- CreateMockRead(*resp1, 1), |
- CreateMockRead(*body1, 2), |
- CreateMockRead(*goaway, 3), |
- MockRead(ASYNC, 0, 4) // EOF |
- }; |
- |
- // Create SpdySession and SpdyStream and send the request. |
- DeterministicSocketData data(reads, arraysize(reads), |
- writes, arraysize(writes)); |
- data.set_connect_data(connect_data); |
- session_deps_.host_resolver->set_synchronous_mode(true); |
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); |
- |
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); |
- |
- CreateDeterministicNetworkSession(); |
- |
- scoped_refptr<SpdySession> session = CreateInitializedSession(); |
- |
- GURL url1("http://www.google.com"); |
- scoped_refptr<SpdyStream> spdy_stream1 = |
- CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog()); |
- ASSERT_TRUE(spdy_stream1.get() != NULL); |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- |
- scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
- (*headers)["method"] = "GET"; |
- (*headers)["scheme"] = url1.scheme(); |
- (*headers)["host"] = url1.host(); |
- (*headers)["url"] = url1.path(); |
- (*headers)["version"] = "HTTP/1.1"; |
- |
- spdy_stream1->set_spdy_headers(headers.Pass()); |
- EXPECT_TRUE(spdy_stream1->HasUrl()); |
- spdy_stream1->SendRequest(false); |
- |
- // Run until 1st read. |
- EXPECT_EQ(0u, spdy_stream1->stream_id()); |
- data.RunFor(1); |
- EXPECT_EQ(1u, spdy_stream1->stream_id()); |
- |
- // Drop the reference to the session. |
- session = NULL; |
- |
- // Run until GoAway. |
- data.RunFor(2); |
- |
- // Drop the reference to the stream which deletes its reference to the |
- // SpdySession. Only references to SpdySession are held by DoLoop and |
- // SpdySessionPool. If DoLoop doesn't hold the reference, we get a crash if |
- // SpdySession is deleted from the SpdySessionPool. |
- spdy_stream1 = NULL; |
- |
- data.RunFor(2); |
- EXPECT_TRUE(data.at_write_eof()); |
- EXPECT_TRUE(data.at_read_eof()); |
-} |
- |
// Within this framework, a SpdySession should be initialized with |
// flow control disabled and with protocol version 2. |
TEST_F(SpdySessionSpdy2Test, ProtocolNegotiation) { |