| Index: net/spdy/spdy_session_unittest.cc
|
| diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
|
| index c023164253d26fd1d8afc7a89beb7bc719a2c7db..1f7ca60daf75cd4a5577812870b720fbd2408592 100644
|
| --- a/net/spdy/spdy_session_unittest.cc
|
| +++ b/net/spdy/spdy_session_unittest.cc
|
| @@ -1045,6 +1045,76 @@ TEST_P(SpdySessionTest, StreamIdSpaceExhausted) {
|
| 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;
|
|
|