summaryrefslogtreecommitdiffstats
path: root/chromium/net/spdy/spdy_session_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/spdy/spdy_session_unittest.cc')
-rw-r--r--chromium/net/spdy/spdy_session_unittest.cc957
1 files changed, 705 insertions, 252 deletions
diff --git a/chromium/net/spdy/spdy_session_unittest.cc b/chromium/net/spdy/spdy_session_unittest.cc
index 2f185c7c01a..7145fc81027 100644
--- a/chromium/net/spdy/spdy_session_unittest.cc
+++ b/chromium/net/spdy/spdy_session_unittest.cc
@@ -107,7 +107,7 @@ class SpdySessionTest : public PlatformTest,
test_url_(kTestUrl),
test_host_port_pair_(kTestHost, kTestPort),
key_(test_host_port_pair_, ProxyServer::Direct(),
- kPrivacyModeDisabled) {
+ PRIVACY_MODE_DISABLED) {
}
virtual ~SpdySessionTest() {
@@ -182,16 +182,19 @@ INSTANTIATE_TEST_CASE_P(
NextProto,
SpdySessionTest,
testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
- kProtoHTTP2Draft04));
+ kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
// Try to create a SPDY session that will fail during
// initialization. Nothing should blow up.
TEST_P(SpdySessionTest, InitialReadError) {
CreateDeterministicNetworkSession();
- TryCreateFakeSpdySessionExpectingFailure(
- spdy_session_pool_, key_, ERR_FAILED);
+ base::WeakPtr<SpdySession> session = TryCreateFakeSpdySessionExpectingFailure(
+ spdy_session_pool_, key_, ERR_CONNECTION_CLOSED);
+ EXPECT_TRUE(session);
+ // Flush the read.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(session);
}
namespace {
@@ -238,9 +241,6 @@ TEST_P(SpdySessionTest, PendingStreamCancellingAnother) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -280,12 +280,9 @@ TEST_P(SpdySessionTest, PendingStreamCancellingAnother) {
session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult());
-
- data.RunFor(1);
}
-// A session receiving a GOAWAY frame with no active streams should
-// immediately close.
+// A session receiving a GOAWAY frame with no active streams should close.
TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -298,9 +295,6 @@ TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -312,9 +306,8 @@ TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
// Read and process the GOAWAY frame.
data.RunFor(1);
-
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
-
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -332,16 +325,16 @@ TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
data.StopAfter(1);
- TryCreateInsecureSpdySessionExpectingFailure(
- http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog());
+ base::WeakPtr<SpdySession> session =
+ TryCreateInsecureSpdySessionExpectingFailure(
+ http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(session);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
}
@@ -369,9 +362,6 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -379,7 +369,7 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, MEDIUM, BoundNetLog());
@@ -417,12 +407,13 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
EXPECT_EQ(NULL, spdy_stream2.get());
EXPECT_TRUE(session->IsStreamActive(1));
- EXPECT_FALSE(session->IsClosed());
+ EXPECT_TRUE(session->IsGoingAway());
// Should close the session.
spdy_stream1->Close();
EXPECT_EQ(NULL, spdy_stream1.get());
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -453,9 +444,6 @@ TEST_P(SpdySessionTest, GoAwayTwice) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -463,7 +451,7 @@ TEST_P(SpdySessionTest, GoAwayTwice) {
EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, MEDIUM, BoundNetLog());
@@ -500,13 +488,12 @@ TEST_P(SpdySessionTest, GoAwayTwice) {
EXPECT_FALSE(session->IsStreamActive(3));
EXPECT_EQ(NULL, spdy_stream2.get());
EXPECT_TRUE(session->IsStreamActive(1));
-
- EXPECT_FALSE(session->IsClosed());
+ EXPECT_TRUE(session->IsGoingAway());
// Read and process the second GOAWAY frame, which should close the
// session.
data.RunFor(1);
-
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -535,9 +522,6 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -545,7 +529,7 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, MEDIUM, BoundNetLog());
@@ -582,19 +566,85 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
EXPECT_FALSE(session->IsStreamActive(3));
EXPECT_EQ(NULL, spdy_stream2.get());
EXPECT_TRUE(session->IsStreamActive(1));
-
- EXPECT_FALSE(session->IsClosed());
+ EXPECT_TRUE(session->IsGoingAway());
session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
-
EXPECT_EQ(NULL, spdy_stream1.get());
+
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(session == NULL);
+}
+
+// Process a joint read buffer which causes the session to begin draining, and
+// then processes a GOAWAY. The session should gracefully drain. Regression test
+// for crbug.com/379469
+TEST_P(SpdySessionTest, GoAwayWhileDraining) {
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0),
+ };
+
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+ scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ size_t joint_size = goaway->size() * 2 + body->size();
+
+ // Compose interleaved |goaway| and |body| frames into a single read.
+ scoped_ptr<char[]> buffer(new char[joint_size]);
+ {
+ size_t out = 0;
+ memcpy(&buffer[out], goaway->data(), goaway->size());
+ out += goaway->size();
+ memcpy(&buffer[out], body->data(), body->size());
+ out += body->size();
+ memcpy(&buffer[out], goaway->data(), goaway->size());
+ out += goaway->size();
+ ASSERT_EQ(out, joint_size);
+ }
+ SpdyFrame joint_frames(buffer.get(), joint_size, false);
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), CreateMockRead(joint_frames, 2),
+ MockRead(ASYNC, 0, 3) // EOF
+ };
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ DeterministicSocketData data(
+ reads, arraysize(reads), writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ CreateDeterministicNetworkSession();
+ base::WeakPtr<SpdySession> session =
+ CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
+
+ GURL url(kDefaultURL);
+ base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ scoped_ptr<SpdyHeaderBlock> headers(
+ spdy_util_.ConstructGetHeaderBlock(url.spec()));
+ spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
+
+ data.RunFor(3);
+ base::MessageLoop::current()->RunUntilIdle();
+
+ // Stream and session closed gracefully.
+ EXPECT_TRUE(delegate.StreamIsClosed());
+ EXPECT_EQ(OK, delegate.WaitForClose());
+ EXPECT_EQ(kUploadData, delegate.TakeReceivedData());
EXPECT_TRUE(session == NULL);
}
// Try to create a stream after receiving a GOAWAY frame. It should
// fail.
TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
- const char kStreamUrl[] = "http://www.google.com";
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
@@ -613,9 +663,6 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -623,7 +670,7 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
- GURL url(kStreamUrl);
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, MEDIUM, BoundNetLog());
@@ -662,13 +709,12 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
// Receiving a SYN_STREAM frame after a GOAWAY frame should result in
// the stream being refused.
TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
- const char kStreamUrl[] = "http://www.google.com";
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
scoped_ptr<SpdyFrame>
- push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
+ push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kDefaultURL));
MockRead reads[] = {
CreateMockRead(*goaway, 1),
CreateMockRead(*push, 2),
@@ -687,9 +733,6 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -697,7 +740,7 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
- GURL url(kStreamUrl);
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, MEDIUM, BoundNetLog());
@@ -724,7 +767,75 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
// Read and process the SYN_STREAM frame, the subsequent RST_STREAM,
// and EOF.
data.RunFor(3);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(session == NULL);
+}
+
+// A session observing a network change with active streams should close
+// when the last active stream is closed.
+TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) {
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ MockRead reads[] = {
+ MockRead(ASYNC, 0, 1) // EOF
+ };
+ scoped_ptr<SpdyFrame> req1(
+ spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
+ MockWrite writes[] = {
+ CreateMockWrite(*req1, 0),
+ };
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ CreateDeterministicNetworkSession();
+
+ base::WeakPtr<SpdySession> session =
+ CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
+
+ EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
+
+ base::WeakPtr<SpdyStream> spdy_stream =
+ CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session,
+ GURL(kDefaultURL), MEDIUM, BoundNetLog());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ scoped_ptr<SpdyHeaderBlock> headers(
+ spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
+
+ spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
+
+ data.RunFor(1);
+
+ EXPECT_EQ(1u, spdy_stream->stream_id());
+
+ EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
+ spdy_session_pool_->OnIPAddressChanged();
+
+ // The SpdySessionPool behavior differs based on how the OSs reacts to
+ // network changes; see comment in SpdySessionPool::OnIPAddressChanged().
+#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
+ // For OSs where the TCP connections will close upon relevant network
+ // changes, SpdySessionPool doesn't need to force them to close, so in these
+ // cases verify the session has become unavailable but remains open and the
+ // pre-existing stream is still active.
+ EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
+
+ EXPECT_TRUE(session->IsGoingAway());
+
+ EXPECT_TRUE(session->IsStreamActive(1));
+
+ // Should close the session.
+ spdy_stream->Close();
+#endif
+ EXPECT_EQ(NULL, spdy_stream.get());
+
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -733,12 +844,12 @@ TEST_P(SpdySessionTest, ClientPing) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1));
+ scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true));
MockRead reads[] = {
CreateMockRead(*read_ping, 1),
MockRead(ASYNC, 0, 0, 2) // EOF
};
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
MockWrite writes[] = {
CreateMockWrite(*write_ping, 0),
};
@@ -747,9 +858,6 @@ TEST_P(SpdySessionTest, ClientPing) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -791,12 +899,12 @@ TEST_P(SpdySessionTest, ServerPing) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2));
+ scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2, false));
MockRead reads[] = {
CreateMockRead(*read_ping),
MockRead(SYNCHRONOUS, 0, 0) // EOF
};
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2));
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2, true));
MockWrite writes[] = {
CreateMockWrite(*write_ping),
};
@@ -805,9 +913,6 @@ TEST_P(SpdySessionTest, ServerPing) {
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -838,7 +943,7 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) {
session_deps_.time_func = TheNearFuture;
MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
MockWrite writes[] = {
@@ -857,15 +962,12 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, LOWEST, BoundNetLog());
@@ -884,45 +986,245 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) {
session->CloseSessionOnError(ERR_ABORTED, "Aborting");
}
-TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
+TEST_P(SpdySessionTest, StreamIdSpaceExhausted) {
+ const SpdyStreamId kLastStreamId = 0x7fffffff;
session_deps_.host_resolver->set_synchronous_mode(true);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
- session_deps_.time_func = TheNearFuture;
+ // Test setup: |stream_hi_water_mark_| and |max_concurrent_streams_| are
+ // fixed to allow for two stream ID assignments, and three concurrent
+ // streams. Four streams are started, and two are activated. Verify the
+ // session goes away, and that the created (but not activated) and
+ // stalled streams are aborted. Also verify the activated streams complete,
+ // at which point the session closes.
+
+ scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyGet(
+ NULL, 0, false, kLastStreamId - 2, MEDIUM, true));
+ scoped_ptr<SpdyFrame> req2(
+ spdy_util_.ConstructSpdyGet(NULL, 0, false, kLastStreamId, MEDIUM, true));
+
+ MockWrite writes[] = {
+ CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
+ };
+
+ scoped_ptr<SpdyFrame> resp1(
+ spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId - 2));
+ scoped_ptr<SpdyFrame> resp2(
+ spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId));
+
+ scoped_ptr<SpdyFrame> body1(
+ spdy_util_.ConstructSpdyBodyFrame(kLastStreamId - 2, true));
+ scoped_ptr<SpdyFrame> body2(
+ spdy_util_.ConstructSpdyBodyFrame(kLastStreamId, true));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp1, 2), CreateMockRead(*resp2, 3),
+ CreateMockRead(*body1, 4), CreateMockRead(*body2, 5),
+ MockRead(ASYNC, 0, 6) // EOF
+ };
+
+ DeterministicSocketData data(
+ reads, arraysize(reads), writes, arraysize(writes));
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ CreateDeterministicNetworkSession();
+ base::WeakPtr<SpdySession> session =
+ CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
+
+ // Fix stream_hi_water_mark_ to allow for two stream activations.
+ session->stream_hi_water_mark_ = kLastStreamId - 2;
+ // Fix max_concurrent_streams to allow for three stream creations.
+ session->max_concurrent_streams_ = 3;
+
+ // Create three streams synchronously, and begin a fourth (which is stalled).
+ GURL url(kDefaultURL);
+ base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
+ test::StreamDelegateDoNothing delegate1(stream1);
+ stream1->SetDelegate(&delegate1);
+
+ base::WeakPtr<SpdyStream> stream2 = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
+ test::StreamDelegateDoNothing delegate2(stream2);
+ stream2->SetDelegate(&delegate2);
+
+ base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
+ test::StreamDelegateDoNothing delegate3(stream3);
+ stream3->SetDelegate(&delegate3);
+
+ SpdyStreamRequest request4;
+ TestCompletionCallback callback4;
+ EXPECT_EQ(ERR_IO_PENDING,
+ request4.StartRequest(SPDY_REQUEST_RESPONSE_STREAM,
+ session,
+ url,
+ MEDIUM,
+ BoundNetLog(),
+ callback4.callback()));
+
+ // Streams 1-3 were created. 4th is stalled. No streams are active yet.
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(3u, session->num_created_streams());
+ EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
+
+ // Activate stream 1. One ID remains available.
+ stream1->SendRequestHeaders(
+ scoped_ptr<SpdyHeaderBlock>(
+ spdy_util_.ConstructGetHeaderBlock(url.spec())),
+ NO_MORE_DATA_TO_SEND);
+ data.RunFor(1);
+
+ EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id());
+ EXPECT_EQ(1u, session->num_active_streams());
+ EXPECT_EQ(2u, session->num_created_streams());
+ EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
+
+ // Activate stream 2. ID space is exhausted.
+ stream2->SendRequestHeaders(
+ scoped_ptr<SpdyHeaderBlock>(
+ spdy_util_.ConstructGetHeaderBlock(url.spec())),
+ NO_MORE_DATA_TO_SEND);
+ data.RunFor(1);
+
+ // Active streams remain active.
+ EXPECT_EQ(kLastStreamId, stream2->stream_id());
+ EXPECT_EQ(2u, session->num_active_streams());
+
+ // Session is going away. Created and stalled streams were aborted.
+ EXPECT_EQ(SpdySession::STATE_GOING_AWAY, session->availability_state_);
+ EXPECT_EQ(ERR_ABORTED, delegate3.WaitForClose());
+ EXPECT_EQ(ERR_ABORTED, callback4.WaitForResult());
+ EXPECT_EQ(0u, session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
+
+ // Read responses on remaining active streams.
+ data.RunFor(4);
+ EXPECT_EQ(OK, delegate1.WaitForClose());
+ EXPECT_EQ(kUploadData, delegate1.TakeReceivedData());
+ EXPECT_EQ(OK, delegate2.WaitForClose());
+ EXPECT_EQ(kUploadData, delegate2.TakeReceivedData());
+
+ // Session was destroyed.
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_FALSE(session.get());
+}
+
+// Verifies that an unstalled pending stream creation racing with a new stream
+// creation doesn't violate the maximum stream concurrency. Regression test for
+// crbug.com/373858.
+TEST_P(SpdySessionTest, UnstallRacesWithStreamCreation) {
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
+ };
+
+ StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ data.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
CreateNetworkSession();
+ base::WeakPtr<SpdySession> session =
+ CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
+ // Fix max_concurrent_streams to allow for one open stream.
+ session->max_concurrent_streams_ = 1;
+
+ // Create two streams: one synchronously, and one which stalls.
+ GURL url(kDefaultURL);
+ base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
+
+ SpdyStreamRequest request2;
+ TestCompletionCallback callback2;
+ EXPECT_EQ(ERR_IO_PENDING,
+ request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM,
+ session,
+ url,
+ MEDIUM,
+ BoundNetLog(),
+ callback2.callback()));
+
+ EXPECT_EQ(1u, session->num_created_streams());
+ EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
+
+ // Cancel the first stream. A callback to unstall the second stream was
+ // posted. Don't run it yet.
+ stream1->Cancel();
+
+ EXPECT_EQ(0u, session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
+
+ // Create a third stream prior to the second stream's callback.
+ base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
+
+ EXPECT_EQ(1u, session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
+
+ // NOW run the message loop. The unstalled stream will re-stall itself.
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_EQ(1u, session->num_created_streams());
+ EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
+
+ // Cancel the third stream and run the message loop. Verify that the second
+ // stream creation now completes.
+ stream3->Cancel();
+ base::MessageLoop::current()->RunUntilIdle();
+
+ EXPECT_EQ(1u, session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(OK, callback2.WaitForResult());
+}
+
+TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
+ session_deps_.host_resolver->set_synchronous_mode(true);
+ session_deps_.time_func = TheNearFuture;
+
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
+
+ scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
+ NULL, 0, 2, 1, "http://www.google.com/a.dat"));
+ scoped_ptr<SpdyFrame> push_a_body(
+ spdy_util_.ConstructSpdyBodyFrame(2, false));
+ scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
+ NULL, 0, 4, 1, "http://www.google.com/b.dat"));
+ MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4)};
+ MockRead reads[] = {
+ CreateMockRead(*push_a, 1), CreateMockRead(*push_a_body, 2),
+ CreateMockRead(*push_b, 3), MockRead(ASYNC, 0, 5), // EOF
+ };
+ DeterministicSocketData data(
+ reads, arraysize(reads), writes, arraysize(writes));
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
- CreateFakeSpdySession(spdy_session_pool_, key_);
+ CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- session->buffered_spdy_framer_.reset(
- new BufferedSpdyFramer(spdy_util_.spdy_version(), false));
-
- // Create the associated stream and add to active streams.
- scoped_ptr<SpdyHeaderBlock> request_headers(
- spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
-
- scoped_ptr<SpdyStream> stream(new SpdyStream(SPDY_REQUEST_RESPONSE_STREAM,
- session,
- GURL(),
- DEFAULT_PRIORITY,
- kSpdyStreamInitialWindowSize,
- kSpdyStreamInitialWindowSize,
- session->net_log_));
- stream->SendRequestHeaders(request_headers.Pass(), NO_MORE_DATA_TO_SEND);
- SpdyStream* stream_ptr = stream.get();
- session->InsertCreatedStream(stream.Pass());
- stream = session->ActivateCreatedStream(stream_ptr);
- session->InsertActivatedStream(stream.Pass());
+ // Process the principal request, and the first push stream request & body.
+ GURL url(kDefaultURL);
+ base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
- SpdyHeaderBlock headers;
- spdy_util_.AddUrlToHeaderBlock("http://www.google.com/a.dat", &headers);
+ scoped_ptr<SpdyHeaderBlock> headers(
+ spdy_util_.ConstructGetHeaderBlock(url.spec()));
+ spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
- // OnSynStream() expects |in_io_loop_| to be true.
- session->in_io_loop_ = true;
- session->OnSynStream(2, 1, 0, 0, true, false, headers);
- session->in_io_loop_ = false;
+ data.RunFor(3);
// Verify that there is one unclaimed push stream.
EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
@@ -931,19 +1233,37 @@ TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
GURL("http://www.google.com/a.dat"));
EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
- // Shift time to expire the push stream.
- g_time_delta = base::TimeDelta::FromSeconds(301);
+ if (session->flow_control_state_ ==
+ SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) {
+ // Unclaimed push body consumed bytes from the session window.
+ EXPECT_EQ(kSpdySessionInitialWindowSize - kUploadDataSize,
+ session->session_recv_window_size_);
+ EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+ }
- spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat", &headers);
- session->in_io_loop_ = true;
- session->OnSynStream(4, 1, 0, 0, true, false, headers);
- session->in_io_loop_ = false;
+ // Shift time to expire the push stream. Read the second SYN_STREAM,
+ // and verify a RST_STREAM was written.
+ g_time_delta = base::TimeDelta::FromSeconds(301);
+ data.RunFor(2);
// Verify that the second pushed stream evicted the first pushed stream.
EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
iter = session->unclaimed_pushed_streams_.find(
GURL("http://www.google.com/b.dat"));
EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
+
+ if (session->flow_control_state_ ==
+ SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) {
+ // Verify that the session window reclaimed the evicted stream body.
+ EXPECT_EQ(kSpdySessionInitialWindowSize,
+ session->session_recv_window_size_);
+ EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_);
+ }
+
+ // Read and process EOF.
+ data.RunFor(1);
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_TRUE(session == NULL);
}
TEST_P(SpdySessionTest, FailedPing) {
@@ -951,17 +1271,18 @@ TEST_P(SpdySessionTest, FailedPing) {
MockConnect connect_data(SYNCHRONOUS, OK);
MockRead reads[] = {
- MockRead(ASYNC, 0, 0, 0) // EOF
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
};
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
- DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
+ scoped_ptr<SpdyFrame> goaway(
+ spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Failed ping."));
+ MockWrite writes[] = {CreateMockWrite(*write_ping), CreateMockWrite(*goaway)};
+ StaticSocketDataProvider data(
+ reads, arraysize(reads), writes, arraysize(writes));
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
-
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
- CreateDeterministicNetworkSession();
+ CreateNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
@@ -977,13 +1298,13 @@ TEST_P(SpdySessionTest, FailedPing) {
session->set_hung_interval(base::TimeDelta::FromSeconds(0));
// Send a PING frame.
- session->WritePingFrame(1);
+ session->WritePingFrame(1, false);
EXPECT_LT(0, session->pings_in_flight());
EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
EXPECT_TRUE(session->check_ping_status_pending());
// Assert session is not closed.
- EXPECT_FALSE(session->IsClosed());
+ EXPECT_TRUE(session->IsAvailable());
EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams());
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
@@ -992,11 +1313,10 @@ TEST_P(SpdySessionTest, FailedPing) {
base::TimeTicks now = base::TimeTicks::Now();
session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1);
session->CheckPingStatus(now);
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
-
- data.RunFor(1);
EXPECT_EQ(NULL, spdy_stream1.get());
}
@@ -1020,14 +1340,17 @@ TEST_P(SpdySessionTest, OnSettings) {
MockRead(ASYNC, 0, 1),
};
- DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
+ scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+ MockWrite writes[] = {
+ CreateMockWrite(*settings_ack, 2),
+ };
+
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -1054,6 +1377,11 @@ TEST_P(SpdySessionTest, OnSettings) {
EXPECT_EQ(OK, stream_releaser.WaitForResult());
data.RunFor(1);
+ if (spdy_util_.spdy_version() >= SPDY4) {
+ // Allow the SETTINGS+ACK to write, so the session finishes draining.
+ data.RunFor(1);
+ }
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -1062,6 +1390,11 @@ TEST_P(SpdySessionTest, OnSettings) {
// also clears the persisted data. Verify that persisted data is
// correct.
TEST_P(SpdySessionTest, ClearSettings) {
+ if (spdy_util_.spdy_version() >= SPDY4) {
+ // SPDY4 doesn't include settings persistence, or a CLEAR_SETTINGS flag.
+ // Flag 0x1, CLEAR_SETTINGS in SPDY3, is instead settings ACK in SPDY4.
+ return;
+ }
session_deps_.host_resolver->set_synchronous_mode(true);
SettingsMap new_settings;
@@ -1082,9 +1415,6 @@ TEST_P(SpdySessionTest, ClearSettings) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
// Initialize the SpdySetting with the default.
@@ -1153,9 +1483,6 @@ TEST_P(SpdySessionTest, CancelPendingCreateStream) {
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateNetworkSession();
// Initialize the SpdySetting with 1 max concurrent streams.
@@ -1229,7 +1556,7 @@ TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
kSessionFlowControlStreamId,
kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
std::vector<MockWrite> writes;
- if (GetParam() == kProtoHTTP2Draft04) {
+ if (GetParam() == kProtoSPDY4) {
writes.push_back(
MockWrite(ASYNC,
kHttp2ConnectionHeaderPrefix,
@@ -1256,9 +1583,6 @@ TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateNetworkSession();
spdy_session_pool_->http_server_properties()->SetSpdySetting(
@@ -1309,9 +1633,6 @@ TEST_P(SpdySessionTest, Initialize) {
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -1340,7 +1661,7 @@ TEST_P(SpdySessionTest, Initialize) {
EXPECT_NE(log.bound().source().id, socket_source.id);
}
-TEST_P(SpdySessionTest, CloseSessionOnError) {
+TEST_P(SpdySessionTest, NetLogOnSessionGoaway) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
@@ -1354,9 +1675,6 @@ TEST_P(SpdySessionTest, CloseSessionOnError) {
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateNetworkSession();
CapturingBoundNetLog log;
@@ -1385,6 +1703,53 @@ TEST_P(SpdySessionTest, CloseSessionOnError) {
CapturingNetLog::CapturedEntry entry = entries[pos];
int error_code = 0;
ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
+ EXPECT_EQ(OK, error_code);
+ } else {
+ ADD_FAILURE();
+ }
+}
+
+TEST_P(SpdySessionTest, NetLogOnSessionEOF) {
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, 0, 0) // EOF
+ };
+
+ StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+ data.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ CreateNetworkSession();
+
+ CapturingBoundNetLog log;
+ base::WeakPtr<SpdySession> session =
+ CreateInsecureSpdySession(http_session_, key_, log.bound());
+ EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
+
+ // Flush the read completion task.
+ base::MessageLoop::current()->RunUntilIdle();
+
+ EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
+ EXPECT_TRUE(session == NULL);
+
+ // Check that the NetLog was filled reasonably.
+ net::CapturingNetLog::CapturedEntryList entries;
+ log.GetEntries(&entries);
+ EXPECT_LT(0u, entries.size());
+
+ // Check that we logged SPDY_SESSION_CLOSE correctly.
+ int pos =
+ net::ExpectLogContainsSomewhere(entries,
+ 0,
+ net::NetLog::TYPE_SPDY_SESSION_CLOSE,
+ net::NetLog::PHASE_NONE);
+
+ if (pos < static_cast<int>(entries.size())) {
+ CapturingNetLog::CapturedEntry entry = entries[pos];
+ int error_code = 0;
+ ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code);
} else {
ADD_FAILURE();
@@ -1429,15 +1794,12 @@ TEST_P(SpdySessionTest, OutOfOrderSynStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream_lowest =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
@@ -1502,15 +1864,12 @@ TEST_P(SpdySessionTest, CancelStream) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, HIGHEST, BoundNetLog());
@@ -1519,7 +1878,7 @@ TEST_P(SpdySessionTest, CancelStream) {
test::StreamDelegateDoNothing delegate1(spdy_stream1);
spdy_stream1->SetDelegate(&delegate1);
- GURL url2("http://www.google.com");
+ GURL url2(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url2, LOWEST, BoundNetLog());
@@ -1575,22 +1934,19 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, url1, HIGHEST, BoundNetLog());
ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- GURL url2("http://www.google.com");
+ GURL url2(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, url2, LOWEST, BoundNetLog());
@@ -1626,6 +1982,7 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
EXPECT_TRUE(delegate1.StreamIsClosed());
EXPECT_TRUE(delegate2.StreamIsClosed());
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -1649,22 +2006,19 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, url1, HIGHEST, BoundNetLog());
ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- GURL url2("http://www.google.com");
+ GURL url2(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, url2, LOWEST, BoundNetLog());
@@ -1702,6 +2056,7 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
EXPECT_TRUE(delegate1.StreamIsClosed());
EXPECT_TRUE(delegate2.StreamIsClosed());
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -1730,22 +2085,19 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, MEDIUM, BoundNetLog());
ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- GURL url2("http://www.google.com");
+ GURL url2(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url2, MEDIUM, BoundNetLog());
@@ -1786,6 +2138,7 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
EXPECT_TRUE(delegate1.StreamIsClosed());
EXPECT_TRUE(delegate2.StreamIsClosed());
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -1814,22 +2167,19 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, MEDIUM, BoundNetLog());
ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- GURL url2("http://www.google.com");
+ GURL url2(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url2, MEDIUM, BoundNetLog());
@@ -1872,6 +2222,7 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
EXPECT_TRUE(delegate1.StreamIsClosed());
EXPECT_TRUE(delegate2.StreamIsClosed());
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
@@ -1886,7 +2237,7 @@ class SessionClosingDelegate : public test::StreamDelegateDoNothing {
virtual ~SessionClosingDelegate() {}
virtual void OnClose(int status) OVERRIDE {
- session_to_close_->CloseSessionOnError(ERR_ABORTED, "Aborted");
+ session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error");
}
private:
@@ -1902,27 +2253,31 @@ TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+ scoped_ptr<SpdyFrame> goaway(
+ spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Error"));
+ // The GOAWAY has higher-priority than the RST_STREAM, and is written first
+ // despite being queued second.
MockWrite writes[] = {
- CreateMockWrite(*req, 0),
+ CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 1),
+ CreateMockWrite(*rst, 2),
};
MockRead reads[] = {
- MockRead(ASYNC, 0, 1) // EOF
+ MockRead(ASYNC, 0, 3) // EOF
};
DeterministicSocketData data(reads, arraysize(reads),
writes, arraysize(writes));
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, MEDIUM, BoundNetLog());
@@ -1949,10 +2304,13 @@ TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
EXPECT_EQ(NULL, spdy_stream.get());
EXPECT_TRUE(delegate.StreamIsClosed());
+
+ data.RunFor(2); // Write the RST_STREAM & GOAWAY.
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(session == NULL);
}
-TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
+TEST_P(SpdySessionTest, DISABLED_VerifyDomainAuthentication) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
@@ -1994,7 +2352,8 @@ TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
}
-TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) {
+// TODO(rch): re-enable this.
+TEST_P(SpdySessionTest, DISABLED_ConnectionPooledWithTlsChannelId) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
@@ -2048,6 +2407,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
new_settings[kSpdySettingsIds1] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+ scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
scoped_ptr<SpdyFrame> req1(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
scoped_ptr<SpdyFrame> req2(
@@ -2055,9 +2415,10 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
scoped_ptr<SpdyFrame> req3(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
MockWrite writes[] = {
- CreateMockWrite(*req1, 1),
- CreateMockWrite(*req2, 4),
- CreateMockWrite(*req3, 7),
+ CreateMockWrite(*settings_ack, 1),
+ CreateMockWrite(*req1, 2),
+ CreateMockWrite(*req2, 5),
+ CreateMockWrite(*req3, 8),
};
// Set up the socket so we read a SETTINGS frame that sets max concurrent
@@ -2076,13 +2437,13 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
MockRead reads[] = {
CreateMockRead(*settings_frame),
- CreateMockRead(*resp1, 2),
- CreateMockRead(*body1, 3),
- CreateMockRead(*resp2, 5),
- CreateMockRead(*body2, 6),
- CreateMockRead(*resp3, 8),
- CreateMockRead(*body3, 9),
- MockRead(ASYNC, 0, 10) // EOF
+ CreateMockRead(*resp1, 3),
+ CreateMockRead(*body1, 4),
+ CreateMockRead(*resp2, 6),
+ CreateMockRead(*body2, 7),
+ CreateMockRead(*resp3, 9),
+ CreateMockRead(*body3, 10),
+ MockRead(ASYNC, 0, 11) // EOF
};
DeterministicSocketData data(reads, arraysize(reads),
@@ -2090,9 +2451,6 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -2101,7 +2459,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
// Read the settings frame.
data.RunFor(1);
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, LOWEST, BoundNetLog());
@@ -2111,7 +2469,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
spdy_stream1->SetDelegate(&delegate1);
TestCompletionCallback callback2;
- GURL url2("http://www.google.com");
+ GURL url2(kDefaultURL);
SpdyStreamRequest request2;
ASSERT_EQ(ERR_IO_PENDING,
request2.StartRequest(
@@ -2119,7 +2477,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
session, url2, LOWEST, BoundNetLog(), callback2.callback()));
TestCompletionCallback callback3;
- GURL url3("http://www.google.com");
+ GURL url3(kDefaultURL);
SpdyStreamRequest request3;
ASSERT_EQ(ERR_IO_PENDING,
request3.StartRequest(
@@ -2137,7 +2495,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
// Run until 1st stream is activated and then closed.
EXPECT_EQ(0u, delegate1.stream_id());
- data.RunFor(3);
+ data.RunFor(4);
EXPECT_EQ(NULL, spdy_stream1.get());
EXPECT_EQ(1u, delegate1.stream_id());
@@ -2213,9 +2571,6 @@ TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateNetworkSession();
base::WeakPtr<SpdySession> session =
@@ -2229,7 +2584,7 @@ TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
ASSERT_TRUE(spdy_stream != NULL);
}
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, url1, LOWEST, BoundNetLog());
@@ -2237,7 +2592,7 @@ TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
EXPECT_EQ(0u, spdy_stream1->stream_id());
TestCompletionCallback callback2;
- GURL url2("http://www.google.com");
+ GURL url2(kDefaultURL);
SpdyStreamRequest request2;
ASSERT_EQ(ERR_IO_PENDING,
request2.StartRequest(
@@ -2245,7 +2600,7 @@ TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
callback2.callback()));
TestCompletionCallback callback3;
- GURL url3("http://www.google.com");
+ GURL url3(kDefaultURL);
SpdyStreamRequest request3;
ASSERT_EQ(ERR_IO_PENDING,
request3.StartRequest(
@@ -2334,15 +2689,12 @@ TEST_P(SpdySessionTest, ReadDataWithoutYielding) {
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();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, MEDIUM, BoundNetLog());
@@ -2428,15 +2780,12 @@ TEST_P(SpdySessionTest, TestYieldingDuringReadData) {
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();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, MEDIUM, BoundNetLog());
@@ -2544,15 +2893,12 @@ TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) {
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();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, MEDIUM, BoundNetLog());
@@ -2618,15 +2964,12 @@ TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) {
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();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url1, MEDIUM, BoundNetLog());
@@ -2718,7 +3061,7 @@ TEST_P(SpdySessionTest, CloseOneIdleConnection) {
// Create an idle SPDY session.
SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
- kPrivacyModeDisabled);
+ PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session1 =
CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
EXPECT_FALSE(pool->IsStalled());
@@ -2778,14 +3121,14 @@ TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
// Create an idle SPDY session.
SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
- kPrivacyModeDisabled);
+ PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session1 =
CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
EXPECT_FALSE(pool->IsStalled());
// Set up an alias for the idle SPDY session, increasing its ref count to 2.
SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
- kPrivacyModeDisabled);
+ PRIVACY_MODE_DISABLED);
HostResolver::RequestInfo info(key2.host_port_pair());
AddressList addresses;
// Pre-populate the DNS cache, since a synchronous resolution is required in
@@ -2864,9 +3207,9 @@ TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
HttpNetworkSession::NORMAL_SOCKET_POOL);
// Create a SPDY session.
- GURL url1("http://www.google.com");
+ GURL url1(kDefaultURL);
SpdySessionKey key1(HostPortPair(url1.host(), 80),
- ProxyServer::Direct(), kPrivacyModeDisabled);
+ ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session1 =
CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
EXPECT_FALSE(pool->IsStalled());
@@ -2927,9 +3270,9 @@ TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
HostPortPair host_port_pair("www.google.com", 443);
SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeEnabled);
+ PRIVACY_MODE_ENABLED);
SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
+ PRIVACY_MODE_DISABLED);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
@@ -2968,7 +3311,7 @@ class StreamCreatingDelegate : public test::StreamDelegateDoNothing {
virtual ~StreamCreatingDelegate() {}
virtual void OnClose(int status) OVERRIDE {
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
ignore_result(
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session_, url, MEDIUM, BoundNetLog()));
@@ -3003,15 +3346,12 @@ TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- GURL url("http://www.google.com");
+ GURL url(kDefaultURL);
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
session, url, MEDIUM, BoundNetLog());
@@ -3065,15 +3405,17 @@ TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
MockRead(ASYNC, 0, 1) // EOF
};
- session_deps_.host_resolver->set_synchronous_mode(true);
+ scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+ MockWrite writes[] = {
+ CreateMockWrite(*settings_ack, 2),
+ };
- scoped_ptr<DeterministicSocketData> data(
- new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
- data->set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get());
+ session_deps_.host_resolver->set_synchronous_mode(true);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
CreateDeterministicNetworkSession();
@@ -3086,7 +3428,7 @@ TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
TestCompletionCallback callback1;
EXPECT_NE(spdy_stream1->send_window_size(), window_size);
- data->RunFor(1); // Process the SETTINGS frame, but not the EOF
+ data.RunFor(1); // Process the SETTINGS frame, but not the EOF
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
@@ -3134,9 +3476,6 @@ TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
@@ -3224,9 +3563,6 @@ TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) {
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
CreateDeterministicNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
@@ -3302,9 +3638,6 @@ TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
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();
base::WeakPtr<SpdySession> session =
@@ -3380,9 +3713,6 @@ TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
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();
base::WeakPtr<SpdySession> session =
@@ -3472,9 +3802,6 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
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();
base::WeakPtr<SpdySession> session =
@@ -3633,7 +3960,6 @@ void SpdySessionTest::RunResumeAfterUnstallTest(
EXPECT_TRUE(delegate.send_headers_completed());
EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
- EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version"));
EXPECT_EQ(std::string(), delegate.TakeReceivedData());
EXPECT_TRUE(data.at_write_eof());
}
@@ -3830,12 +4156,10 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
EXPECT_TRUE(delegate1.send_headers_completed());
EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
- EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
EXPECT_TRUE(delegate2.send_headers_completed());
EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
- EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
EXPECT_TRUE(data.at_write_eof());
@@ -4019,7 +4343,6 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
EXPECT_TRUE(delegate2.send_headers_completed());
EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
- EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
EXPECT_TRUE(delegate3.send_headers_completed());
@@ -4125,6 +4448,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
// Close the session (since we can't do it from within the delegate
// method, since it's in the stream's loop).
session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(session == NULL);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
@@ -4141,4 +4465,133 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
EXPECT_TRUE(data.at_write_eof());
}
+TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) {
+ if (GetParam() < kProtoSPDY31)
+ return;
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
+ scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+ 0,
+ GOAWAY_FLOW_CONTROL_ERROR,
+ "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than "
+ "the receive window size of 1"));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 3),
+ };
+
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), CreateMockRead(*body, 2),
+ };
+
+ DeterministicSocketData data(
+ reads, arraysize(reads), writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ CreateDeterministicNetworkSession();
+
+ base::WeakPtr<SpdySession> session =
+ CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
+
+ GURL url(kDefaultURL);
+ base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream.get() != NULL);
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ scoped_ptr<SpdyHeaderBlock> headers(
+ spdy_util_.ConstructGetHeaderBlock(url.spec()));
+ spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+
+ data.RunFor(1); // Write request.
+
+ // Put session on the edge of overflowing it's recv window.
+ session->session_recv_window_size_ = 1;
+
+ // Read response headers & body. Body overflows the session window, and a
+ // goaway is written.
+ data.RunFor(3);
+ base::MessageLoop::current()->RunUntilIdle();
+
+ EXPECT_EQ(ERR_SPDY_FLOW_CONTROL_ERROR, delegate.WaitForClose());
+ EXPECT_TRUE(session == NULL);
+}
+
+TEST_P(SpdySessionTest, SplitHeaders) {
+ GURL kStreamUrl("http://www.google.com/foo.dat");
+ SpdyHeaderBlock headers;
+ spdy_util_.AddUrlToHeaderBlock(kStreamUrl.spec(), &headers);
+ headers["alpha"] = "beta";
+
+ SpdyHeaderBlock request_headers;
+ SpdyHeaderBlock response_headers;
+
+ SplitPushedHeadersToRequestAndResponse(
+ headers, spdy_util_.spdy_version(), &request_headers, &response_headers);
+
+ SpdyHeaderBlock::const_iterator it = response_headers.find("alpha");
+ std::string alpha_val =
+ (it == response_headers.end()) ? std::string() : it->second;
+ EXPECT_EQ("beta", alpha_val);
+
+ GURL request_url =
+ GetUrlFromHeaderBlock(request_headers, spdy_util_.spdy_version(), true);
+ EXPECT_EQ(kStreamUrl, request_url);
+}
+
+TEST(MapFramerErrorToProtocolError, MapsValues) {
+ CHECK_EQ(
+ SPDY_ERROR_INVALID_CONTROL_FRAME,
+ MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
+ CHECK_EQ(
+ SPDY_ERROR_INVALID_DATA_FRAME_FLAGS,
+ MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS));
+ CHECK_EQ(
+ SPDY_ERROR_GOAWAY_FRAME_CORRUPT,
+ MapFramerErrorToProtocolError(SpdyFramer::SPDY_GOAWAY_FRAME_CORRUPT));
+ CHECK_EQ(SPDY_ERROR_UNEXPECTED_FRAME,
+ MapFramerErrorToProtocolError(SpdyFramer::SPDY_UNEXPECTED_FRAME));
+}
+
+TEST(MapFramerErrorToNetError, MapsValue) {
+ CHECK_EQ(ERR_SPDY_PROTOCOL_ERROR,
+ MapFramerErrorToNetError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
+ CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR,
+ MapFramerErrorToNetError(SpdyFramer::SPDY_COMPRESS_FAILURE));
+ CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR,
+ MapFramerErrorToNetError(SpdyFramer::SPDY_DECOMPRESS_FAILURE));
+ CHECK_EQ(
+ ERR_SPDY_FRAME_SIZE_ERROR,
+ MapFramerErrorToNetError(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
+}
+
+TEST(MapRstStreamStatusToProtocolError, MapsValues) {
+ CHECK_EQ(STATUS_CODE_PROTOCOL_ERROR,
+ MapRstStreamStatusToProtocolError(RST_STREAM_PROTOCOL_ERROR));
+ CHECK_EQ(STATUS_CODE_FRAME_SIZE_ERROR,
+ MapRstStreamStatusToProtocolError(RST_STREAM_FRAME_SIZE_ERROR));
+ CHECK_EQ(STATUS_CODE_ENHANCE_YOUR_CALM,
+ MapRstStreamStatusToProtocolError(RST_STREAM_ENHANCE_YOUR_CALM));
+}
+
+TEST(MapNetErrorToGoAwayStatus, MapsValue) {
+ CHECK_EQ(GOAWAY_INADEQUATE_SECURITY,
+ MapNetErrorToGoAwayStatus(ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY));
+ CHECK_EQ(GOAWAY_FLOW_CONTROL_ERROR,
+ MapNetErrorToGoAwayStatus(ERR_SPDY_FLOW_CONTROL_ERROR));
+ CHECK_EQ(GOAWAY_PROTOCOL_ERROR,
+ MapNetErrorToGoAwayStatus(ERR_SPDY_PROTOCOL_ERROR));
+ CHECK_EQ(GOAWAY_COMPRESSION_ERROR,
+ MapNetErrorToGoAwayStatus(ERR_SPDY_COMPRESSION_ERROR));
+ CHECK_EQ(GOAWAY_FRAME_SIZE_ERROR,
+ MapNetErrorToGoAwayStatus(ERR_SPDY_FRAME_SIZE_ERROR));
+ CHECK_EQ(GOAWAY_PROTOCOL_ERROR, MapNetErrorToGoAwayStatus(ERR_UNEXPECTED));
+}
+
} // namespace net