Chromium Code Reviews| Index: net/spdy/spdy_session_spdy3_unittest.cc |
| diff --git a/net/spdy/spdy_session_spdy3_unittest.cc b/net/spdy/spdy_session_spdy3_unittest.cc |
| index 5418528de7f10a9d61c8cee862300b5b0a6e970e..bf39939c8369d9bc83115a0670d79622090f33d3 100644 |
| --- a/net/spdy/spdy_session_spdy3_unittest.cc |
| +++ b/net/spdy/spdy_session_spdy3_unittest.cc |
| @@ -41,6 +41,29 @@ base::TimeTicks TheNearFuture() { |
| return base::TimeTicks::Now() + base::TimeDelta::FromSeconds(g_delta_seconds); |
| } |
| +// TODO(akalin): Merge with ConstructSpdyGet(). (The sticking point is |
| +// CONTROL_FLAG_NONE vs. CONTROL_FLAG_FIN.) |
|
Ryan Hamilton
2013/03/14 15:29:45
Curious... Isn't it illegal for a SYN_STREAM whic
akalin
2013/03/15 17:28:56
Okay, converted these tests to use posts and added
|
| +scoped_ptr<SpdyFrame> ConstructSpdyGetRequest(const char* url, |
| + SpdyStreamId id, |
| + RequestPriority priority) { |
| + const SpdyHeaderInfo kSynStartHeader = { |
| + SYN_STREAM, |
| + id, |
| + 0, |
| + ConvertRequestPriorityToSpdyPriority(priority, 3), |
| + 0, |
| + CONTROL_FLAG_NONE, |
| + false, |
| + RST_STREAM_INVALID, |
| + NULL, |
| + 0, |
| + DATA_FLAG_NONE |
| + }; |
| + |
| + return scoped_ptr<SpdyFrame>( |
| + ConstructSpdyPacket(kSynStartHeader, ConstructHeaderBlock(url))); |
| +} |
| + |
| } // namespace |
| class SpdySessionSpdy3Test : public PlatformTest { |
| @@ -948,19 +971,10 @@ TEST_F(SpdySessionSpdy3Test, OutOfOrderSynStreams) { |
| ASSERT_TRUE(spdy_stream2.get() != NULL); |
| EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
| - (*headers)[":method"] = "GET"; |
| - (*headers)[":scheme"] = url.scheme(); |
| - (*headers)[":host"] = url.host(); |
| - (*headers)[":path"] = url.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock); |
| - *headers2 = *headers; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| - spdy_stream2->set_spdy_headers(headers2.Pass()); |
| + spdy_stream2->set_spdy_headers(ConstructHeaderBlock(url.spec())); |
| EXPECT_TRUE(spdy_stream2->HasUrl()); |
| spdy_stream1->SendRequest(false); |
| @@ -1020,19 +1034,10 @@ TEST_F(SpdySessionSpdy3Test, CancelStream) { |
| ASSERT_TRUE(spdy_stream2.get() != NULL); |
| EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
| - (*headers)[":method"] = "GET"; |
| - (*headers)[":scheme"] = url1.scheme(); |
| - (*headers)[":host"] = url1.host(); |
| - (*headers)[":path"] = url1.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock); |
| - *headers2 = *headers; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| - spdy_stream2->set_spdy_headers(headers2.Pass()); |
| + spdy_stream2->set_spdy_headers(ConstructHeaderBlock(url2.spec())); |
| EXPECT_TRUE(spdy_stream2->HasUrl()); |
| spdy_stream1->SendRequest(false); |
| @@ -1093,21 +1098,12 @@ TEST_F(SpdySessionSpdy3Test, CloseSessionWithTwoCreatedStreams) { |
| ASSERT_TRUE(spdy_stream2.get() != NULL); |
| EXPECT_EQ(0u, spdy_stream2->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"; |
| - scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock); |
| - *headers2 = *headers; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| test::ClosingDelegate delegate1(spdy_stream1.get()); |
| spdy_stream1->SetDelegate(&delegate1); |
| - spdy_stream2->set_spdy_headers(headers2.Pass()); |
| + spdy_stream2->set_spdy_headers(ConstructHeaderBlock(url2.spec())); |
| EXPECT_TRUE(spdy_stream2->HasUrl()); |
| test::ClosingDelegate delegate2(spdy_stream2.get()); |
| spdy_stream2->SetDelegate(&delegate2); |
| @@ -1350,18 +1346,7 @@ TEST_F(SpdySessionSpdy3Test, CloseTwoStalledCreateStream) { |
| EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams()); |
| EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST)); |
| - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
| - (*headers)[":method"] = "GET"; |
| - (*headers)[":scheme"] = url1.scheme(); |
| - (*headers)[":host"] = url1.host(); |
| - (*headers)[":path"] = url1.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock); |
| - *headers2 = *headers; |
| - scoped_ptr<SpdyHeaderBlock> headers3(new SpdyHeaderBlock); |
| - *headers3 = *headers; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| spdy_stream1->SendRequest(false); |
| @@ -1373,7 +1358,7 @@ TEST_F(SpdySessionSpdy3Test, CloseTwoStalledCreateStream) { |
| EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST)); |
| scoped_refptr<SpdyStream> stream2 = request2.ReleaseStream(); |
| - stream2->set_spdy_headers(headers2.Pass()); |
| + stream2->set_spdy_headers(ConstructHeaderBlock(url2.spec())); |
| EXPECT_TRUE(stream2->HasUrl()); |
| stream2->SendRequest(false); |
| @@ -1385,7 +1370,7 @@ TEST_F(SpdySessionSpdy3Test, CloseTwoStalledCreateStream) { |
| EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST)); |
| scoped_refptr<SpdyStream> stream3 = request3.ReleaseStream(); |
| - stream3->set_spdy_headers(headers3.Pass()); |
| + stream3->set_spdy_headers(ConstructHeaderBlock(url3.spec())); |
| EXPECT_TRUE(stream3->HasUrl()); |
| stream3->SendRequest(false); |
| @@ -1702,14 +1687,7 @@ TEST_F(SpdySessionSpdy3Test, ReadDataWithoutYielding) { |
| 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)[":path"] = url1.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| spdy_stream1->SendRequest(false); |
| @@ -1792,14 +1770,7 @@ TEST_F(SpdySessionSpdy3Test, TestYieldingDuringReadData) { |
| 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)[":path"] = url1.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| spdy_stream1->SendRequest(false); |
| @@ -1905,14 +1876,7 @@ TEST_F(SpdySessionSpdy3Test, TestYieldingDuringAsyncReadData) { |
| 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)[":path"] = url1.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| spdy_stream1->SendRequest(false); |
| @@ -1980,14 +1944,7 @@ TEST_F(SpdySessionSpdy3Test, GoAwayWhileInDoLoop) { |
| 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)[":path"] = url1.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - |
| - spdy_stream1->set_spdy_headers(headers.Pass()); |
| + spdy_stream1->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(spdy_stream1->HasUrl()); |
| spdy_stream1->SendRequest(false); |
| @@ -2341,14 +2298,7 @@ TEST_F(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31) { |
| stream.get(), scoped_ptr<SpdyHeaderBlock>(), buf.get()); |
| stream->SetDelegate(&delegate); |
| - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
| - (*headers)[":method"] = "GET"; |
| - (*headers)[":scheme"] = url1.scheme(); |
| - (*headers)[":host"] = url1.host(); |
| - (*headers)[":path"] = url1.path(); |
| - (*headers)[":version"] = "HTTP/1.1"; |
| - |
| - stream->set_spdy_headers(headers.Pass()); |
| + stream->set_spdy_headers(ConstructHeaderBlock(url1.spec())); |
| EXPECT_TRUE(stream->HasUrl()); |
| EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true)); |
| @@ -2405,4 +2355,248 @@ TEST_F(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31) { |
| EXPECT_EQ(OK, delegate.WaitForClose()); |
| } |
| +// TODO(akalin): Re-enable the tests below when we fix the unstall bug |
| +// mentioned in crbug.com/178943. |
| + |
| +// Cause a stall by reducing the flow control send window to 0. The |
| +// stream should resume when that window is then increased. |
| +TEST_F(SpdySessionSpdy3Test, DISABLED_ResumeAfterSendWindowSizeIncrease31) { |
| + const char kStreamUrl[] = "http://www.google.com/"; |
| + GURL url(kStreamUrl); |
| + |
| + session_deps_.enable_spdy_31 = true; |
| + session_deps_.host_resolver->set_synchronous_mode(true); |
| + |
| + scoped_ptr<SpdyFrame> initial_window_update( |
| + ConstructSpdyWindowUpdate( |
| + kSessionFlowControlStreamId, |
| + kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize)); |
| + const char kBodyData[] = "Body data"; |
| + const size_t kBodyDataSize = arraysize(kBodyData); |
| + scoped_ptr<SpdyFrame> req = ConstructSpdyGetRequest(kStreamUrl, 1, LOWEST); |
| + scoped_ptr<SpdyFrame> msg( |
| + ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| + MockWrite writes[] = { |
| + CreateMockWrite(*initial_window_update, 0), |
| + CreateMockWrite(*req, 1), |
| + CreateMockWrite(*msg, 3), |
| + }; |
| + |
| + scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| + scoped_ptr<SpdyFrame> echo( |
| + ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| + MockRead reads[] = { |
| + CreateMockRead(*resp, 2), |
| + CreateMockRead(*echo, 4), |
| + MockRead(ASYNC, 0, 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(); |
| + scoped_refptr<SpdySession> session = GetSession(pair_); |
| + InitializeSession( |
| + http_session_.get(), session.get(), test_host_port_pair_); |
| + EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| + session->flow_control_state()); |
| + |
| + scoped_refptr<SpdyStream> stream = |
| + CreateStreamSynchronously(session, url, LOWEST, BoundNetLog()); |
| + ASSERT_TRUE(stream.get() != NULL); |
| + scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(kBodyDataSize)); |
| + memcpy(buf->data(), kBodyData, kBodyDataSize); |
| + |
| + test::StreamDelegateWithBody delegate(stream.get(), buf); |
| + stream->SetDelegate(&delegate); |
| + |
| + EXPECT_FALSE(stream->HasUrl()); |
| + |
| + stream->set_spdy_headers(ConstructHeaderBlock(kStreamUrl)); |
| + EXPECT_TRUE(stream->HasUrl()); |
| + EXPECT_EQ(kStreamUrl, stream->GetUrl().spec()); |
| + |
| + EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true)); |
| + |
| + data.RunFor(3); |
| + |
| + EXPECT_FALSE(stream->stalled_by_flow_control()); |
| + |
| + // Reduce the send window size to 0 to stall. |
| + while (session->session_send_window_size_ > 0) { |
| + session->DecreaseSendWindowSize( |
| + std::min(kMaxSpdyFrameChunkSize, session->session_send_window_size_)); |
| + } |
| + |
| + stream->QueueStreamData(buf.get(), buf->size(), DATA_FLAG_NONE); |
| + |
| + EXPECT_TRUE(stream->stalled_by_flow_control()); |
| + |
| + session->IncreaseSendWindowSize(kBodyDataSize); |
| + |
| + EXPECT_FALSE(stream->stalled_by_flow_control()); |
| + |
| + data.RunFor(3); |
| + |
| + EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); |
| + |
| + EXPECT_TRUE(delegate.send_headers_completed()); |
| + EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); |
| + EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); |
| + EXPECT_EQ(std::string(kBodyData, kBodyDataSize), delegate.received_data()); |
| + EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate.body_data_sent()); |
| +} |
| + |
| +// Cause a stall by reducing the flow control recv window to 0. The |
| +// stream should resume when that window is then increased. |
| +TEST_F(SpdySessionSpdy3Test, |
| + DISABLED_ResumeByPriorityAfterSendWindowSizeIncrease31) { |
| + const char kStreamUrl[] = "http://www.google.com/"; |
| + GURL url(kStreamUrl); |
| + |
| + session_deps_.enable_spdy_31 = true; |
| + session_deps_.host_resolver->set_synchronous_mode(true); |
| + |
| + const char kBodyData[] = "Body data"; |
| + const size_t kBodyDataSize = arraysize(kBodyData); |
| + scoped_ptr<SpdyFrame> initial_window_update( |
| + ConstructSpdyWindowUpdate( |
| + kSessionFlowControlStreamId, |
| + kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize)); |
| + scoped_ptr<SpdyFrame> req1 = ConstructSpdyGetRequest(kStreamUrl, 1, LOWEST); |
| + scoped_ptr<SpdyFrame> req2 = ConstructSpdyGetRequest(kStreamUrl, 3, MEDIUM); |
| + scoped_ptr<SpdyFrame> msg1( |
| + ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| + scoped_ptr<SpdyFrame> msg2( |
| + ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| + MockWrite writes[] = { |
| + CreateMockWrite(*initial_window_update, 0), |
| + CreateMockWrite(*req1, 1), |
| + CreateMockWrite(*req2, 3), |
| + CreateMockWrite(*msg1, 5), |
| + CreateMockWrite(*msg2, 7), |
| + }; |
| + |
| + scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| + scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); |
| + scoped_ptr<SpdyFrame> echo1( |
| + ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| + scoped_ptr<SpdyFrame> echo2( |
| + ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| + MockRead reads[] = { |
| + CreateMockRead(*resp1, 2), |
| + CreateMockRead(*resp2, 4), |
| + CreateMockRead(*echo1, 6), |
| + CreateMockRead(*echo2, 8), |
| + MockRead(ASYNC, 0, 0, 9), // 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(); |
| + scoped_refptr<SpdySession> session = GetSession(pair_); |
| + InitializeSession( |
| + http_session_.get(), session.get(), test_host_port_pair_); |
| + EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| + session->flow_control_state()); |
| + |
| + scoped_refptr<SpdyStream> stream1 = |
| + CreateStreamSynchronously(session, url, LOWEST, BoundNetLog()); |
| + ASSERT_TRUE(stream1.get() != NULL); |
| + scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(kBodyDataSize)); |
| + memcpy(buf->data(), kBodyData, kBodyDataSize); |
| + |
| + test::StreamDelegateWithBody delegate1(stream1.get(), buf); |
| + stream1->SetDelegate(&delegate1); |
| + |
| + EXPECT_FALSE(stream1->HasUrl()); |
| + |
| + stream1->set_spdy_headers(ConstructHeaderBlock(kStreamUrl)); |
| + EXPECT_TRUE(stream1->HasUrl()); |
| + EXPECT_EQ(kStreamUrl, stream1->GetUrl().spec()); |
| + |
| + EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequest(true)); |
| + |
| + data.RunFor(3); |
| + EXPECT_EQ(1u, stream1->stream_id()); |
| + |
| + scoped_refptr<SpdyStream> stream2 = |
| + CreateStreamSynchronously(session, url, MEDIUM, BoundNetLog()); |
| + ASSERT_TRUE(stream2.get() != NULL); |
| + scoped_refptr<IOBufferWithSize> buf2(new IOBufferWithSize(kBodyDataSize)); |
| + memcpy(buf2->data(), kBodyData, kBodyDataSize); |
| + |
| + test::StreamDelegateWithBody delegate2(stream2.get(), buf2); |
| + stream2->SetDelegate(&delegate2); |
| + |
| + EXPECT_FALSE(stream2->HasUrl()); |
| + |
| + stream2->set_spdy_headers(ConstructHeaderBlock(kStreamUrl)); |
| + EXPECT_TRUE(stream2->HasUrl()); |
| + EXPECT_EQ(kStreamUrl, stream2->GetUrl().spec()); |
| + |
| + EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequest(true)); |
| + |
| + data.RunFor(2); |
| + EXPECT_EQ(3u, stream2->stream_id()); |
| + |
| + EXPECT_FALSE(stream1->stalled_by_flow_control()); |
| + EXPECT_FALSE(stream2->stalled_by_flow_control()); |
| + |
| + // Reduce the send window size to 0 to stall. |
| + while (session->session_send_window_size_ > 0) { |
| + session->DecreaseSendWindowSize( |
| + std::min(kMaxSpdyFrameChunkSize, session->session_send_window_size_)); |
| + } |
| + |
| + stream1->QueueStreamData(buf.get(), buf->size(), DATA_FLAG_NONE); |
| + stream2->QueueStreamData(buf.get(), buf->size(), DATA_FLAG_NONE); |
| + |
| + EXPECT_TRUE(stream1->stalled_by_flow_control()); |
| + EXPECT_TRUE(stream2->stalled_by_flow_control()); |
| + |
| + // This should unstall only stream2. |
| + session->IncreaseSendWindowSize(kBodyDataSize); |
| + |
| + EXPECT_TRUE(stream1->stalled_by_flow_control()); |
| + EXPECT_FALSE(stream2->stalled_by_flow_control()); |
| + |
| + data.RunFor(2); |
| + |
| + EXPECT_TRUE(stream1->stalled_by_flow_control()); |
| + EXPECT_FALSE(stream2->stalled_by_flow_control()); |
| + |
| + // This should then unstall stream1. |
| + session->IncreaseSendWindowSize(kBodyDataSize); |
| + |
| + EXPECT_FALSE(stream1->stalled_by_flow_control()); |
| + EXPECT_FALSE(stream2->stalled_by_flow_control()); |
| + |
| + data.RunFor(3); |
| + |
| + EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); |
| + EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); |
| + |
| + EXPECT_TRUE(delegate1.send_headers_completed()); |
| + EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); |
| + EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version")); |
| + EXPECT_EQ(std::string(kBodyData, kBodyDataSize), delegate1.received_data()); |
| + EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate1.body_data_sent()); |
| + |
| + EXPECT_TRUE(delegate2.send_headers_completed()); |
| + EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); |
| + EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); |
| + EXPECT_EQ(std::string(kBodyData, kBodyDataSize), delegate2.received_data()); |
| + EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate2.body_data_sent()); |
| +} |
| + |
| } // namespace net |