Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(555)

Unified Diff: net/spdy/spdy_session_unittest.cc

Issue 287063003: Correct SpdySession StreamID exhaustion behavior (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comment tweaks. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_session_unittest.cc
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 5978f9384d9520b0eadd7ebad9f2036e0aa0fcf4..c435a57469ad590ec61c1acc00a1e1bc42584552 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -920,6 +920,131 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) {
session->CloseSessionOnError(ERR_ABORTED, "Aborting");
}
+TEST_P(SpdySessionTest, StreamIdSpaceExhausted) {
+ const SpdyStreamId kLastStreamId = 0x7fffffff;
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ // 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.
+ EXPECT_FALSE(session.get());
+}
+
TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
session_deps_.host_resolver->set_synchronous_mode(true);
session_deps_.time_func = TheNearFuture;
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698