Ensure SpdySession::StartGoingAway is always called with an error.

Also add test coverage of SPDY network changes with created streams.

BUG=382553
R=rch@chromium.org

Review URL: https://codereview.chromium.org/328823003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276495 0039d316-1c4b-4281-b951-d872f2087c98
parent d34bb928
......@@ -1598,7 +1598,12 @@ void SpdySession::DoDrainSession(Error err, const std::string& description) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors",
total_bytes_received_, 1, 100000000, 50);
StartGoingAway(0, err);
if (err == OK) {
// We ought to be going away already, as this is a graceful close.
DcheckGoingAway();
} else {
StartGoingAway(0, err);
}
DcheckDraining();
MaybePostWriteLoop();
}
......@@ -1639,6 +1644,7 @@ SpdyStreamId SpdySession::GetNewStreamId() {
void SpdySession::CloseSessionOnError(Error err,
const std::string& description) {
DCHECK_LT(err, ERR_IO_PENDING);
DoDrainSession(err, description);
}
......
......@@ -284,7 +284,7 @@ void SpdySessionPool::OnIPAddressChanged() {
// to a generated TCP reset.
#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
(*it)->MakeUnavailable();
(*it)->StartGoingAway(kLastStreamId, OK);
(*it)->StartGoingAway(kLastStreamId, ERR_NETWORK_CHANGED);
(*it)->MaybeFinishGoingAway();
#else
(*it)->CloseSessionOnError(ERR_NETWORK_CHANGED,
......
......@@ -537,6 +537,7 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
test_host_port_pairA, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> sessionA =
CreateInsecureSpdySession(http_session_, keyA, BoundNetLog());
GURL urlA(kTestHostA);
base::WeakPtr<SpdyStream> spdy_streamA = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, sessionA, urlA, MEDIUM, BoundNetLog());
......@@ -555,7 +556,7 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
EXPECT_TRUE(sessionA->IsGoingAway());
EXPECT_FALSE(delegateA.StreamIsClosed());
// Set up session B: Available, but idle.
// Set up session B: Available, with a created stream.
const std::string kTestHostB("http://www.b.com");
HostPortPair test_host_port_pairB(kTestHostB, 80);
SpdySessionKey keyB(
......@@ -564,6 +565,12 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
CreateInsecureSpdySession(http_session_, keyB, BoundNetLog());
EXPECT_TRUE(sessionB->IsAvailable());
GURL urlB(kTestHostB);
base::WeakPtr<SpdyStream> spdy_streamB = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, sessionB, urlB, MEDIUM, BoundNetLog());
test::StreamDelegateDoNothing delegateB(spdy_streamB);
spdy_streamB->SetDelegate(&delegateB);
// Set up session C: Draining.
session_deps_.socket_factory->AddSocketDataProvider(&data);
const std::string kTestHostC("http://www.c.com");
......@@ -583,9 +590,13 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
EXPECT_TRUE(sessionB->IsDraining());
EXPECT_TRUE(sessionC->IsDraining());
EXPECT_EQ(1u, sessionA->num_active_streams()); // Stream is still active.
EXPECT_EQ(1u,
sessionA->num_active_streams()); // Active stream is still active.
EXPECT_FALSE(delegateA.StreamIsClosed());
EXPECT_TRUE(delegateB.StreamIsClosed()); // Created stream was closed.
EXPECT_EQ(ERR_NETWORK_CHANGED, delegateB.WaitForClose());
sessionA->CloseSessionOnError(ERR_ABORTED, "Closing");
sessionB->CloseSessionOnError(ERR_ABORTED, "Closing");
......@@ -596,8 +607,11 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
EXPECT_TRUE(sessionB->IsDraining());
EXPECT_TRUE(sessionC->IsDraining());
// Both streams were closed with an error.
EXPECT_TRUE(delegateA.StreamIsClosed());
EXPECT_EQ(ERR_NETWORK_CHANGED, delegateA.WaitForClose());
EXPECT_TRUE(delegateB.StreamIsClosed());
EXPECT_EQ(ERR_NETWORK_CHANGED, delegateB.WaitForClose());
#endif // defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment