Home | History | Annotate | Download | only in spdy
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/spdy/spdy_session.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/run_loop.h"
     11 #include "net/base/io_buffer.h"
     12 #include "net/base/ip_endpoint.h"
     13 #include "net/base/net_log_unittest.h"
     14 #include "net/base/request_priority.h"
     15 #include "net/base/test_data_directory.h"
     16 #include "net/base/test_data_stream.h"
     17 #include "net/socket/client_socket_pool_manager.h"
     18 #include "net/socket/next_proto.h"
     19 #include "net/socket/socket_test_util.h"
     20 #include "net/spdy/spdy_http_utils.h"
     21 #include "net/spdy/spdy_session_pool.h"
     22 #include "net/spdy/spdy_session_test_util.h"
     23 #include "net/spdy/spdy_stream.h"
     24 #include "net/spdy/spdy_stream_test_util.h"
     25 #include "net/spdy/spdy_test_util_common.h"
     26 #include "net/spdy/spdy_test_utils.h"
     27 #include "net/test/cert_test_util.h"
     28 #include "testing/platform_test.h"
     29 
     30 namespace net {
     31 
     32 namespace {
     33 
     34 static const char kTestUrl[] = "http://www.example.org/";
     35 static const char kTestHost[] = "www.example.org";
     36 static const int kTestPort = 80;
     37 
     38 const char kBodyData[] = "Body data";
     39 const size_t kBodyDataSize = arraysize(kBodyData);
     40 const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize);
     41 
     42 static base::TimeDelta g_time_delta;
     43 base::TimeTicks TheNearFuture() {
     44   return base::TimeTicks::Now() + g_time_delta;
     45 }
     46 
     47 }  // namespace
     48 
     49 class SpdySessionTest : public PlatformTest,
     50                         public ::testing::WithParamInterface<NextProto> {
     51  public:
     52   // Functions used with RunResumeAfterUnstallTest().
     53 
     54   void StallSessionOnly(SpdySession* session, SpdyStream* stream) {
     55     StallSessionSend(session);
     56   }
     57 
     58   void StallStreamOnly(SpdySession* session, SpdyStream* stream) {
     59     StallStreamSend(stream);
     60   }
     61 
     62   void StallSessionStream(SpdySession* session, SpdyStream* stream) {
     63     StallSessionSend(session);
     64     StallStreamSend(stream);
     65   }
     66 
     67   void StallStreamSession(SpdySession* session, SpdyStream* stream) {
     68     StallStreamSend(stream);
     69     StallSessionSend(session);
     70   }
     71 
     72   void UnstallSessionOnly(SpdySession* session,
     73                           SpdyStream* stream,
     74                           int32 delta_window_size) {
     75     UnstallSessionSend(session, delta_window_size);
     76   }
     77 
     78   void UnstallStreamOnly(SpdySession* session,
     79                          SpdyStream* stream,
     80                          int32 delta_window_size) {
     81     UnstallStreamSend(stream, delta_window_size);
     82   }
     83 
     84   void UnstallSessionStream(SpdySession* session,
     85                             SpdyStream* stream,
     86                             int32 delta_window_size) {
     87     UnstallSessionSend(session, delta_window_size);
     88     UnstallStreamSend(stream, delta_window_size);
     89   }
     90 
     91   void UnstallStreamSession(SpdySession* session,
     92                             SpdyStream* stream,
     93                             int32 delta_window_size) {
     94     UnstallStreamSend(stream, delta_window_size);
     95     UnstallSessionSend(session, delta_window_size);
     96   }
     97 
     98  protected:
     99   SpdySessionTest()
    100       : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
    101             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    102         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
    103             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    104         spdy_util_(GetParam()),
    105         session_deps_(GetParam()),
    106         spdy_session_pool_(NULL),
    107         test_url_(kTestUrl),
    108         test_host_port_pair_(kTestHost, kTestPort),
    109         key_(test_host_port_pair_, ProxyServer::Direct(),
    110              kPrivacyModeDisabled) {
    111   }
    112 
    113   virtual ~SpdySessionTest() {
    114     // Important to restore the per-pool limit first, since the pool limit must
    115     // always be greater than group limit, and the tests reduce both limits.
    116     ClientSocketPoolManager::set_max_sockets_per_pool(
    117         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
    118     ClientSocketPoolManager::set_max_sockets_per_group(
    119         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
    120   }
    121 
    122   virtual void SetUp() OVERRIDE {
    123     g_time_delta = base::TimeDelta();
    124   }
    125 
    126   void CreateDeterministicNetworkSession() {
    127     http_session_ =
    128         SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
    129     spdy_session_pool_ = http_session_->spdy_session_pool();
    130   }
    131 
    132   void CreateNetworkSession() {
    133     http_session_ =
    134         SpdySessionDependencies::SpdyCreateSession(&session_deps_);
    135     spdy_session_pool_ = http_session_->spdy_session_pool();
    136   }
    137 
    138   void StallSessionSend(SpdySession* session) {
    139     // Reduce the send window size to 0 to stall.
    140     while (session->session_send_window_size_ > 0) {
    141       session->DecreaseSendWindowSize(
    142           std::min(kMaxSpdyFrameChunkSize, session->session_send_window_size_));
    143     }
    144   }
    145 
    146   void UnstallSessionSend(SpdySession* session, int32 delta_window_size) {
    147     session->IncreaseSendWindowSize(delta_window_size);
    148   }
    149 
    150   void StallStreamSend(SpdyStream* stream) {
    151     // Reduce the send window size to 0 to stall.
    152     while (stream->send_window_size() > 0) {
    153       stream->DecreaseSendWindowSize(
    154           std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
    155     }
    156   }
    157 
    158   void UnstallStreamSend(SpdyStream* stream, int32 delta_window_size) {
    159     stream->IncreaseSendWindowSize(delta_window_size);
    160   }
    161 
    162   void RunResumeAfterUnstallTest(
    163       const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function,
    164       const base::Callback<void(SpdySession*, SpdyStream*, int32)>&
    165           unstall_function);
    166 
    167   // Original socket limits.  Some tests set these.  Safest to always restore
    168   // them once each test has been run.
    169   int old_max_group_sockets_;
    170   int old_max_pool_sockets_;
    171 
    172   SpdyTestUtil spdy_util_;
    173   SpdySessionDependencies session_deps_;
    174   scoped_refptr<HttpNetworkSession> http_session_;
    175   SpdySessionPool* spdy_session_pool_;
    176   GURL test_url_;
    177   HostPortPair test_host_port_pair_;
    178   SpdySessionKey key_;
    179 };
    180 
    181 INSTANTIATE_TEST_CASE_P(
    182     NextProto,
    183     SpdySessionTest,
    184     testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
    185                     kProtoHTTP2Draft04));
    186 
    187 // Try to create a SPDY session that will fail during
    188 // initialization. Nothing should blow up.
    189 TEST_P(SpdySessionTest, InitialReadError) {
    190   CreateDeterministicNetworkSession();
    191 
    192   TryCreateFakeSpdySessionExpectingFailure(
    193       spdy_session_pool_, key_, ERR_FAILED);
    194 }
    195 
    196 // A session receiving a GOAWAY frame with no active streams should
    197 // immediately close.
    198 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
    199   session_deps_.host_resolver->set_synchronous_mode(true);
    200 
    201   MockConnect connect_data(SYNCHRONOUS, OK);
    202   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    203   MockRead reads[] = {
    204     CreateMockRead(*goaway, 0),
    205   };
    206   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    207   data.set_connect_data(connect_data);
    208   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    209 
    210   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    211   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    212 
    213   CreateDeterministicNetworkSession();
    214 
    215   base::WeakPtr<SpdySession> session =
    216       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    217 
    218   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    219 
    220   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    221 
    222   // Read and process the GOAWAY frame.
    223   data.RunFor(1);
    224 
    225   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    226 
    227   EXPECT_TRUE(session == NULL);
    228 }
    229 
    230 // A session receiving a GOAWAY frame immediately with no active
    231 // streams should then close.
    232 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
    233   session_deps_.host_resolver->set_synchronous_mode(true);
    234 
    235   MockConnect connect_data(SYNCHRONOUS, OK);
    236   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    237   MockRead reads[] = {
    238     CreateMockRead(*goaway, 0, SYNCHRONOUS),
    239   };
    240   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    241   data.set_connect_data(connect_data);
    242   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    243 
    244   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    245   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    246 
    247   CreateDeterministicNetworkSession();
    248 
    249   data.StopAfter(1);
    250 
    251   TryCreateInsecureSpdySessionExpectingFailure(
    252       http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog());
    253 
    254   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    255 }
    256 
    257 // A session receiving a GOAWAY frame with active streams should close
    258 // when the last active stream is closed.
    259 TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
    260   session_deps_.host_resolver->set_synchronous_mode(true);
    261 
    262   MockConnect connect_data(SYNCHRONOUS, OK);
    263   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    264   MockRead reads[] = {
    265     CreateMockRead(*goaway, 2),
    266     MockRead(ASYNC, 0, 3)  // EOF
    267   };
    268   scoped_ptr<SpdyFrame> req1(
    269       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    270   scoped_ptr<SpdyFrame> req2(
    271       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
    272   MockWrite writes[] = {
    273     CreateMockWrite(*req1, 0),
    274     CreateMockWrite(*req2, 1),
    275   };
    276   DeterministicSocketData data(reads, arraysize(reads),
    277                                writes, arraysize(writes));
    278   data.set_connect_data(connect_data);
    279   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    280 
    281   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    282   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    283 
    284   CreateDeterministicNetworkSession();
    285 
    286   base::WeakPtr<SpdySession> session =
    287       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    288 
    289   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    290 
    291   GURL url("http://www.google.com");
    292   base::WeakPtr<SpdyStream> spdy_stream1 =
    293       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    294                                 session, url, MEDIUM, BoundNetLog());
    295   test::StreamDelegateDoNothing delegate1(spdy_stream1);
    296   spdy_stream1->SetDelegate(&delegate1);
    297 
    298   base::WeakPtr<SpdyStream> spdy_stream2 =
    299       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    300                                 session, url, MEDIUM, BoundNetLog());
    301   test::StreamDelegateDoNothing delegate2(spdy_stream2);
    302   spdy_stream2->SetDelegate(&delegate2);
    303 
    304   scoped_ptr<SpdyHeaderBlock> headers(
    305       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    306   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
    307 
    308   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    309   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
    310   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
    311   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
    312 
    313   data.RunFor(2);
    314 
    315   EXPECT_EQ(1u, spdy_stream1->stream_id());
    316   EXPECT_EQ(3u, spdy_stream2->stream_id());
    317 
    318   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    319 
    320   // Read and process the GOAWAY frame.
    321   data.RunFor(1);
    322 
    323   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    324 
    325   EXPECT_FALSE(session->IsStreamActive(3));
    326   EXPECT_EQ(NULL, spdy_stream2.get());
    327   EXPECT_TRUE(session->IsStreamActive(1));
    328 
    329   EXPECT_FALSE(session->IsClosed());
    330 
    331   // Should close the session.
    332   spdy_stream1->Close();
    333   EXPECT_EQ(NULL, spdy_stream1.get());
    334 
    335   EXPECT_TRUE(session == NULL);
    336 }
    337 
    338 // Have a session receive two GOAWAY frames, with the last one causing
    339 // the last active stream to be closed. The session should then be
    340 // closed after the second GOAWAY frame.
    341 TEST_P(SpdySessionTest, GoAwayTwice) {
    342   session_deps_.host_resolver->set_synchronous_mode(true);
    343 
    344   MockConnect connect_data(SYNCHRONOUS, OK);
    345   scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1));
    346   scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0));
    347   MockRead reads[] = {
    348     CreateMockRead(*goaway1, 2),
    349     CreateMockRead(*goaway2, 3),
    350     MockRead(ASYNC, 0, 4)  // EOF
    351   };
    352   scoped_ptr<SpdyFrame> req1(
    353       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    354   scoped_ptr<SpdyFrame> req2(
    355       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
    356   MockWrite writes[] = {
    357     CreateMockWrite(*req1, 0),
    358     CreateMockWrite(*req2, 1),
    359   };
    360   DeterministicSocketData data(reads, arraysize(reads),
    361                                writes, arraysize(writes));
    362   data.set_connect_data(connect_data);
    363   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    364 
    365   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    366   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    367 
    368   CreateDeterministicNetworkSession();
    369 
    370   base::WeakPtr<SpdySession> session =
    371       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    372 
    373   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    374 
    375   GURL url("http://www.google.com");
    376   base::WeakPtr<SpdyStream> spdy_stream1 =
    377       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    378                                 session, url, MEDIUM, BoundNetLog());
    379   test::StreamDelegateDoNothing delegate1(spdy_stream1);
    380   spdy_stream1->SetDelegate(&delegate1);
    381 
    382   base::WeakPtr<SpdyStream> spdy_stream2 =
    383       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    384                                 session, url, MEDIUM, BoundNetLog());
    385   test::StreamDelegateDoNothing delegate2(spdy_stream2);
    386   spdy_stream2->SetDelegate(&delegate2);
    387 
    388   scoped_ptr<SpdyHeaderBlock> headers(
    389       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    390   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
    391 
    392   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    393   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
    394   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
    395   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
    396 
    397   data.RunFor(2);
    398 
    399   EXPECT_EQ(1u, spdy_stream1->stream_id());
    400   EXPECT_EQ(3u, spdy_stream2->stream_id());
    401 
    402   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    403 
    404   // Read and process the first GOAWAY frame.
    405   data.RunFor(1);
    406 
    407   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    408 
    409   EXPECT_FALSE(session->IsStreamActive(3));
    410   EXPECT_EQ(NULL, spdy_stream2.get());
    411   EXPECT_TRUE(session->IsStreamActive(1));
    412 
    413   EXPECT_FALSE(session->IsClosed());
    414 
    415   // Read and process the second GOAWAY frame, which should close the
    416   // session.
    417   data.RunFor(1);
    418 
    419   EXPECT_TRUE(session == NULL);
    420 }
    421 
    422 // Have a session with active streams receive a GOAWAY frame and then
    423 // close it. It should handle the close properly (i.e., not try to
    424 // make itself unavailable in its pool twice).
    425 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
    426   session_deps_.host_resolver->set_synchronous_mode(true);
    427 
    428   MockConnect connect_data(SYNCHRONOUS, OK);
    429   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    430   MockRead reads[] = {
    431     CreateMockRead(*goaway, 2),
    432     MockRead(ASYNC, 0, 3)  // EOF
    433   };
    434   scoped_ptr<SpdyFrame> req1(
    435       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    436   scoped_ptr<SpdyFrame> req2(
    437       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
    438   MockWrite writes[] = {
    439     CreateMockWrite(*req1, 0),
    440     CreateMockWrite(*req2, 1),
    441   };
    442   DeterministicSocketData data(reads, arraysize(reads),
    443                                writes, arraysize(writes));
    444   data.set_connect_data(connect_data);
    445   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    446 
    447   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    448   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    449 
    450   CreateDeterministicNetworkSession();
    451 
    452   base::WeakPtr<SpdySession> session =
    453       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    454 
    455   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    456 
    457   GURL url("http://www.google.com");
    458   base::WeakPtr<SpdyStream> spdy_stream1 =
    459       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    460                                 session, url, MEDIUM, BoundNetLog());
    461   test::StreamDelegateDoNothing delegate1(spdy_stream1);
    462   spdy_stream1->SetDelegate(&delegate1);
    463 
    464   base::WeakPtr<SpdyStream> spdy_stream2 =
    465       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    466                                 session, url, MEDIUM, BoundNetLog());
    467   test::StreamDelegateDoNothing delegate2(spdy_stream2);
    468   spdy_stream2->SetDelegate(&delegate2);
    469 
    470   scoped_ptr<SpdyHeaderBlock> headers(
    471       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    472   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
    473 
    474   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    475   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
    476   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
    477   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
    478 
    479   data.RunFor(2);
    480 
    481   EXPECT_EQ(1u, spdy_stream1->stream_id());
    482   EXPECT_EQ(3u, spdy_stream2->stream_id());
    483 
    484   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    485 
    486   // Read and process the GOAWAY frame.
    487   data.RunFor(1);
    488 
    489   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    490 
    491   EXPECT_FALSE(session->IsStreamActive(3));
    492   EXPECT_EQ(NULL, spdy_stream2.get());
    493   EXPECT_TRUE(session->IsStreamActive(1));
    494 
    495   EXPECT_FALSE(session->IsClosed());
    496 
    497   session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
    498 
    499   EXPECT_EQ(NULL, spdy_stream1.get());
    500   EXPECT_TRUE(session == NULL);
    501 }
    502 
    503 // Try to create a stream after receiving a GOAWAY frame. It should
    504 // fail.
    505 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
    506   const char kStreamUrl[] = "http://www.google.com";
    507   session_deps_.host_resolver->set_synchronous_mode(true);
    508 
    509   MockConnect connect_data(SYNCHRONOUS, OK);
    510   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    511   MockRead reads[] = {
    512     CreateMockRead(*goaway, 1),
    513     MockRead(ASYNC, 0, 2)  // EOF
    514   };
    515   scoped_ptr<SpdyFrame> req(
    516       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    517   MockWrite writes[] = {
    518     CreateMockWrite(*req, 0),
    519   };
    520   DeterministicSocketData data(reads, arraysize(reads),
    521                                writes, arraysize(writes));
    522   data.set_connect_data(connect_data);
    523   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    524 
    525   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    526   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    527 
    528   CreateDeterministicNetworkSession();
    529 
    530   base::WeakPtr<SpdySession> session =
    531       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    532 
    533   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    534 
    535   GURL url(kStreamUrl);
    536   base::WeakPtr<SpdyStream> spdy_stream =
    537       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    538                                 session, url, MEDIUM, BoundNetLog());
    539   test::StreamDelegateDoNothing delegate(spdy_stream);
    540   spdy_stream->SetDelegate(&delegate);
    541 
    542   scoped_ptr<SpdyHeaderBlock> headers(
    543       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    544   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    545   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
    546 
    547   data.RunFor(1);
    548 
    549   EXPECT_EQ(1u, spdy_stream->stream_id());
    550 
    551   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    552 
    553   // Read and process the GOAWAY frame.
    554   data.RunFor(1);
    555 
    556   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    557   EXPECT_TRUE(session->IsStreamActive(1));
    558 
    559   SpdyStreamRequest stream_request;
    560   int rv = stream_request.StartRequest(
    561       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog(),
    562       CompletionCallback());
    563   EXPECT_EQ(ERR_FAILED, rv);
    564 
    565   // Read and process EOF.
    566   data.RunFor(1);
    567 
    568   EXPECT_TRUE(session == NULL);
    569 }
    570 
    571 // Receiving a SYN_STREAM frame after a GOAWAY frame should result in
    572 // the stream being refused.
    573 TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
    574   const char kStreamUrl[] = "http://www.google.com";
    575   session_deps_.host_resolver->set_synchronous_mode(true);
    576 
    577   MockConnect connect_data(SYNCHRONOUS, OK);
    578   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    579   scoped_ptr<SpdyFrame>
    580       push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
    581   MockRead reads[] = {
    582     CreateMockRead(*goaway, 1),
    583     CreateMockRead(*push, 2),
    584     MockRead(ASYNC, 0, 4)  // EOF
    585   };
    586   scoped_ptr<SpdyFrame> req(
    587       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    588   scoped_ptr<SpdyFrame> rst(
    589       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
    590   MockWrite writes[] = {
    591     CreateMockWrite(*req, 0),
    592     CreateMockWrite(*rst, 3)
    593   };
    594   DeterministicSocketData data(reads, arraysize(reads),
    595                                writes, arraysize(writes));
    596   data.set_connect_data(connect_data);
    597   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    598 
    599   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    600   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    601 
    602   CreateDeterministicNetworkSession();
    603 
    604   base::WeakPtr<SpdySession> session =
    605       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    606 
    607   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    608 
    609   GURL url(kStreamUrl);
    610   base::WeakPtr<SpdyStream> spdy_stream =
    611       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    612                                 session, url, MEDIUM, BoundNetLog());
    613   test::StreamDelegateDoNothing delegate(spdy_stream);
    614   spdy_stream->SetDelegate(&delegate);
    615 
    616   scoped_ptr<SpdyHeaderBlock> headers(
    617       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    618   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    619   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
    620 
    621   data.RunFor(1);
    622 
    623   EXPECT_EQ(1u, spdy_stream->stream_id());
    624 
    625   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    626 
    627   // Read and process the GOAWAY frame.
    628   data.RunFor(1);
    629 
    630   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    631   EXPECT_TRUE(session->IsStreamActive(1));
    632 
    633   // Read and process the SYN_STREAM frame, the subsequent RST_STREAM,
    634   // and EOF.
    635   data.RunFor(3);
    636 
    637   EXPECT_TRUE(session == NULL);
    638 }
    639 
    640 TEST_P(SpdySessionTest, ClientPing) {
    641   session_deps_.enable_ping = true;
    642   session_deps_.host_resolver->set_synchronous_mode(true);
    643 
    644   MockConnect connect_data(SYNCHRONOUS, OK);
    645   scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1));
    646   MockRead reads[] = {
    647     CreateMockRead(*read_ping, 1),
    648     MockRead(ASYNC, 0, 0, 2)  // EOF
    649   };
    650   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
    651   MockWrite writes[] = {
    652     CreateMockWrite(*write_ping, 0),
    653   };
    654   DeterministicSocketData data(
    655       reads, arraysize(reads), writes, arraysize(writes));
    656   data.set_connect_data(connect_data);
    657   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    658 
    659   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    660   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    661 
    662   CreateDeterministicNetworkSession();
    663 
    664   base::WeakPtr<SpdySession> session =
    665       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    666 
    667   base::WeakPtr<SpdyStream> spdy_stream1 =
    668       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
    669                                 session, test_url_, MEDIUM, BoundNetLog());
    670   ASSERT_TRUE(spdy_stream1.get() != NULL);
    671   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
    672   spdy_stream1->SetDelegate(&delegate);
    673 
    674   base::TimeTicks before_ping_time = base::TimeTicks::Now();
    675 
    676   session->set_connection_at_risk_of_loss_time(
    677       base::TimeDelta::FromSeconds(-1));
    678   session->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
    679 
    680   session->SendPrefacePingIfNoneInFlight();
    681 
    682   data.RunFor(2);
    683 
    684   session->CheckPingStatus(before_ping_time);
    685 
    686   EXPECT_EQ(0, session->pings_in_flight());
    687   EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
    688   EXPECT_FALSE(session->check_ping_status_pending());
    689   EXPECT_GE(session->last_activity_time(), before_ping_time);
    690 
    691   data.RunFor(1);
    692 
    693   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
    694 
    695   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    696   EXPECT_TRUE(session == NULL);
    697 }
    698 
    699 TEST_P(SpdySessionTest, ServerPing) {
    700   session_deps_.host_resolver->set_synchronous_mode(true);
    701 
    702   MockConnect connect_data(SYNCHRONOUS, OK);
    703   scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2));
    704   MockRead reads[] = {
    705     CreateMockRead(*read_ping),
    706     MockRead(SYNCHRONOUS, 0, 0)  // EOF
    707   };
    708   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2));
    709   MockWrite writes[] = {
    710     CreateMockWrite(*write_ping),
    711   };
    712   StaticSocketDataProvider data(
    713       reads, arraysize(reads), writes, arraysize(writes));
    714   data.set_connect_data(connect_data);
    715   session_deps_.socket_factory->AddSocketDataProvider(&data);
    716 
    717   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    718   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
    719 
    720   CreateNetworkSession();
    721 
    722   base::WeakPtr<SpdySession> session =
    723       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    724 
    725   base::WeakPtr<SpdyStream> spdy_stream1 =
    726       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
    727                                 session, test_url_, MEDIUM, BoundNetLog());
    728   ASSERT_TRUE(spdy_stream1.get() != NULL);
    729   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
    730   spdy_stream1->SetDelegate(&delegate);
    731 
    732   // Flush the read completion task.
    733   base::MessageLoop::current()->RunUntilIdle();
    734 
    735   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    736 
    737   EXPECT_TRUE(session == NULL);
    738   EXPECT_EQ(NULL, spdy_stream1.get());
    739 }
    740 
    741 // Cause a ping to be sent out while producing a write. The write loop
    742 // should handle this properly, i.e. another DoWriteLoop task should
    743 // not be posted. This is a regression test for
    744 // http://crbug.com/261043 .
    745 TEST_P(SpdySessionTest, PingAndWriteLoop) {
    746   session_deps_.enable_ping = true;
    747   session_deps_.time_func = TheNearFuture;
    748 
    749   MockConnect connect_data(SYNCHRONOUS, OK);
    750   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
    751   scoped_ptr<SpdyFrame> req(
    752       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
    753   MockWrite writes[] = {
    754     CreateMockWrite(*req, 0),
    755     CreateMockWrite(*write_ping, 1),
    756   };
    757 
    758   MockRead reads[] = {
    759     MockRead(ASYNC, 0, 2)  // EOF
    760   };
    761 
    762   session_deps_.host_resolver->set_synchronous_mode(true);
    763 
    764   DeterministicSocketData data(reads, arraysize(reads),
    765                                writes, arraysize(writes));
    766   data.set_connect_data(connect_data);
    767   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    768 
    769   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    770   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    771 
    772   CreateDeterministicNetworkSession();
    773 
    774   base::WeakPtr<SpdySession> session =
    775       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    776 
    777   GURL url("http://www.google.com");
    778   base::WeakPtr<SpdyStream> spdy_stream =
    779       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    780                                 session, url, LOWEST, BoundNetLog());
    781   test::StreamDelegateDoNothing delegate(spdy_stream);
    782   spdy_stream->SetDelegate(&delegate);
    783 
    784   scoped_ptr<SpdyHeaderBlock> headers(
    785       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    786   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    787 
    788   // Shift time so that a ping will be sent out.
    789   g_time_delta = base::TimeDelta::FromSeconds(11);
    790 
    791   data.RunFor(2);
    792 
    793   session->CloseSessionOnError(ERR_ABORTED, "Aborting");
    794 }
    795 
    796 TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
    797   session_deps_.host_resolver->set_synchronous_mode(true);
    798 
    799   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    800   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
    801   session_deps_.time_func = TheNearFuture;
    802 
    803   CreateNetworkSession();
    804 
    805   base::WeakPtr<SpdySession> session =
    806       CreateFakeSpdySession(spdy_session_pool_, key_);
    807 
    808   session->buffered_spdy_framer_.reset(
    809       new BufferedSpdyFramer(spdy_util_.spdy_version(), false));
    810 
    811   // Create the associated stream and add to active streams.
    812   scoped_ptr<SpdyHeaderBlock> request_headers(
    813       spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
    814 
    815   scoped_ptr<SpdyStream> stream(new SpdyStream(SPDY_REQUEST_RESPONSE_STREAM,
    816                                                session,
    817                                                GURL(),
    818                                                DEFAULT_PRIORITY,
    819                                                kSpdyStreamInitialWindowSize,
    820                                                kSpdyStreamInitialWindowSize,
    821                                                session->net_log_));
    822   stream->SendRequestHeaders(request_headers.Pass(), NO_MORE_DATA_TO_SEND);
    823   SpdyStream* stream_ptr = stream.get();
    824   session->InsertCreatedStream(stream.Pass());
    825   stream = session->ActivateCreatedStream(stream_ptr);
    826   session->InsertActivatedStream(stream.Pass());
    827 
    828   SpdyHeaderBlock headers;
    829   spdy_util_.AddUrlToHeaderBlock("http://www.google.com/a.dat", &headers);
    830 
    831   // OnSynStream() expects |in_io_loop_| to be true.
    832   session->in_io_loop_ = true;
    833   session->OnSynStream(2, 1, 0, 0, true, false, headers);
    834   session->in_io_loop_ = false;
    835 
    836   // Verify that there is one unclaimed push stream.
    837   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
    838   SpdySession::PushedStreamMap::iterator iter =
    839       session->unclaimed_pushed_streams_.find(
    840           GURL("http://www.google.com/a.dat"));
    841   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
    842 
    843   // Shift time to expire the push stream.
    844   g_time_delta = base::TimeDelta::FromSeconds(301);
    845 
    846   spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat", &headers);
    847   session->in_io_loop_ = true;
    848   session->OnSynStream(4, 1, 0, 0, true, false, headers);
    849   session->in_io_loop_ = false;
    850 
    851   // Verify that the second pushed stream evicted the first pushed stream.
    852   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
    853   iter = session->unclaimed_pushed_streams_.find(
    854       GURL("http://www.google.com/b.dat"));
    855   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
    856 }
    857 
    858 TEST_P(SpdySessionTest, FailedPing) {
    859   session_deps_.host_resolver->set_synchronous_mode(true);
    860 
    861   MockConnect connect_data(SYNCHRONOUS, OK);
    862   MockRead reads[] = {
    863     MockRead(ASYNC, 0, 0, 0)  // EOF
    864   };
    865   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
    866   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    867   data.set_connect_data(connect_data);
    868   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    869 
    870   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    871   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    872 
    873   CreateDeterministicNetworkSession();
    874 
    875   base::WeakPtr<SpdySession> session =
    876       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    877 
    878   base::WeakPtr<SpdyStream> spdy_stream1 =
    879       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
    880                                 session, test_url_, MEDIUM, BoundNetLog());
    881   ASSERT_TRUE(spdy_stream1.get() != NULL);
    882   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
    883   spdy_stream1->SetDelegate(&delegate);
    884 
    885   session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
    886   session->set_hung_interval(base::TimeDelta::FromSeconds(0));
    887 
    888   // Send a PING frame.
    889   session->WritePingFrame(1);
    890   EXPECT_LT(0, session->pings_in_flight());
    891   EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
    892   EXPECT_TRUE(session->check_ping_status_pending());
    893 
    894   // Assert session is not closed.
    895   EXPECT_FALSE(session->IsClosed());
    896   EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams());
    897   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    898 
    899   // We set last time we have received any data in 1 sec less than now.
    900   // CheckPingStatus will trigger timeout because hung interval is zero.
    901   base::TimeTicks now = base::TimeTicks::Now();
    902   session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1);
    903   session->CheckPingStatus(now);
    904 
    905   EXPECT_TRUE(session == NULL);
    906   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    907 
    908   data.RunFor(1);
    909   EXPECT_EQ(NULL, spdy_stream1.get());
    910 }
    911 
    912 // Request kInitialMaxConcurrentStreams + 1 streams.  Receive a
    913 // settings frame increasing the max concurrent streams by 1.  Make
    914 // sure nothing blows up. This is a regression test for
    915 // http://crbug.com/57331 .
    916 TEST_P(SpdySessionTest, OnSettings) {
    917   session_deps_.host_resolver->set_synchronous_mode(true);
    918 
    919   const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS;
    920 
    921   SettingsMap new_settings;
    922   const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
    923   new_settings[kSpdySettingsIds] =
    924       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
    925   scoped_ptr<SpdyFrame> settings_frame(
    926       spdy_util_.ConstructSpdySettings(new_settings));
    927   MockRead reads[] = {
    928     CreateMockRead(*settings_frame, 0),
    929     MockRead(ASYNC, 0, 1),
    930   };
    931 
    932   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    933   MockConnect connect_data(SYNCHRONOUS, OK);
    934   data.set_connect_data(connect_data);
    935   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    936 
    937   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    938   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    939 
    940   CreateDeterministicNetworkSession();
    941 
    942   base::WeakPtr<SpdySession> session =
    943       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    944 
    945   // Create the maximum number of concurrent streams.
    946   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
    947     base::WeakPtr<SpdyStream> spdy_stream =
    948         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
    949                                   session, test_url_, MEDIUM, BoundNetLog());
    950     ASSERT_TRUE(spdy_stream != NULL);
    951   }
    952 
    953   StreamReleaserCallback stream_releaser;
    954   SpdyStreamRequest request;
    955   ASSERT_EQ(ERR_IO_PENDING,
    956             request.StartRequest(
    957                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
    958                 BoundNetLog(),
    959                 stream_releaser.MakeCallback(&request)));
    960 
    961   data.RunFor(1);
    962 
    963   EXPECT_EQ(OK, stream_releaser.WaitForResult());
    964 
    965   data.RunFor(1);
    966   EXPECT_TRUE(session == NULL);
    967 }
    968 
    969 // Start with a persisted value for max concurrent streams. Receive a
    970 // settings frame increasing the max concurrent streams by 1 and which
    971 // also clears the persisted data. Verify that persisted data is
    972 // correct.
    973 TEST_P(SpdySessionTest, ClearSettings) {
    974   session_deps_.host_resolver->set_synchronous_mode(true);
    975 
    976   SettingsMap new_settings;
    977   const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
    978   new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
    979       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
    980   scoped_ptr<SpdyFrame> settings_frame(
    981       spdy_util_.ConstructSpdySettings(new_settings));
    982   uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
    983   test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version());
    984   MockRead reads[] = {
    985     CreateMockRead(*settings_frame, 0),
    986     MockRead(ASYNC, 0, 1),
    987   };
    988 
    989   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    990   MockConnect connect_data(SYNCHRONOUS, OK);
    991   data.set_connect_data(connect_data);
    992   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    993 
    994   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    995   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
    996 
    997   CreateDeterministicNetworkSession();
    998 
    999   // Initialize the SpdySetting with the default.
   1000   spdy_session_pool_->http_server_properties()->SetSpdySetting(
   1001       test_host_port_pair_,
   1002       SETTINGS_MAX_CONCURRENT_STREAMS,
   1003       SETTINGS_FLAG_PLEASE_PERSIST,
   1004       kInitialMaxConcurrentStreams);
   1005 
   1006   EXPECT_FALSE(
   1007       spdy_session_pool_->http_server_properties()->GetSpdySettings(
   1008           test_host_port_pair_).empty());
   1009 
   1010   base::WeakPtr<SpdySession> session =
   1011       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1012 
   1013   // Create the maximum number of concurrent streams.
   1014   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
   1015     base::WeakPtr<SpdyStream> spdy_stream =
   1016         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1017                                   session, test_url_, MEDIUM, BoundNetLog());
   1018     ASSERT_TRUE(spdy_stream != NULL);
   1019   }
   1020 
   1021   StreamReleaserCallback stream_releaser;
   1022 
   1023   SpdyStreamRequest request;
   1024   ASSERT_EQ(ERR_IO_PENDING,
   1025             request.StartRequest(
   1026                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
   1027                 BoundNetLog(),
   1028                 stream_releaser.MakeCallback(&request)));
   1029 
   1030   data.RunFor(1);
   1031 
   1032   EXPECT_EQ(OK, stream_releaser.WaitForResult());
   1033 
   1034   // Make sure that persisted data is cleared.
   1035   EXPECT_TRUE(
   1036       spdy_session_pool_->http_server_properties()->GetSpdySettings(
   1037           test_host_port_pair_).empty());
   1038 
   1039   // Make sure session's max_concurrent_streams is correct.
   1040   EXPECT_EQ(kInitialMaxConcurrentStreams + 1,
   1041             session->max_concurrent_streams());
   1042 
   1043   data.RunFor(1);
   1044   EXPECT_TRUE(session == NULL);
   1045 }
   1046 
   1047 // Start with max concurrent streams set to 1.  Request two streams.
   1048 // When the first completes, have the callback close its stream, which
   1049 // should trigger the second stream creation.  Then cancel that one
   1050 // immediately.  Don't crash.  This is a regression test for
   1051 // http://crbug.com/63532 .
   1052 TEST_P(SpdySessionTest, CancelPendingCreateStream) {
   1053   session_deps_.host_resolver->set_synchronous_mode(true);
   1054 
   1055   MockRead reads[] = {
   1056     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   1057   };
   1058 
   1059   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1060   MockConnect connect_data(SYNCHRONOUS, OK);
   1061 
   1062   data.set_connect_data(connect_data);
   1063   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1064 
   1065   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1066   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   1067 
   1068   CreateNetworkSession();
   1069 
   1070   // Initialize the SpdySetting with 1 max concurrent streams.
   1071   spdy_session_pool_->http_server_properties()->SetSpdySetting(
   1072       test_host_port_pair_,
   1073       SETTINGS_MAX_CONCURRENT_STREAMS,
   1074       SETTINGS_FLAG_PLEASE_PERSIST,
   1075       1);
   1076 
   1077   base::WeakPtr<SpdySession> session =
   1078       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1079 
   1080   // Leave room for only one more stream to be created.
   1081   for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
   1082     base::WeakPtr<SpdyStream> spdy_stream =
   1083         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1084                                   session, test_url_, MEDIUM, BoundNetLog());
   1085     ASSERT_TRUE(spdy_stream != NULL);
   1086   }
   1087 
   1088   // Create 2 more streams.  First will succeed.  Second will be pending.
   1089   base::WeakPtr<SpdyStream> spdy_stream1 =
   1090       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1091                                 session, test_url_, MEDIUM, BoundNetLog());
   1092   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1093 
   1094   // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
   1095   // a valgrind error if the callback is invoked when it's not supposed to be.
   1096   scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
   1097 
   1098   SpdyStreamRequest request;
   1099   ASSERT_EQ(ERR_IO_PENDING,
   1100             request.StartRequest(
   1101                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
   1102                 BoundNetLog(),
   1103                 callback->callback()));
   1104 
   1105   // Release the first one, this will allow the second to be created.
   1106   spdy_stream1->Cancel();
   1107   EXPECT_EQ(NULL, spdy_stream1.get());
   1108 
   1109   request.CancelRequest();
   1110   callback.reset();
   1111 
   1112   // Should not crash when running the pending callback.
   1113   base::MessageLoop::current()->RunUntilIdle();
   1114 }
   1115 
   1116 TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
   1117   session_deps_.host_resolver->set_synchronous_mode(true);
   1118 
   1119   MockRead reads[] = {
   1120     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   1121   };
   1122 
   1123   SettingsMap settings;
   1124   const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
   1125   const SpdySettingsIds kSpdySettingsIds2 = SETTINGS_INITIAL_WINDOW_SIZE;
   1126   const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024;
   1127   settings[kSpdySettingsIds1] =
   1128       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
   1129   if (spdy_util_.spdy_version() >= SPDY3) {
   1130     settings[kSpdySettingsIds2] =
   1131         SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize);
   1132   }
   1133   MockConnect connect_data(SYNCHRONOUS, OK);
   1134   scoped_ptr<SpdyFrame> settings_frame(
   1135       spdy_util_.ConstructSpdySettings(settings));
   1136   scoped_ptr<SpdyFrame> initial_window_update(
   1137       spdy_util_.ConstructSpdyWindowUpdate(
   1138           kSessionFlowControlStreamId,
   1139           kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
   1140   std::vector<MockWrite> writes;
   1141   if (GetParam() == kProtoHTTP2Draft04) {
   1142     writes.push_back(
   1143         MockWrite(ASYNC,
   1144                   kHttp2ConnectionHeaderPrefix,
   1145                   kHttp2ConnectionHeaderPrefixSize));
   1146   }
   1147   writes.push_back(CreateMockWrite(*settings_frame));
   1148   if (GetParam() >= kProtoSPDY31) {
   1149     writes.push_back(CreateMockWrite(*initial_window_update));
   1150   };
   1151 
   1152   SettingsMap server_settings;
   1153   const uint32 initial_max_concurrent_streams = 1;
   1154   server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
   1155       SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
   1156                             initial_max_concurrent_streams);
   1157   scoped_ptr<SpdyFrame> server_settings_frame(
   1158       spdy_util_.ConstructSpdySettings(server_settings));
   1159   writes.push_back(CreateMockWrite(*server_settings_frame));
   1160 
   1161   session_deps_.stream_initial_recv_window_size = kInitialRecvWindowSize;
   1162 
   1163   StaticSocketDataProvider data(reads, arraysize(reads),
   1164                                 vector_as_array(&writes), writes.size());
   1165   data.set_connect_data(connect_data);
   1166   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1167 
   1168   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1169   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   1170 
   1171   CreateNetworkSession();
   1172 
   1173   spdy_session_pool_->http_server_properties()->SetSpdySetting(
   1174       test_host_port_pair_,
   1175       SETTINGS_MAX_CONCURRENT_STREAMS,
   1176       SETTINGS_FLAG_PLEASE_PERSIST,
   1177       initial_max_concurrent_streams);
   1178 
   1179   SpdySessionPoolPeer pool_peer(spdy_session_pool_);
   1180   pool_peer.SetEnableSendingInitialData(true);
   1181 
   1182   base::WeakPtr<SpdySession> session =
   1183       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1184 
   1185   base::MessageLoop::current()->RunUntilIdle();
   1186   EXPECT_TRUE(data.at_write_eof());
   1187 }
   1188 
   1189 TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) {
   1190   CreateNetworkSession();
   1191 
   1192   base::WeakPtr<HttpServerProperties> test_http_server_properties =
   1193       spdy_session_pool_->http_server_properties();
   1194   SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2);
   1195   test_http_server_properties->SetSpdySetting(
   1196       test_host_port_pair_,
   1197       SETTINGS_MAX_CONCURRENT_STREAMS,
   1198       SETTINGS_FLAG_PLEASE_PERSIST,
   1199       2);
   1200   EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
   1201       test_host_port_pair_).size());
   1202   spdy_session_pool_->OnIPAddressChanged();
   1203   EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
   1204       test_host_port_pair_).size());
   1205 }
   1206 
   1207 TEST_P(SpdySessionTest, Initialize) {
   1208   CapturingBoundNetLog log;
   1209   session_deps_.net_log = log.bound().net_log();
   1210   session_deps_.host_resolver->set_synchronous_mode(true);
   1211 
   1212   MockConnect connect_data(SYNCHRONOUS, OK);
   1213   MockRead reads[] = {
   1214     MockRead(ASYNC, 0, 0)  // EOF
   1215   };
   1216 
   1217   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1218   data.set_connect_data(connect_data);
   1219   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1220 
   1221   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1222   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   1223 
   1224   CreateNetworkSession();
   1225 
   1226   base::WeakPtr<SpdySession> session =
   1227       CreateInsecureSpdySession(http_session_, key_, log.bound());
   1228   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   1229 
   1230   // Flush the read completion task.
   1231   base::MessageLoop::current()->RunUntilIdle();
   1232 
   1233   net::CapturingNetLog::CapturedEntryList entries;
   1234   log.GetEntries(&entries);
   1235   EXPECT_LT(0u, entries.size());
   1236 
   1237   // Check that we logged TYPE_SPDY_SESSION_INITIALIZED correctly.
   1238   int pos = net::ExpectLogContainsSomewhere(
   1239       entries, 0,
   1240       net::NetLog::TYPE_SPDY_SESSION_INITIALIZED,
   1241       net::NetLog::PHASE_NONE);
   1242   EXPECT_LT(0, pos);
   1243 
   1244   CapturingNetLog::CapturedEntry entry = entries[pos];
   1245   NetLog::Source socket_source;
   1246   EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(),
   1247                                                   &socket_source));
   1248   EXPECT_TRUE(socket_source.IsValid());
   1249   EXPECT_NE(log.bound().source().id, socket_source.id);
   1250 }
   1251 
   1252 TEST_P(SpdySessionTest, CloseSessionOnError) {
   1253   session_deps_.host_resolver->set_synchronous_mode(true);
   1254 
   1255   MockConnect connect_data(SYNCHRONOUS, OK);
   1256   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
   1257   MockRead reads[] = {
   1258     CreateMockRead(*goaway),
   1259     MockRead(SYNCHRONOUS, 0, 0)  // EOF
   1260   };
   1261 
   1262   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1263   data.set_connect_data(connect_data);
   1264   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1265 
   1266   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1267   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   1268 
   1269   CreateNetworkSession();
   1270 
   1271   CapturingBoundNetLog log;
   1272   base::WeakPtr<SpdySession> session =
   1273       CreateInsecureSpdySession(http_session_, key_, log.bound());
   1274   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   1275 
   1276   // Flush the read completion task.
   1277   base::MessageLoop::current()->RunUntilIdle();
   1278 
   1279   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
   1280   EXPECT_TRUE(session == NULL);
   1281 
   1282   // Check that the NetLog was filled reasonably.
   1283   net::CapturingNetLog::CapturedEntryList entries;
   1284   log.GetEntries(&entries);
   1285   EXPECT_LT(0u, entries.size());
   1286 
   1287   // Check that we logged SPDY_SESSION_CLOSE correctly.
   1288   int pos = net::ExpectLogContainsSomewhere(
   1289       entries, 0,
   1290       net::NetLog::TYPE_SPDY_SESSION_CLOSE,
   1291       net::NetLog::PHASE_NONE);
   1292 
   1293   if (pos < static_cast<int>(entries.size())) {
   1294     CapturingNetLog::CapturedEntry entry = entries[pos];
   1295     int error_code = 0;
   1296     ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
   1297     EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code);
   1298   } else {
   1299     ADD_FAILURE();
   1300   }
   1301 }
   1302 
   1303 // Queue up a low-priority SYN_STREAM followed by a high-priority
   1304 // one. The high priority one should still send first and receive
   1305 // first.
   1306 TEST_P(SpdySessionTest, OutOfOrderSynStreams) {
   1307   // Construct the request.
   1308   MockConnect connect_data(SYNCHRONOUS, OK);
   1309   scoped_ptr<SpdyFrame> req_highest(
   1310       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, HIGHEST, true));
   1311   scoped_ptr<SpdyFrame> req_lowest(
   1312       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
   1313   MockWrite writes[] = {
   1314     CreateMockWrite(*req_highest, 0),
   1315     CreateMockWrite(*req_lowest, 1),
   1316   };
   1317 
   1318   scoped_ptr<SpdyFrame> resp_highest(
   1319       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   1320   scoped_ptr<SpdyFrame> body_highest(
   1321       spdy_util_.ConstructSpdyBodyFrame(1, true));
   1322   scoped_ptr<SpdyFrame> resp_lowest(
   1323       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   1324   scoped_ptr<SpdyFrame> body_lowest(
   1325       spdy_util_.ConstructSpdyBodyFrame(3, true));
   1326   MockRead reads[] = {
   1327     CreateMockRead(*resp_highest, 2),
   1328     CreateMockRead(*body_highest, 3),
   1329     CreateMockRead(*resp_lowest, 4),
   1330     CreateMockRead(*body_lowest, 5),
   1331     MockRead(ASYNC, 0, 6)  // EOF
   1332   };
   1333 
   1334   session_deps_.host_resolver->set_synchronous_mode(true);
   1335 
   1336   DeterministicSocketData data(reads, arraysize(reads),
   1337                                writes, arraysize(writes));
   1338   data.set_connect_data(connect_data);
   1339   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1340 
   1341   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1342   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1343 
   1344   CreateDeterministicNetworkSession();
   1345 
   1346   base::WeakPtr<SpdySession> session =
   1347       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1348 
   1349   GURL url("http://www.google.com");
   1350 
   1351   base::WeakPtr<SpdyStream> spdy_stream_lowest =
   1352       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1353                                 session, url, LOWEST, BoundNetLog());
   1354   ASSERT_TRUE(spdy_stream_lowest);
   1355   EXPECT_EQ(0u, spdy_stream_lowest->stream_id());
   1356   test::StreamDelegateDoNothing delegate_lowest(spdy_stream_lowest);
   1357   spdy_stream_lowest->SetDelegate(&delegate_lowest);
   1358 
   1359   base::WeakPtr<SpdyStream> spdy_stream_highest =
   1360       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1361                                 session, url, HIGHEST, BoundNetLog());
   1362   ASSERT_TRUE(spdy_stream_highest);
   1363   EXPECT_EQ(0u, spdy_stream_highest->stream_id());
   1364   test::StreamDelegateDoNothing delegate_highest(spdy_stream_highest);
   1365   spdy_stream_highest->SetDelegate(&delegate_highest);
   1366 
   1367   // Queue the lower priority one first.
   1368 
   1369   scoped_ptr<SpdyHeaderBlock> headers_lowest(
   1370       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   1371   spdy_stream_lowest->SendRequestHeaders(
   1372       headers_lowest.Pass(), NO_MORE_DATA_TO_SEND);
   1373   EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders());
   1374 
   1375   scoped_ptr<SpdyHeaderBlock> headers_highest(
   1376       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   1377   spdy_stream_highest->SendRequestHeaders(
   1378       headers_highest.Pass(), NO_MORE_DATA_TO_SEND);
   1379   EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders());
   1380 
   1381   data.RunFor(7);
   1382 
   1383   EXPECT_FALSE(spdy_stream_lowest);
   1384   EXPECT_FALSE(spdy_stream_highest);
   1385   EXPECT_EQ(3u, delegate_lowest.stream_id());
   1386   EXPECT_EQ(1u, delegate_highest.stream_id());
   1387 }
   1388 
   1389 TEST_P(SpdySessionTest, CancelStream) {
   1390   MockConnect connect_data(SYNCHRONOUS, OK);
   1391   // Request 1, at HIGHEST priority, will be cancelled before it writes data.
   1392   // Request 2, at LOWEST priority, will be a full request and will be id 1.
   1393   scoped_ptr<SpdyFrame> req2(
   1394       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   1395   MockWrite writes[] = {
   1396     CreateMockWrite(*req2, 0),
   1397   };
   1398 
   1399   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   1400   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   1401   MockRead reads[] = {
   1402     CreateMockRead(*resp2, 1),
   1403     CreateMockRead(*body2, 2),
   1404     MockRead(ASYNC, 0, 3)  // EOF
   1405   };
   1406 
   1407   session_deps_.host_resolver->set_synchronous_mode(true);
   1408 
   1409   DeterministicSocketData data(reads, arraysize(reads),
   1410                                writes, arraysize(writes));
   1411   data.set_connect_data(connect_data);
   1412   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1413 
   1414   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1415   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1416 
   1417   CreateDeterministicNetworkSession();
   1418 
   1419   base::WeakPtr<SpdySession> session =
   1420       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1421 
   1422   GURL url1("http://www.google.com");
   1423   base::WeakPtr<SpdyStream> spdy_stream1 =
   1424       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1425                                 session, url1, HIGHEST, BoundNetLog());
   1426   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1427   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1428   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   1429   spdy_stream1->SetDelegate(&delegate1);
   1430 
   1431   GURL url2("http://www.google.com");
   1432   base::WeakPtr<SpdyStream> spdy_stream2 =
   1433       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1434                                 session, url2, LOWEST, BoundNetLog());
   1435   ASSERT_TRUE(spdy_stream2.get() != NULL);
   1436   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1437   test::StreamDelegateDoNothing delegate2(spdy_stream2);
   1438   spdy_stream2->SetDelegate(&delegate2);
   1439 
   1440   scoped_ptr<SpdyHeaderBlock> headers(
   1441       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   1442   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1443   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   1444 
   1445   scoped_ptr<SpdyHeaderBlock> headers2(
   1446       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   1447   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   1448   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   1449 
   1450   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1451 
   1452   spdy_stream1->Cancel();
   1453   EXPECT_EQ(NULL, spdy_stream1.get());
   1454 
   1455   EXPECT_EQ(0u, delegate1.stream_id());
   1456 
   1457   data.RunFor(1);
   1458 
   1459   EXPECT_EQ(0u, delegate1.stream_id());
   1460   EXPECT_EQ(1u, delegate2.stream_id());
   1461 
   1462   spdy_stream2->Cancel();
   1463   EXPECT_EQ(NULL, spdy_stream2.get());
   1464 }
   1465 
   1466 // Create two streams that are set to re-close themselves on close,
   1467 // and then close the session. Nothing should blow up. Also a
   1468 // regression test for http://crbug.com/139518 .
   1469 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
   1470   session_deps_.host_resolver->set_synchronous_mode(true);
   1471 
   1472   MockConnect connect_data(SYNCHRONOUS, OK);
   1473 
   1474   // No actual data will be sent.
   1475   MockWrite writes[] = {
   1476     MockWrite(ASYNC, 0, 1)  // EOF
   1477   };
   1478 
   1479   MockRead reads[] = {
   1480     MockRead(ASYNC, 0, 0)  // EOF
   1481   };
   1482   DeterministicSocketData data(reads, arraysize(reads),
   1483                                writes, arraysize(writes));
   1484   data.set_connect_data(connect_data);
   1485   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1486 
   1487   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1488   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1489 
   1490   CreateDeterministicNetworkSession();
   1491 
   1492   base::WeakPtr<SpdySession> session =
   1493       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1494 
   1495   GURL url1("http://www.google.com");
   1496   base::WeakPtr<SpdyStream> spdy_stream1 =
   1497       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1498                                 session, url1, HIGHEST, BoundNetLog());
   1499   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1500   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1501 
   1502   GURL url2("http://www.google.com");
   1503   base::WeakPtr<SpdyStream> spdy_stream2 =
   1504       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1505                                 session, url2, LOWEST, BoundNetLog());
   1506   ASSERT_TRUE(spdy_stream2.get() != NULL);
   1507   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1508 
   1509   test::ClosingDelegate delegate1(spdy_stream1);
   1510   spdy_stream1->SetDelegate(&delegate1);
   1511 
   1512   test::ClosingDelegate delegate2(spdy_stream2);
   1513   spdy_stream2->SetDelegate(&delegate2);
   1514 
   1515   scoped_ptr<SpdyHeaderBlock> headers(
   1516       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   1517   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1518   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   1519 
   1520   scoped_ptr<SpdyHeaderBlock> headers2(
   1521       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   1522   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   1523   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   1524 
   1525   // Ensure that the streams have not yet been activated and assigned an id.
   1526   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1527   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1528 
   1529   // Ensure we don't crash while closing the session.
   1530   session->CloseSessionOnError(ERR_ABORTED, std::string());
   1531 
   1532   EXPECT_EQ(NULL, spdy_stream1.get());
   1533   EXPECT_EQ(NULL, spdy_stream2.get());
   1534 
   1535   EXPECT_TRUE(delegate1.StreamIsClosed());
   1536   EXPECT_TRUE(delegate2.StreamIsClosed());
   1537 
   1538   EXPECT_TRUE(session == NULL);
   1539 }
   1540 
   1541 // Create two streams that are set to close each other on close, and
   1542 // then close the session. Nothing should blow up.
   1543 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
   1544   session_deps_.host_resolver->set_synchronous_mode(true);
   1545 
   1546   MockConnect connect_data(SYNCHRONOUS, OK);
   1547 
   1548   // No actual data will be sent.
   1549   MockWrite writes[] = {
   1550     MockWrite(ASYNC, 0, 1)  // EOF
   1551   };
   1552 
   1553   MockRead reads[] = {
   1554     MockRead(ASYNC, 0, 0)  // EOF
   1555   };
   1556   DeterministicSocketData data(reads, arraysize(reads),
   1557                                writes, arraysize(writes));
   1558   data.set_connect_data(connect_data);
   1559   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1560 
   1561   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1562   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1563 
   1564   CreateDeterministicNetworkSession();
   1565 
   1566   base::WeakPtr<SpdySession> session =
   1567       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1568 
   1569   GURL url1("http://www.google.com");
   1570   base::WeakPtr<SpdyStream> spdy_stream1 =
   1571       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1572                                 session, url1, HIGHEST, BoundNetLog());
   1573   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1574   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1575 
   1576   GURL url2("http://www.google.com");
   1577   base::WeakPtr<SpdyStream> spdy_stream2 =
   1578       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1579                                 session, url2, LOWEST, BoundNetLog());
   1580   ASSERT_TRUE(spdy_stream2.get() != NULL);
   1581   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1582 
   1583   // Make |spdy_stream1| close |spdy_stream2|.
   1584   test::ClosingDelegate delegate1(spdy_stream2);
   1585   spdy_stream1->SetDelegate(&delegate1);
   1586 
   1587   // Make |spdy_stream2| close |spdy_stream1|.
   1588   test::ClosingDelegate delegate2(spdy_stream1);
   1589   spdy_stream2->SetDelegate(&delegate2);
   1590 
   1591   scoped_ptr<SpdyHeaderBlock> headers(
   1592       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   1593   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1594   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   1595 
   1596   scoped_ptr<SpdyHeaderBlock> headers2(
   1597       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   1598   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   1599   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   1600 
   1601   // Ensure that the streams have not yet been activated and assigned an id.
   1602   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1603   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1604 
   1605   // Ensure we don't crash while closing the session.
   1606   session->CloseSessionOnError(ERR_ABORTED, std::string());
   1607 
   1608   EXPECT_EQ(NULL, spdy_stream1.get());
   1609   EXPECT_EQ(NULL, spdy_stream2.get());
   1610 
   1611   EXPECT_TRUE(delegate1.StreamIsClosed());
   1612   EXPECT_TRUE(delegate2.StreamIsClosed());
   1613 
   1614   EXPECT_TRUE(session == NULL);
   1615 }
   1616 
   1617 // Create two streams that are set to re-close themselves on close,
   1618 // activate them, and then close the session. Nothing should blow up.
   1619 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
   1620   session_deps_.host_resolver->set_synchronous_mode(true);
   1621 
   1622   MockConnect connect_data(SYNCHRONOUS, OK);
   1623 
   1624   scoped_ptr<SpdyFrame> req1(
   1625       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   1626   scoped_ptr<SpdyFrame> req2(
   1627       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
   1628   MockWrite writes[] = {
   1629     CreateMockWrite(*req1, 0),
   1630     CreateMockWrite(*req2, 1),
   1631   };
   1632 
   1633   MockRead reads[] = {
   1634     MockRead(ASYNC, 0, 2)  // EOF
   1635   };
   1636 
   1637   DeterministicSocketData data(reads, arraysize(reads),
   1638                                writes, arraysize(writes));
   1639   data.set_connect_data(connect_data);
   1640   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1641 
   1642   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1643   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1644 
   1645   CreateDeterministicNetworkSession();
   1646 
   1647   base::WeakPtr<SpdySession> session =
   1648       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1649 
   1650   GURL url1("http://www.google.com");
   1651   base::WeakPtr<SpdyStream> spdy_stream1 =
   1652       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1653                                 session, url1, MEDIUM, BoundNetLog());
   1654   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1655   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1656 
   1657   GURL url2("http://www.google.com");
   1658   base::WeakPtr<SpdyStream> spdy_stream2 =
   1659       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1660                                 session, url2, MEDIUM, BoundNetLog());
   1661   ASSERT_TRUE(spdy_stream2.get() != NULL);
   1662   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1663 
   1664   test::ClosingDelegate delegate1(spdy_stream1);
   1665   spdy_stream1->SetDelegate(&delegate1);
   1666 
   1667   test::ClosingDelegate delegate2(spdy_stream2);
   1668   spdy_stream2->SetDelegate(&delegate2);
   1669 
   1670   scoped_ptr<SpdyHeaderBlock> headers(
   1671       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   1672   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1673   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   1674 
   1675   scoped_ptr<SpdyHeaderBlock> headers2(
   1676       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   1677   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   1678   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   1679 
   1680   // Ensure that the streams have not yet been activated and assigned an id.
   1681   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1682   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1683 
   1684   data.RunFor(2);
   1685 
   1686   EXPECT_EQ(1u, spdy_stream1->stream_id());
   1687   EXPECT_EQ(3u, spdy_stream2->stream_id());
   1688 
   1689   // Ensure we don't crash while closing the session.
   1690   session->CloseSessionOnError(ERR_ABORTED, std::string());
   1691 
   1692   EXPECT_EQ(NULL, spdy_stream1.get());
   1693   EXPECT_EQ(NULL, spdy_stream2.get());
   1694 
   1695   EXPECT_TRUE(delegate1.StreamIsClosed());
   1696   EXPECT_TRUE(delegate2.StreamIsClosed());
   1697 
   1698   EXPECT_TRUE(session == NULL);
   1699 }
   1700 
   1701 // Create two streams that are set to close each other on close,
   1702 // activate them, and then close the session. Nothing should blow up.
   1703 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
   1704   session_deps_.host_resolver->set_synchronous_mode(true);
   1705 
   1706   MockConnect connect_data(SYNCHRONOUS, OK);
   1707 
   1708   scoped_ptr<SpdyFrame> req1(
   1709       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   1710   scoped_ptr<SpdyFrame> req2(
   1711       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
   1712   MockWrite writes[] = {
   1713     CreateMockWrite(*req1, 0),
   1714     CreateMockWrite(*req2, 1),
   1715   };
   1716 
   1717   MockRead reads[] = {
   1718     MockRead(ASYNC, 0, 2)  // EOF
   1719   };
   1720 
   1721   DeterministicSocketData data(reads, arraysize(reads),
   1722                                writes, arraysize(writes));
   1723   data.set_connect_data(connect_data);
   1724   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1725 
   1726   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1727   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1728 
   1729   CreateDeterministicNetworkSession();
   1730 
   1731   base::WeakPtr<SpdySession> session =
   1732       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1733 
   1734   GURL url1("http://www.google.com");
   1735   base::WeakPtr<SpdyStream> spdy_stream1 =
   1736       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1737                                 session, url1, MEDIUM, BoundNetLog());
   1738   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1739   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1740 
   1741   GURL url2("http://www.google.com");
   1742   base::WeakPtr<SpdyStream> spdy_stream2 =
   1743       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1744                                 session, url2, MEDIUM, BoundNetLog());
   1745   ASSERT_TRUE(spdy_stream2.get() != NULL);
   1746   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1747 
   1748   // Make |spdy_stream1| close |spdy_stream2|.
   1749   test::ClosingDelegate delegate1(spdy_stream2);
   1750   spdy_stream1->SetDelegate(&delegate1);
   1751 
   1752   // Make |spdy_stream2| close |spdy_stream1|.
   1753   test::ClosingDelegate delegate2(spdy_stream1);
   1754   spdy_stream2->SetDelegate(&delegate2);
   1755 
   1756   scoped_ptr<SpdyHeaderBlock> headers(
   1757       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   1758   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1759   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   1760 
   1761   scoped_ptr<SpdyHeaderBlock> headers2(
   1762       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   1763   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   1764   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   1765 
   1766   // Ensure that the streams have not yet been activated and assigned an id.
   1767   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1768   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1769 
   1770   data.RunFor(2);
   1771 
   1772   EXPECT_EQ(1u, spdy_stream1->stream_id());
   1773   EXPECT_EQ(3u, spdy_stream2->stream_id());
   1774 
   1775   // Ensure we don't crash while closing the session.
   1776   session->CloseSessionOnError(ERR_ABORTED, std::string());
   1777 
   1778   EXPECT_EQ(NULL, spdy_stream1.get());
   1779   EXPECT_EQ(NULL, spdy_stream2.get());
   1780 
   1781   EXPECT_TRUE(delegate1.StreamIsClosed());
   1782   EXPECT_TRUE(delegate2.StreamIsClosed());
   1783 
   1784   EXPECT_TRUE(session == NULL);
   1785 }
   1786 
   1787 // Delegate that closes a given session when the stream is closed.
   1788 class SessionClosingDelegate : public test::StreamDelegateDoNothing {
   1789  public:
   1790   SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
   1791                          const base::WeakPtr<SpdySession>& session_to_close)
   1792       : StreamDelegateDoNothing(stream),
   1793         session_to_close_(session_to_close) {}
   1794 
   1795   virtual ~SessionClosingDelegate() {}
   1796 
   1797   virtual void OnClose(int status) OVERRIDE {
   1798     session_to_close_->CloseSessionOnError(ERR_ABORTED, "Aborted");
   1799   }
   1800 
   1801  private:
   1802   base::WeakPtr<SpdySession> session_to_close_;
   1803 };
   1804 
   1805 // Close an activated stream that closes its session. Nothing should
   1806 // blow up. This is a regression test for http://crbug.com/263691 .
   1807 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
   1808   session_deps_.host_resolver->set_synchronous_mode(true);
   1809 
   1810   MockConnect connect_data(SYNCHRONOUS, OK);
   1811 
   1812   scoped_ptr<SpdyFrame> req(
   1813       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   1814   MockWrite writes[] = {
   1815     CreateMockWrite(*req, 0),
   1816   };
   1817 
   1818   MockRead reads[] = {
   1819     MockRead(ASYNC, 0, 1)  // EOF
   1820   };
   1821   DeterministicSocketData data(reads, arraysize(reads),
   1822                                writes, arraysize(writes));
   1823   data.set_connect_data(connect_data);
   1824   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1825 
   1826   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1827   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1828 
   1829   CreateDeterministicNetworkSession();
   1830 
   1831   base::WeakPtr<SpdySession> session =
   1832       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1833 
   1834   GURL url("http://www.google.com");
   1835   base::WeakPtr<SpdyStream> spdy_stream =
   1836       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1837                                 session, url, MEDIUM, BoundNetLog());
   1838   ASSERT_TRUE(spdy_stream.get() != NULL);
   1839   EXPECT_EQ(0u, spdy_stream->stream_id());
   1840 
   1841   SessionClosingDelegate delegate(spdy_stream, session);
   1842   spdy_stream->SetDelegate(&delegate);
   1843 
   1844   scoped_ptr<SpdyHeaderBlock> headers(
   1845       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   1846   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1847   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
   1848 
   1849   EXPECT_EQ(0u, spdy_stream->stream_id());
   1850 
   1851   data.RunFor(1);
   1852 
   1853   EXPECT_EQ(1u, spdy_stream->stream_id());
   1854 
   1855   // Ensure we don't crash while closing the stream (which closes the
   1856   // session).
   1857   spdy_stream->Cancel();
   1858 
   1859   EXPECT_EQ(NULL, spdy_stream.get());
   1860   EXPECT_TRUE(delegate.StreamIsClosed());
   1861   EXPECT_TRUE(session == NULL);
   1862 }
   1863 
   1864 TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
   1865   session_deps_.host_resolver->set_synchronous_mode(true);
   1866 
   1867   MockConnect connect_data(SYNCHRONOUS, OK);
   1868 
   1869   // No actual data will be sent.
   1870   MockWrite writes[] = {
   1871     MockWrite(ASYNC, 0, 1)  // EOF
   1872   };
   1873 
   1874   MockRead reads[] = {
   1875     MockRead(ASYNC, 0, 0)  // EOF
   1876   };
   1877   DeterministicSocketData data(reads, arraysize(reads),
   1878                                writes, arraysize(writes));
   1879   data.set_connect_data(connect_data);
   1880   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1881 
   1882   // Load a cert that is valid for:
   1883   //   www.example.org
   1884   //   mail.example.org
   1885   //   www.example.com
   1886   base::FilePath certs_dir = GetTestCertsDirectory();
   1887   scoped_refptr<X509Certificate> test_cert(
   1888       ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
   1889   ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
   1890 
   1891   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1892   ssl.cert = test_cert;
   1893   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1894 
   1895   CreateDeterministicNetworkSession();
   1896 
   1897   base::WeakPtr<SpdySession> session =
   1898       CreateSecureSpdySession(http_session_, key_, BoundNetLog());
   1899 
   1900   EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
   1901   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
   1902   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com"));
   1903   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
   1904 }
   1905 
   1906 TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) {
   1907   session_deps_.host_resolver->set_synchronous_mode(true);
   1908 
   1909   MockConnect connect_data(SYNCHRONOUS, OK);
   1910 
   1911   // No actual data will be sent.
   1912   MockWrite writes[] = {
   1913     MockWrite(ASYNC, 0, 1)  // EOF
   1914   };
   1915 
   1916   MockRead reads[] = {
   1917     MockRead(ASYNC, 0, 0)  // EOF
   1918   };
   1919   DeterministicSocketData data(reads, arraysize(reads),
   1920                                writes, arraysize(writes));
   1921   data.set_connect_data(connect_data);
   1922   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1923 
   1924   // Load a cert that is valid for:
   1925   //   www.example.org
   1926   //   mail.example.org
   1927   //   www.example.com
   1928   base::FilePath certs_dir = GetTestCertsDirectory();
   1929   scoped_refptr<X509Certificate> test_cert(
   1930       ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
   1931   ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
   1932 
   1933   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   1934   ssl.channel_id_sent = true;
   1935   ssl.cert = test_cert;
   1936   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   1937 
   1938   CreateDeterministicNetworkSession();
   1939 
   1940   base::WeakPtr<SpdySession> session =
   1941       CreateSecureSpdySession(http_session_, key_, BoundNetLog());
   1942 
   1943   EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
   1944   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
   1945   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com"));
   1946   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
   1947 }
   1948 
   1949 TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
   1950   // TODO(rtenneti): Define a helper class/methods and move the common code in
   1951   // this file.
   1952   MockConnect connect_data(SYNCHRONOUS, OK);
   1953 
   1954   SettingsMap new_settings;
   1955   const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
   1956   const uint32 max_concurrent_streams = 1;
   1957   new_settings[kSpdySettingsIds1] =
   1958       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
   1959 
   1960   scoped_ptr<SpdyFrame> req1(
   1961       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   1962   scoped_ptr<SpdyFrame> req2(
   1963       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
   1964   scoped_ptr<SpdyFrame> req3(
   1965       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
   1966   MockWrite writes[] = {
   1967     CreateMockWrite(*req1, 1),
   1968     CreateMockWrite(*req2, 4),
   1969     CreateMockWrite(*req3, 7),
   1970   };
   1971 
   1972   // Set up the socket so we read a SETTINGS frame that sets max concurrent
   1973   // streams to 1.
   1974   scoped_ptr<SpdyFrame> settings_frame(
   1975       spdy_util_.ConstructSpdySettings(new_settings));
   1976 
   1977   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   1978   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   1979 
   1980   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   1981   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   1982 
   1983   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
   1984   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
   1985 
   1986   MockRead reads[] = {
   1987     CreateMockRead(*settings_frame),
   1988     CreateMockRead(*resp1, 2),
   1989     CreateMockRead(*body1, 3),
   1990     CreateMockRead(*resp2, 5),
   1991     CreateMockRead(*body2, 6),
   1992     CreateMockRead(*resp3, 8),
   1993     CreateMockRead(*body3, 9),
   1994     MockRead(ASYNC, 0, 10)  // EOF
   1995   };
   1996 
   1997   DeterministicSocketData data(reads, arraysize(reads),
   1998                                writes, arraysize(writes));
   1999   data.set_connect_data(connect_data);
   2000   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2001 
   2002   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2003   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2004 
   2005   CreateDeterministicNetworkSession();
   2006 
   2007   base::WeakPtr<SpdySession> session =
   2008       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2009 
   2010   // Read the settings frame.
   2011   data.RunFor(1);
   2012 
   2013   GURL url1("http://www.google.com");
   2014   base::WeakPtr<SpdyStream> spdy_stream1 =
   2015       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2016                                 session, url1, LOWEST, BoundNetLog());
   2017   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2018   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2019   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2020   spdy_stream1->SetDelegate(&delegate1);
   2021 
   2022   TestCompletionCallback callback2;
   2023   GURL url2("http://www.google.com");
   2024   SpdyStreamRequest request2;
   2025   ASSERT_EQ(ERR_IO_PENDING,
   2026             request2.StartRequest(
   2027                 SPDY_REQUEST_RESPONSE_STREAM,
   2028                 session, url2, LOWEST, BoundNetLog(), callback2.callback()));
   2029 
   2030   TestCompletionCallback callback3;
   2031   GURL url3("http://www.google.com");
   2032   SpdyStreamRequest request3;
   2033   ASSERT_EQ(ERR_IO_PENDING,
   2034             request3.StartRequest(
   2035                 SPDY_REQUEST_RESPONSE_STREAM,
   2036                 session, url3, LOWEST, BoundNetLog(), callback3.callback()));
   2037 
   2038   EXPECT_EQ(0u, session->num_active_streams());
   2039   EXPECT_EQ(1u, session->num_created_streams());
   2040   EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
   2041 
   2042   scoped_ptr<SpdyHeaderBlock> headers(
   2043       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2044   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2045   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2046 
   2047   // Run until 1st stream is activated and then closed.
   2048   EXPECT_EQ(0u, delegate1.stream_id());
   2049   data.RunFor(3);
   2050   EXPECT_EQ(NULL, spdy_stream1.get());
   2051   EXPECT_EQ(1u, delegate1.stream_id());
   2052 
   2053   EXPECT_EQ(0u, session->num_active_streams());
   2054   EXPECT_EQ(0u, session->num_created_streams());
   2055   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
   2056 
   2057   // Pump loop for SpdySession::ProcessPendingStreamRequests() to
   2058   // create the 2nd stream.
   2059   base::MessageLoop::current()->RunUntilIdle();
   2060 
   2061   EXPECT_EQ(0u, session->num_active_streams());
   2062   EXPECT_EQ(1u, session->num_created_streams());
   2063   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
   2064 
   2065   base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream();
   2066   test::StreamDelegateDoNothing delegate2(stream2);
   2067   stream2->SetDelegate(&delegate2);
   2068   scoped_ptr<SpdyHeaderBlock> headers2(
   2069       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   2070   stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   2071   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   2072 
   2073   // Run until 2nd stream is activated and then closed.
   2074   EXPECT_EQ(0u, delegate2.stream_id());
   2075   data.RunFor(3);
   2076   EXPECT_EQ(NULL, stream2.get());
   2077   EXPECT_EQ(3u, delegate2.stream_id());
   2078 
   2079   EXPECT_EQ(0u, session->num_active_streams());
   2080   EXPECT_EQ(0u, session->num_created_streams());
   2081   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2082 
   2083   // Pump loop for SpdySession::ProcessPendingStreamRequests() to
   2084   // create the 3rd stream.
   2085   base::MessageLoop::current()->RunUntilIdle();
   2086 
   2087   EXPECT_EQ(0u, session->num_active_streams());
   2088   EXPECT_EQ(1u, session->num_created_streams());
   2089   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2090 
   2091   base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream();
   2092   test::StreamDelegateDoNothing delegate3(stream3);
   2093   stream3->SetDelegate(&delegate3);
   2094   scoped_ptr<SpdyHeaderBlock> headers3(
   2095       spdy_util_.ConstructGetHeaderBlock(url3.spec()));
   2096   stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND);
   2097   EXPECT_TRUE(stream3->HasUrlFromHeaders());
   2098 
   2099   // Run until 2nd stream is activated and then closed.
   2100   EXPECT_EQ(0u, delegate3.stream_id());
   2101   data.RunFor(3);
   2102   EXPECT_EQ(NULL, stream3.get());
   2103   EXPECT_EQ(5u, delegate3.stream_id());
   2104 
   2105   EXPECT_EQ(0u, session->num_active_streams());
   2106   EXPECT_EQ(0u, session->num_created_streams());
   2107   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2108 
   2109   data.RunFor(1);
   2110 }
   2111 
   2112 TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
   2113   session_deps_.host_resolver->set_synchronous_mode(true);
   2114 
   2115   MockRead reads[] = {
   2116     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   2117   };
   2118 
   2119   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   2120   MockConnect connect_data(SYNCHRONOUS, OK);
   2121 
   2122   data.set_connect_data(connect_data);
   2123   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2124 
   2125   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2126   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2127 
   2128   CreateNetworkSession();
   2129 
   2130   base::WeakPtr<SpdySession> session =
   2131       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2132 
   2133   // Leave room for only one more stream to be created.
   2134   for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
   2135     base::WeakPtr<SpdyStream> spdy_stream =
   2136         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2137                                   session, test_url_, MEDIUM, BoundNetLog());
   2138     ASSERT_TRUE(spdy_stream != NULL);
   2139   }
   2140 
   2141   GURL url1("http://www.google.com");
   2142   base::WeakPtr<SpdyStream> spdy_stream1 =
   2143       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2144                                 session, url1, LOWEST, BoundNetLog());
   2145   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2146   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2147 
   2148   TestCompletionCallback callback2;
   2149   GURL url2("http://www.google.com");
   2150   SpdyStreamRequest request2;
   2151   ASSERT_EQ(ERR_IO_PENDING,
   2152             request2.StartRequest(
   2153                 SPDY_BIDIRECTIONAL_STREAM, session, url2, LOWEST, BoundNetLog(),
   2154                 callback2.callback()));
   2155 
   2156   TestCompletionCallback callback3;
   2157   GURL url3("http://www.google.com");
   2158   SpdyStreamRequest request3;
   2159   ASSERT_EQ(ERR_IO_PENDING,
   2160             request3.StartRequest(
   2161                 SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(),
   2162                 callback3.callback()));
   2163 
   2164   EXPECT_EQ(0u, session->num_active_streams());
   2165   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
   2166   EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
   2167 
   2168   // Cancel the first stream; this will allow the second stream to be created.
   2169   EXPECT_TRUE(spdy_stream1.get() != NULL);
   2170   spdy_stream1->Cancel();
   2171   EXPECT_EQ(NULL, spdy_stream1.get());
   2172 
   2173   EXPECT_EQ(OK, callback2.WaitForResult());
   2174   EXPECT_EQ(0u, session->num_active_streams());
   2175   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
   2176   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
   2177 
   2178   // Cancel the second stream; this will allow the third stream to be created.
   2179   base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream();
   2180   spdy_stream2->Cancel();
   2181   EXPECT_EQ(NULL, spdy_stream2.get());
   2182 
   2183   EXPECT_EQ(OK, callback3.WaitForResult());
   2184   EXPECT_EQ(0u, session->num_active_streams());
   2185   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
   2186   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2187 
   2188   // Cancel the third stream.
   2189   base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream();
   2190   spdy_stream3->Cancel();
   2191   EXPECT_EQ(NULL, spdy_stream3.get());
   2192   EXPECT_EQ(0u, session->num_active_streams());
   2193   EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams());
   2194   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2195 }
   2196 
   2197 TEST_P(SpdySessionTest, NeedsCredentials) {
   2198   MockConnect connect_data(SYNCHRONOUS, OK);
   2199   MockRead reads[] = {
   2200     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   2201   };
   2202   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   2203   data.set_connect_data(connect_data);
   2204   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2205 
   2206   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2207   ssl.channel_id_sent = true;
   2208   ssl.protocol_negotiated = GetParam();
   2209   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2210 
   2211   CreateNetworkSession();
   2212 
   2213   const GURL url("https://www.foo.com");
   2214   HostPortPair test_host_port_pair(url.host(), 443);
   2215   SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(),
   2216                      kPrivacyModeDisabled);
   2217 
   2218   base::WeakPtr<SpdySession> session =
   2219       CreateSecureSpdySession(http_session_, key, BoundNetLog());
   2220 
   2221   EXPECT_EQ(spdy_util_.spdy_version() >= SPDY3, session->NeedsCredentials());
   2222 
   2223   // Flush the read completion task.
   2224   base::MessageLoop::current()->RunUntilIdle();
   2225 
   2226   session->CloseSessionOnError(ERR_ABORTED, std::string());
   2227 }
   2228 
   2229 // Test that SpdySession::DoReadLoop reads data from the socket
   2230 // without yielding.  This test makes 32k - 1 bytes of data available
   2231 // on the socket for reading. It then verifies that it has read all
   2232 // the available data without yielding.
   2233 TEST_P(SpdySessionTest, ReadDataWithoutYielding) {
   2234   MockConnect connect_data(SYNCHRONOUS, OK);
   2235   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   2236 
   2237   scoped_ptr<SpdyFrame> req1(
   2238       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2239   MockWrite writes[] = {
   2240     CreateMockWrite(*req1, 0),
   2241   };
   2242 
   2243   // Build buffer of size kMaxReadBytesWithoutYielding / 4
   2244   // (-spdy_data_frame_size).
   2245   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
   2246   const int kPayloadSize =
   2247       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
   2248   TestDataStream test_stream;
   2249   scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
   2250   char* payload_data = payload->data();
   2251   test_stream.GetBytes(payload_data, kPayloadSize);
   2252 
   2253   scoped_ptr<SpdyFrame> partial_data_frame(
   2254       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
   2255   scoped_ptr<SpdyFrame> finish_data_frame(
   2256       framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN));
   2257 
   2258   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2259 
   2260   // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
   2261   // bytes.
   2262   MockRead reads[] = {
   2263     CreateMockRead(*resp1, 1),
   2264     CreateMockRead(*partial_data_frame, 2),
   2265     CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
   2266     CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
   2267     CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS),
   2268     MockRead(ASYNC, 0, 6)  // EOF
   2269   };
   2270 
   2271   // Create SpdySession and SpdyStream and send the request.
   2272   DeterministicSocketData data(reads, arraysize(reads),
   2273                                writes, arraysize(writes));
   2274   data.set_connect_data(connect_data);
   2275   session_deps_.host_resolver->set_synchronous_mode(true);
   2276   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2277 
   2278   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2279   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2280 
   2281   CreateDeterministicNetworkSession();
   2282 
   2283   base::WeakPtr<SpdySession> session =
   2284       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2285 
   2286   GURL url1("http://www.google.com");
   2287   base::WeakPtr<SpdyStream> spdy_stream1 =
   2288       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2289                                 session, url1, MEDIUM, BoundNetLog());
   2290   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2291   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2292   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2293   spdy_stream1->SetDelegate(&delegate1);
   2294 
   2295   scoped_ptr<SpdyHeaderBlock> headers1(
   2296       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2297   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   2298   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2299 
   2300   // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't
   2301   // post a task.
   2302   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
   2303 
   2304   // Run until 1st read.
   2305   EXPECT_EQ(0u, delegate1.stream_id());
   2306   data.RunFor(2);
   2307   EXPECT_EQ(1u, delegate1.stream_id());
   2308   EXPECT_EQ(0u, observer.executed_count());
   2309 
   2310   // Read all the data and verify SpdySession::DoReadLoop has not
   2311   // posted a task.
   2312   data.RunFor(4);
   2313   EXPECT_EQ(NULL, spdy_stream1.get());
   2314 
   2315   // Verify task observer's executed_count is zero, which indicates DoRead read
   2316   // all the available data.
   2317   EXPECT_EQ(0u, observer.executed_count());
   2318   EXPECT_TRUE(data.at_write_eof());
   2319   EXPECT_TRUE(data.at_read_eof());
   2320 }
   2321 
   2322 // Test that SpdySession::DoReadLoop yields while reading the
   2323 // data. This test makes 32k + 1 bytes of data available on the socket
   2324 // for reading. It then verifies that DoRead has yielded even though
   2325 // there is data available for it to read (i.e, socket()->Read didn't
   2326 // return ERR_IO_PENDING during socket reads).
   2327 TEST_P(SpdySessionTest, TestYieldingDuringReadData) {
   2328   MockConnect connect_data(SYNCHRONOUS, OK);
   2329   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   2330 
   2331   scoped_ptr<SpdyFrame> req1(
   2332       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2333   MockWrite writes[] = {
   2334     CreateMockWrite(*req1, 0),
   2335   };
   2336 
   2337   // Build buffer of size kMaxReadBytesWithoutYielding / 4
   2338   // (-spdy_data_frame_size).
   2339   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
   2340   const int kPayloadSize =
   2341       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
   2342   TestDataStream test_stream;
   2343   scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
   2344   char* payload_data = payload->data();
   2345   test_stream.GetBytes(payload_data, kPayloadSize);
   2346 
   2347   scoped_ptr<SpdyFrame> partial_data_frame(
   2348       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
   2349   scoped_ptr<SpdyFrame> finish_data_frame(
   2350       framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN));
   2351 
   2352   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2353 
   2354   // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
   2355   MockRead reads[] = {
   2356     CreateMockRead(*resp1, 1),
   2357     CreateMockRead(*partial_data_frame, 2),
   2358     CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
   2359     CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
   2360     CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS),
   2361     CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS),
   2362     MockRead(ASYNC, 0, 7)  // EOF
   2363   };
   2364 
   2365   // Create SpdySession and SpdyStream and send the request.
   2366   DeterministicSocketData data(reads, arraysize(reads),
   2367                                writes, arraysize(writes));
   2368   data.set_connect_data(connect_data);
   2369   session_deps_.host_resolver->set_synchronous_mode(true);
   2370   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2371 
   2372   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2373   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2374 
   2375   CreateDeterministicNetworkSession();
   2376 
   2377   base::WeakPtr<SpdySession> session =
   2378       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2379 
   2380   GURL url1("http://www.google.com");
   2381   base::WeakPtr<SpdyStream> spdy_stream1 =
   2382       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2383                                 session, url1, MEDIUM, BoundNetLog());
   2384   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2385   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2386   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2387   spdy_stream1->SetDelegate(&delegate1);
   2388 
   2389   scoped_ptr<SpdyHeaderBlock> headers1(
   2390       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2391   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   2392   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2393 
   2394   // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a
   2395   // task.
   2396   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
   2397 
   2398   // Run until 1st read.
   2399   EXPECT_EQ(0u, delegate1.stream_id());
   2400   data.RunFor(2);
   2401   EXPECT_EQ(1u, delegate1.stream_id());
   2402   EXPECT_EQ(0u, observer.executed_count());
   2403 
   2404   // Read all the data and verify SpdySession::DoReadLoop has posted a
   2405   // task.
   2406   data.RunFor(6);
   2407   EXPECT_EQ(NULL, spdy_stream1.get());
   2408 
   2409   // Verify task observer's executed_count is 1, which indicates DoRead has
   2410   // posted only one task and thus yielded though there is data available for it
   2411   // to read.
   2412   EXPECT_EQ(1u, observer.executed_count());
   2413   EXPECT_TRUE(data.at_write_eof());
   2414   EXPECT_TRUE(data.at_read_eof());
   2415 }
   2416 
   2417 // Test that SpdySession::DoReadLoop() tests interactions of yielding
   2418 // + async, by doing the following MockReads.
   2419 //
   2420 // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K
   2421 // ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K.
   2422 //
   2423 // The above reads 26K synchronously. Since that is less that 32K, we
   2424 // will attempt to read again. However, that DoRead() will return
   2425 // ERR_IO_PENDING (because of async read), so DoReadLoop() will
   2426 // yield. When we come back, DoRead() will read the results from the
   2427 // async read, and rest of the data synchronously.
   2428 TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) {
   2429   MockConnect connect_data(SYNCHRONOUS, OK);
   2430   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   2431 
   2432   scoped_ptr<SpdyFrame> req1(
   2433       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2434   MockWrite writes[] = {
   2435     CreateMockWrite(*req1, 0),
   2436   };
   2437 
   2438   // Build buffer of size kMaxReadBytesWithoutYielding / 4
   2439   // (-spdy_data_frame_size).
   2440   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
   2441   TestDataStream test_stream;
   2442   const int kEightKPayloadSize =
   2443       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
   2444   scoped_refptr<net::IOBuffer> eightk_payload(
   2445       new net::IOBuffer(kEightKPayloadSize));
   2446   char* eightk_payload_data = eightk_payload->data();
   2447   test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize);
   2448 
   2449   // Build buffer of 2k size.
   2450   TestDataStream test_stream2;
   2451   const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024;
   2452   scoped_refptr<net::IOBuffer> twok_payload(
   2453       new net::IOBuffer(kTwoKPayloadSize));
   2454   char* twok_payload_data = twok_payload->data();
   2455   test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);
   2456 
   2457   scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame(
   2458       1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE));
   2459   scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame(
   2460       1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE));
   2461   scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame(
   2462       1, "h", 1, DATA_FLAG_FIN));
   2463 
   2464   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2465 
   2466   MockRead reads[] = {
   2467     CreateMockRead(*resp1, 1),
   2468     CreateMockRead(*eightk_data_frame, 2),
   2469     CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS),
   2470     CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS),
   2471     CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS),
   2472     CreateMockRead(*eightk_data_frame, 6, ASYNC),
   2473     CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS),
   2474     CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS),
   2475     CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS),
   2476     CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS),
   2477     CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS),
   2478     MockRead(ASYNC, 0, 12)  // EOF
   2479   };
   2480 
   2481   // Create SpdySession and SpdyStream and send the request.
   2482   DeterministicSocketData data(reads, arraysize(reads),
   2483                                writes, arraysize(writes));
   2484   data.set_connect_data(connect_data);
   2485   session_deps_.host_resolver->set_synchronous_mode(true);
   2486   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2487 
   2488   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2489   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2490 
   2491   CreateDeterministicNetworkSession();
   2492 
   2493   base::WeakPtr<SpdySession> session =
   2494       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2495 
   2496   GURL url1("http://www.google.com");
   2497   base::WeakPtr<SpdyStream> spdy_stream1 =
   2498       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2499                                 session, url1, MEDIUM, BoundNetLog());
   2500   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2501   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2502   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2503   spdy_stream1->SetDelegate(&delegate1);
   2504 
   2505   scoped_ptr<SpdyHeaderBlock> headers1(
   2506       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2507   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   2508   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2509 
   2510   // Set up the TaskObserver to monitor SpdySession::DoReadLoop
   2511   // posting of tasks.
   2512   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
   2513 
   2514   // Run until 1st read.
   2515   EXPECT_EQ(0u, delegate1.stream_id());
   2516   data.RunFor(2);
   2517   EXPECT_EQ(1u, delegate1.stream_id());
   2518   EXPECT_EQ(0u, observer.executed_count());
   2519 
   2520   // Read all the data and verify SpdySession::DoReadLoop has posted a
   2521   // task.
   2522   data.RunFor(12);
   2523   EXPECT_EQ(NULL, spdy_stream1.get());
   2524 
   2525   // Verify task observer's executed_count is 1, which indicates DoRead has
   2526   // posted only one task and thus yielded though there is data available for
   2527   // it to read.
   2528   EXPECT_EQ(1u, observer.executed_count());
   2529   EXPECT_TRUE(data.at_write_eof());
   2530   EXPECT_TRUE(data.at_read_eof());
   2531 }
   2532 
   2533 // Send a GoAway frame when SpdySession is in DoReadLoop. Make sure
   2534 // nothing blows up.
   2535 TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) {
   2536   MockConnect connect_data(SYNCHRONOUS, OK);
   2537   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   2538 
   2539   scoped_ptr<SpdyFrame> req1(
   2540       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2541   MockWrite writes[] = {
   2542     CreateMockWrite(*req1, 0),
   2543   };
   2544 
   2545   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2546   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2547   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
   2548 
   2549   MockRead reads[] = {
   2550     CreateMockRead(*resp1, 1),
   2551     CreateMockRead(*body1, 2),
   2552     CreateMockRead(*goaway, 3),
   2553   };
   2554 
   2555   // Create SpdySession and SpdyStream and send the request.
   2556   DeterministicSocketData data(reads, arraysize(reads),
   2557                                writes, arraysize(writes));
   2558   data.set_connect_data(connect_data);
   2559   session_deps_.host_resolver->set_synchronous_mode(true);
   2560   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2561 
   2562   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2563   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2564 
   2565   CreateDeterministicNetworkSession();
   2566 
   2567   base::WeakPtr<SpdySession> session =
   2568       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2569 
   2570   GURL url1("http://www.google.com");
   2571   base::WeakPtr<SpdyStream> spdy_stream1 =
   2572       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2573                                 session, url1, MEDIUM, BoundNetLog());
   2574   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2575   spdy_stream1->SetDelegate(&delegate1);
   2576   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2577   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2578 
   2579   scoped_ptr<SpdyHeaderBlock> headers1(
   2580       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2581   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   2582   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2583 
   2584   // Run until 1st read.
   2585   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2586   data.RunFor(1);
   2587   EXPECT_EQ(1u, spdy_stream1->stream_id());
   2588 
   2589   // Run until GoAway.
   2590   data.RunFor(3);
   2591   EXPECT_EQ(NULL, spdy_stream1.get());
   2592   EXPECT_TRUE(data.at_write_eof());
   2593   EXPECT_TRUE(data.at_read_eof());
   2594   EXPECT_TRUE(session == NULL);
   2595 }
   2596 
   2597 // Within this framework, a SpdySession should be initialized with
   2598 // flow control disabled for protocol version 2, with flow control
   2599 // enabled only for streams for protocol version 3, and with flow
   2600 // control enabled for streams and sessions for higher versions.
   2601 TEST_P(SpdySessionTest, ProtocolNegotiation) {
   2602   session_deps_.host_resolver->set_synchronous_mode(true);
   2603 
   2604   MockConnect connect_data(SYNCHRONOUS, OK);
   2605   MockRead reads[] = {
   2606     MockRead(SYNCHRONOUS, 0, 0)  // EOF
   2607   };
   2608   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   2609   data.set_connect_data(connect_data);
   2610   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2611 
   2612   CreateNetworkSession();
   2613   base::WeakPtr<SpdySession> session =
   2614       CreateFakeSpdySession(spdy_session_pool_, key_);
   2615 
   2616   EXPECT_EQ(spdy_util_.spdy_version(),
   2617             session->buffered_spdy_framer_->protocol_version());
   2618   if (GetParam() == kProtoSPDY2) {
   2619     EXPECT_EQ(SpdySession::FLOW_CONTROL_NONE, session->flow_control_state());
   2620     EXPECT_EQ(0, session->session_send_window_size_);
   2621     EXPECT_EQ(0, session->session_recv_window_size_);
   2622   } else if (GetParam() == kProtoSPDY3) {
   2623     EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state());
   2624     EXPECT_EQ(0, session->session_send_window_size_);
   2625     EXPECT_EQ(0, session->session_recv_window_size_);
   2626   } else {
   2627     EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   2628               session->flow_control_state());
   2629     EXPECT_EQ(kSpdySessionInitialWindowSize,
   2630               session->session_send_window_size_);
   2631     EXPECT_EQ(kSpdySessionInitialWindowSize,
   2632               session->session_recv_window_size_);
   2633   }
   2634   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   2635 }
   2636 
   2637 // Tests the case of a non-SPDY request closing an idle SPDY session when no
   2638 // pointers to the idle session are currently held.
   2639 TEST_P(SpdySessionTest, CloseOneIdleConnection) {
   2640   ClientSocketPoolManager::set_max_sockets_per_group(
   2641       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   2642   ClientSocketPoolManager::set_max_sockets_per_pool(
   2643       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   2644 
   2645   MockConnect connect_data(SYNCHRONOUS, OK);
   2646   MockRead reads[] = {
   2647     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   2648   };
   2649   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   2650   data.set_connect_data(connect_data);
   2651   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2652   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2653 
   2654   CreateNetworkSession();
   2655 
   2656   TransportClientSocketPool* pool =
   2657       http_session_->GetTransportSocketPool(
   2658           HttpNetworkSession::NORMAL_SOCKET_POOL);
   2659 
   2660   // Create an idle SPDY session.
   2661   SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
   2662                       kPrivacyModeDisabled);
   2663   base::WeakPtr<SpdySession> session1 =
   2664       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
   2665   EXPECT_FALSE(pool->IsStalled());
   2666 
   2667   // Trying to create a new connection should cause the pool to be stalled, and
   2668   // post a task asynchronously to try and close the session.
   2669   TestCompletionCallback callback2;
   2670   HostPortPair host_port2("2.com", 80);
   2671   scoped_refptr<TransportSocketParams> params2(
   2672       new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
   2673                                 OnHostResolutionCallback()));
   2674   scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
   2675   EXPECT_EQ(ERR_IO_PENDING,
   2676             connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
   2677                               callback2.callback(), pool, BoundNetLog()));
   2678   EXPECT_TRUE(pool->IsStalled());
   2679 
   2680   // The socket pool should close the connection asynchronously and establish a
   2681   // new connection.
   2682   EXPECT_EQ(OK, callback2.WaitForResult());
   2683   EXPECT_FALSE(pool->IsStalled());
   2684   EXPECT_TRUE(session1 == NULL);
   2685 }
   2686 
   2687 // Tests the case of a non-SPDY request closing an idle SPDY session when no
   2688 // pointers to the idle session are currently held, in the case the SPDY session
   2689 // has an alias.
   2690 TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
   2691   ClientSocketPoolManager::set_max_sockets_per_group(
   2692       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   2693   ClientSocketPoolManager::set_max_sockets_per_pool(
   2694       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   2695 
   2696   MockConnect connect_data(SYNCHRONOUS, OK);
   2697   MockRead reads[] = {
   2698     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   2699   };
   2700   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   2701   data.set_connect_data(connect_data);
   2702   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2703   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2704 
   2705   session_deps_.host_resolver->set_synchronous_mode(true);
   2706   session_deps_.host_resolver->rules()->AddIPLiteralRule(
   2707       "1.com", "192.168.0.2", std::string());
   2708   session_deps_.host_resolver->rules()->AddIPLiteralRule(
   2709       "2.com", "192.168.0.2", std::string());
   2710   // Not strictly needed.
   2711   session_deps_.host_resolver->rules()->AddIPLiteralRule(
   2712       "3.com", "192.168.0.3", std::string());
   2713 
   2714   CreateNetworkSession();
   2715 
   2716   TransportClientSocketPool* pool =
   2717       http_session_->GetTransportSocketPool(
   2718           HttpNetworkSession::NORMAL_SOCKET_POOL);
   2719 
   2720   // Create an idle SPDY session.
   2721   SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
   2722                       kPrivacyModeDisabled);
   2723   base::WeakPtr<SpdySession> session1 =
   2724       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
   2725   EXPECT_FALSE(pool->IsStalled());
   2726 
   2727   // Set up an alias for the idle SPDY session, increasing its ref count to 2.
   2728   SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
   2729                       kPrivacyModeDisabled);
   2730   HostResolver::RequestInfo info(key2.host_port_pair());
   2731   AddressList addresses;
   2732   // Pre-populate the DNS cache, since a synchronous resolution is required in
   2733   // order to create the alias.
   2734   session_deps_.host_resolver->Resolve(
   2735       info, &addresses, CompletionCallback(), NULL, BoundNetLog());
   2736   // Get a session for |key2|, which should return the session created earlier.
   2737   base::WeakPtr<SpdySession> session2 =
   2738       spdy_session_pool_->FindAvailableSession(key2, BoundNetLog());
   2739   ASSERT_EQ(session1.get(), session2.get());
   2740   EXPECT_FALSE(pool->IsStalled());
   2741 
   2742   // Trying to create a new connection should cause the pool to be stalled, and
   2743   // post a task asynchronously to try and close the session.
   2744   TestCompletionCallback callback3;
   2745   HostPortPair host_port3("3.com", 80);
   2746   scoped_refptr<TransportSocketParams> params3(
   2747       new TransportSocketParams(host_port3, DEFAULT_PRIORITY, false, false,
   2748                                 OnHostResolutionCallback()));
   2749   scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle);
   2750   EXPECT_EQ(ERR_IO_PENDING,
   2751             connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
   2752                               callback3.callback(), pool, BoundNetLog()));
   2753   EXPECT_TRUE(pool->IsStalled());
   2754 
   2755   // The socket pool should close the connection asynchronously and establish a
   2756   // new connection.
   2757   EXPECT_EQ(OK, callback3.WaitForResult());
   2758   EXPECT_FALSE(pool->IsStalled());
   2759   EXPECT_TRUE(session1 == NULL);
   2760   EXPECT_TRUE(session2 == NULL);
   2761 }
   2762 
   2763 // Tests that a non-SPDY request can't close a SPDY session that's currently in
   2764 // use.
   2765 TEST_P(SpdySessionTest, CloseOneIdleConnectionFailsWhenSessionInUse) {
   2766   ClientSocketPoolManager::set_max_sockets_per_group(
   2767       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   2768   ClientSocketPoolManager::set_max_sockets_per_pool(
   2769       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   2770 
   2771   MockConnect connect_data(SYNCHRONOUS, OK);
   2772   MockRead reads[] = {
   2773     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   2774   };
   2775   scoped_ptr<SpdyFrame> req1(
   2776       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   2777   scoped_ptr<SpdyFrame> cancel1(
   2778       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   2779   MockWrite writes[] = {
   2780     CreateMockWrite(*req1, 1),
   2781     CreateMockWrite(*cancel1, 1),
   2782   };
   2783   StaticSocketDataProvider data(reads, arraysize(reads),
   2784                                      writes, arraysize(writes));
   2785   data.set_connect_data(connect_data);
   2786   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2787 
   2788   CreateNetworkSession();
   2789 
   2790   TransportClientSocketPool* pool =
   2791       http_session_->GetTransportSocketPool(
   2792           HttpNetworkSession::NORMAL_SOCKET_POOL);
   2793 
   2794   // Create a SPDY session.
   2795   GURL url1("http://www.google.com");
   2796   SpdySessionKey key1(HostPortPair(url1.host(), 80),
   2797                       ProxyServer::Direct(), kPrivacyModeDisabled);
   2798   base::WeakPtr<SpdySession> session1 =
   2799       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
   2800   EXPECT_FALSE(pool->IsStalled());
   2801 
   2802   // Create a stream using the session, and send a request.
   2803 
   2804   TestCompletionCallback callback1;
   2805   base::WeakPtr<SpdyStream> spdy_stream1 =
   2806       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2807                                 session1, url1, DEFAULT_PRIORITY,
   2808                                 BoundNetLog());
   2809   ASSERT_TRUE(spdy_stream1.get());
   2810   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2811   spdy_stream1->SetDelegate(&delegate1);
   2812 
   2813   scoped_ptr<SpdyHeaderBlock> headers1(
   2814       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2815   EXPECT_EQ(ERR_IO_PENDING,
   2816             spdy_stream1->SendRequestHeaders(
   2817                 headers1.Pass(), NO_MORE_DATA_TO_SEND));
   2818   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2819 
   2820   base::MessageLoop::current()->RunUntilIdle();
   2821 
   2822   // Trying to create a new connection should cause the pool to be stalled, and
   2823   // post a task asynchronously to try and close the session.
   2824   TestCompletionCallback callback2;
   2825   HostPortPair host_port2("2.com", 80);
   2826   scoped_refptr<TransportSocketParams> params2(
   2827       new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
   2828                                 OnHostResolutionCallback()));
   2829   scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
   2830   EXPECT_EQ(ERR_IO_PENDING,
   2831             connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
   2832                               callback2.callback(), pool, BoundNetLog()));
   2833   EXPECT_TRUE(pool->IsStalled());
   2834 
   2835   // Running the message loop should cause the socket pool to ask the SPDY
   2836   // session to close an idle socket, but since the socket is in use, nothing
   2837   // happens.
   2838   base::RunLoop().RunUntilIdle();
   2839   EXPECT_TRUE(pool->IsStalled());
   2840   EXPECT_FALSE(callback2.have_result());
   2841 
   2842   // Cancelling the request should still not release the session's socket,
   2843   // since the session is still kept alive by the SpdySessionPool.
   2844   ASSERT_TRUE(spdy_stream1.get());
   2845   spdy_stream1->Cancel();
   2846   base::RunLoop().RunUntilIdle();
   2847   EXPECT_TRUE(pool->IsStalled());
   2848   EXPECT_FALSE(callback2.have_result());
   2849   EXPECT_TRUE(session1 != NULL);
   2850 }
   2851 
   2852 // Verify that SpdySessionKey and therefore SpdySession is different when
   2853 // privacy mode is enabled or disabled.
   2854 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
   2855   CreateDeterministicNetworkSession();
   2856 
   2857   HostPortPair host_port_pair("www.google.com", 443);
   2858   SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
   2859                                      kPrivacyModeEnabled);
   2860   SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
   2861                                      kPrivacyModeDisabled);
   2862 
   2863   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   2864   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   2865 
   2866   // Add SpdySession with PrivacyMode Enabled to the pool.
   2867   base::WeakPtr<SpdySession> session_privacy_enabled =
   2868       CreateFakeSpdySession(spdy_session_pool_, key_privacy_enabled);
   2869 
   2870   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   2871   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   2872 
   2873   // Add SpdySession with PrivacyMode Disabled to the pool.
   2874   base::WeakPtr<SpdySession> session_privacy_disabled =
   2875       CreateFakeSpdySession(spdy_session_pool_, key_privacy_disabled);
   2876 
   2877   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   2878   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   2879 
   2880   session_privacy_enabled->CloseSessionOnError(ERR_ABORTED, std::string());
   2881   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   2882   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   2883 
   2884   session_privacy_disabled->CloseSessionOnError(ERR_ABORTED, std::string());
   2885   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   2886   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   2887 }
   2888 
   2889 // Delegate that creates another stream when its stream is closed.
   2890 class StreamCreatingDelegate : public test::StreamDelegateDoNothing {
   2891  public:
   2892   StreamCreatingDelegate(const base::WeakPtr<SpdyStream>& stream,
   2893                          const base::WeakPtr<SpdySession>& session)
   2894       : StreamDelegateDoNothing(stream),
   2895         session_(session) {}
   2896 
   2897   virtual ~StreamCreatingDelegate() {}
   2898 
   2899   virtual void OnClose(int status) OVERRIDE {
   2900     GURL url("http://www.google.com");
   2901     ignore_result(
   2902         CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2903                                   session_, url, MEDIUM, BoundNetLog()));
   2904   }
   2905 
   2906  private:
   2907   const base::WeakPtr<SpdySession> session_;
   2908 };
   2909 
   2910 // Create another stream in response to a stream being reset. Nothing
   2911 // should blow up. This is a regression test for
   2912 // http://crbug.com/263690 .
   2913 TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
   2914   session_deps_.host_resolver->set_synchronous_mode(true);
   2915 
   2916   MockConnect connect_data(SYNCHRONOUS, OK);
   2917 
   2918   scoped_ptr<SpdyFrame> req(
   2919       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2920   MockWrite writes[] = {
   2921     CreateMockWrite(*req, 0),
   2922   };
   2923 
   2924   scoped_ptr<SpdyFrame> rst(
   2925       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
   2926   MockRead reads[] = {
   2927     CreateMockRead(*rst, 1),
   2928     MockRead(ASYNC, 0, 2)  // EOF
   2929   };
   2930   DeterministicSocketData data(reads, arraysize(reads),
   2931                                writes, arraysize(writes));
   2932   data.set_connect_data(connect_data);
   2933   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2934 
   2935   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2936   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2937 
   2938   CreateDeterministicNetworkSession();
   2939 
   2940   base::WeakPtr<SpdySession> session =
   2941       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2942 
   2943   GURL url("http://www.google.com");
   2944   base::WeakPtr<SpdyStream> spdy_stream =
   2945       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2946                                 session, url, MEDIUM, BoundNetLog());
   2947   ASSERT_TRUE(spdy_stream.get() != NULL);
   2948   EXPECT_EQ(0u, spdy_stream->stream_id());
   2949 
   2950   StreamCreatingDelegate delegate(spdy_stream, session);
   2951   spdy_stream->SetDelegate(&delegate);
   2952 
   2953   scoped_ptr<SpdyHeaderBlock> headers(
   2954       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   2955   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2956   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
   2957 
   2958   EXPECT_EQ(0u, spdy_stream->stream_id());
   2959 
   2960   data.RunFor(1);
   2961 
   2962   EXPECT_EQ(1u, spdy_stream->stream_id());
   2963 
   2964   // Cause the stream to be reset, which should cause another stream
   2965   // to be created.
   2966   data.RunFor(1);
   2967 
   2968   EXPECT_EQ(NULL, spdy_stream.get());
   2969   EXPECT_TRUE(delegate.StreamIsClosed());
   2970   EXPECT_EQ(0u, session->num_active_streams());
   2971   EXPECT_EQ(1u, session->num_created_streams());
   2972 }
   2973 
   2974 // The tests below are only for SPDY/3 and above.
   2975 
   2976 TEST_P(SpdySessionTest, SendCredentials) {
   2977   if (GetParam() < kProtoSPDY3)
   2978     return;
   2979 
   2980   MockConnect connect_data(SYNCHRONOUS, OK);
   2981   MockRead reads[] = {
   2982     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   2983   };
   2984   SettingsMap settings;
   2985   scoped_ptr<SpdyFrame> settings_frame(
   2986       spdy_util_.ConstructSpdySettings(settings));
   2987   MockWrite writes[] = {
   2988     CreateMockWrite(*settings_frame),
   2989   };
   2990   StaticSocketDataProvider data(reads, arraysize(reads),
   2991                                 writes, arraysize(writes));
   2992   data.set_connect_data(connect_data);
   2993   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2994 
   2995   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2996   ssl.channel_id_sent = true;
   2997   ssl.protocol_negotiated = GetParam();
   2998   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2999 
   3000   CreateNetworkSession();
   3001 
   3002   const GURL kTestUrl("https://www.foo.com");
   3003   HostPortPair test_host_port_pair(kTestUrl.host(), 443);
   3004   SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(),
   3005                      kPrivacyModeDisabled);
   3006 
   3007   base::WeakPtr<SpdySession> session =
   3008       CreateSecureSpdySession(http_session_, key, BoundNetLog());
   3009 
   3010   EXPECT_TRUE(session->NeedsCredentials());
   3011 
   3012   // Flush the read completion task.
   3013   base::MessageLoop::current()->RunUntilIdle();
   3014 
   3015   session->CloseSessionOnError(ERR_ABORTED, std::string());
   3016   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key));
   3017 }
   3018 
   3019 TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
   3020   if (GetParam() < kProtoSPDY3)
   3021     return;
   3022 
   3023   // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
   3024   // gets sent.
   3025   SettingsMap new_settings;
   3026   int32 window_size = 1;
   3027   new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
   3028       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
   3029 
   3030   // Set up the socket so we read a SETTINGS frame that sets
   3031   // INITIAL_WINDOW_SIZE.
   3032   MockConnect connect_data(SYNCHRONOUS, OK);
   3033   scoped_ptr<SpdyFrame> settings_frame(
   3034       spdy_util_.ConstructSpdySettings(new_settings));
   3035   MockRead reads[] = {
   3036     CreateMockRead(*settings_frame, 0),
   3037     MockRead(ASYNC, 0, 1)  // EOF
   3038   };
   3039 
   3040   session_deps_.host_resolver->set_synchronous_mode(true);
   3041 
   3042   scoped_ptr<DeterministicSocketData> data(
   3043       new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
   3044   data->set_connect_data(connect_data);
   3045   session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get());
   3046 
   3047   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   3048   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3049 
   3050   CreateDeterministicNetworkSession();
   3051 
   3052   base::WeakPtr<SpdySession> session =
   3053       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3054   base::WeakPtr<SpdyStream> spdy_stream1 =
   3055       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3056                                 session, test_url_, MEDIUM, BoundNetLog());
   3057   ASSERT_TRUE(spdy_stream1.get() != NULL);
   3058   TestCompletionCallback callback1;
   3059   EXPECT_NE(spdy_stream1->send_window_size(), window_size);
   3060 
   3061   data->RunFor(1);  // Process the SETTINGS frame, but not the EOF
   3062   base::MessageLoop::current()->RunUntilIdle();
   3063   EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
   3064   EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
   3065 
   3066   // Release the first one, this will allow the second to be created.
   3067   spdy_stream1->Cancel();
   3068   EXPECT_EQ(NULL, spdy_stream1.get());
   3069 
   3070   base::WeakPtr<SpdyStream> spdy_stream2 =
   3071       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3072                                 session, test_url_, MEDIUM, BoundNetLog());
   3073   ASSERT_TRUE(spdy_stream2.get() != NULL);
   3074   EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
   3075   spdy_stream2->Cancel();
   3076   EXPECT_EQ(NULL, spdy_stream2.get());
   3077 }
   3078 
   3079 // The tests below are only for SPDY/3.1 and above.
   3080 
   3081 // SpdySession::{Increase,Decrease}RecvWindowSize should properly
   3082 // adjust the session receive window size for SPDY 3.1 and higher. In
   3083 // addition, SpdySession::IncreaseRecvWindowSize should trigger
   3084 // sending a WINDOW_UPDATE frame for a large enough delta.
   3085 TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
   3086   if (GetParam() < kProtoSPDY31)
   3087     return;
   3088 
   3089   session_deps_.host_resolver->set_synchronous_mode(true);
   3090 
   3091   const int32 delta_window_size = 100;
   3092 
   3093   MockConnect connect_data(SYNCHRONOUS, OK);
   3094   MockRead reads[] = {
   3095     MockRead(ASYNC, 0, 1)  // EOF
   3096   };
   3097   scoped_ptr<SpdyFrame> window_update(
   3098       spdy_util_.ConstructSpdyWindowUpdate(
   3099           kSessionFlowControlStreamId,
   3100           kSpdySessionInitialWindowSize + delta_window_size));
   3101   MockWrite writes[] = {
   3102     CreateMockWrite(*window_update, 0),
   3103   };
   3104   DeterministicSocketData data(reads, arraysize(reads),
   3105                                writes, arraysize(writes));
   3106   data.set_connect_data(connect_data);
   3107   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3108 
   3109   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   3110   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3111 
   3112   CreateDeterministicNetworkSession();
   3113   base::WeakPtr<SpdySession> session =
   3114       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3115   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3116             session->flow_control_state());
   3117 
   3118   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3119   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3120 
   3121   session->IncreaseRecvWindowSize(delta_window_size);
   3122   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
   3123             session->session_recv_window_size_);
   3124   EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_);
   3125 
   3126   // Should trigger sending a WINDOW_UPDATE frame.
   3127   session->IncreaseRecvWindowSize(kSpdySessionInitialWindowSize);
   3128   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size +
   3129             kSpdySessionInitialWindowSize,
   3130             session->session_recv_window_size_);
   3131   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3132 
   3133   data.RunFor(1);
   3134 
   3135   // DecreaseRecvWindowSize() expects |in_io_loop_| to be true.
   3136   session->in_io_loop_ = true;
   3137   session->DecreaseRecvWindowSize(
   3138       kSpdySessionInitialWindowSize + delta_window_size +
   3139       kSpdySessionInitialWindowSize);
   3140   session->in_io_loop_ = false;
   3141   EXPECT_EQ(0, session->session_recv_window_size_);
   3142   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3143 }
   3144 
   3145 // SpdySession::{Increase,Decrease}SendWindowSize should properly
   3146 // adjust the session send window size when the "enable_spdy_31" flag
   3147 // is set.
   3148 TEST_P(SpdySessionTest, AdjustSendWindowSize) {
   3149   if (GetParam() < kProtoSPDY31)
   3150     return;
   3151 
   3152   session_deps_.host_resolver->set_synchronous_mode(true);
   3153 
   3154   MockConnect connect_data(SYNCHRONOUS, OK);
   3155   MockRead reads[] = {
   3156     MockRead(SYNCHRONOUS, 0, 0)  // EOF
   3157   };
   3158   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   3159   data.set_connect_data(connect_data);
   3160   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3161 
   3162   CreateNetworkSession();
   3163   base::WeakPtr<SpdySession> session =
   3164       CreateFakeSpdySession(spdy_session_pool_, key_);
   3165   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3166             session->flow_control_state());
   3167 
   3168   const int32 delta_window_size = 100;
   3169 
   3170   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3171 
   3172   session->IncreaseSendWindowSize(delta_window_size);
   3173   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
   3174             session->session_send_window_size_);
   3175 
   3176   session->DecreaseSendWindowSize(delta_window_size);
   3177   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3178 }
   3179 
   3180 // Incoming data for an inactive stream should not cause the session
   3181 // receive window size to decrease, but it should cause the unacked
   3182 // bytes to increase.
   3183 TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) {
   3184   if (GetParam() < kProtoSPDY31)
   3185     return;
   3186 
   3187   session_deps_.host_resolver->set_synchronous_mode(true);
   3188 
   3189   MockConnect connect_data(SYNCHRONOUS, OK);
   3190   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false));
   3191   MockRead reads[] = {
   3192     CreateMockRead(*resp, 0),
   3193     MockRead(ASYNC, 0, 1)  // EOF
   3194   };
   3195   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
   3196   data.set_connect_data(connect_data);
   3197   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3198 
   3199   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   3200   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3201 
   3202   CreateDeterministicNetworkSession();
   3203   base::WeakPtr<SpdySession> session =
   3204       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3205   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3206             session->flow_control_state());
   3207 
   3208   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3209   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3210 
   3211   data.RunFor(1);
   3212 
   3213   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3214   EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_);
   3215 
   3216   data.RunFor(1);
   3217 }
   3218 
   3219 // A delegate that drops any received data.
   3220 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
   3221  public:
   3222   DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream,
   3223                            base::StringPiece data)
   3224       : StreamDelegateSendImmediate(stream, data) {}
   3225 
   3226   virtual ~DropReceivedDataDelegate() {}
   3227 
   3228   // Drop any received data.
   3229   virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {}
   3230 };
   3231 
   3232 // Send data back and forth but use a delegate that drops its received
   3233 // data. The receive window should still increase to its original
   3234 // value, i.e. we shouldn't "leak" receive window bytes.
   3235 TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
   3236   if (GetParam() < kProtoSPDY31)
   3237     return;
   3238 
   3239   const char kStreamUrl[] = "http://www.google.com/";
   3240 
   3241   const int32 msg_data_size = 100;
   3242   const std::string msg_data(msg_data_size, 'a');
   3243 
   3244   MockConnect connect_data(SYNCHRONOUS, OK);
   3245 
   3246   scoped_ptr<SpdyFrame> req(
   3247       spdy_util_.ConstructSpdyPost(
   3248           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
   3249   scoped_ptr<SpdyFrame> msg(
   3250       spdy_util_.ConstructSpdyBodyFrame(
   3251           1, msg_data.data(), msg_data_size, false));
   3252   MockWrite writes[] = {
   3253     CreateMockWrite(*req, 0),
   3254     CreateMockWrite(*msg, 2),
   3255   };
   3256 
   3257   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3258   scoped_ptr<SpdyFrame> echo(
   3259       spdy_util_.ConstructSpdyBodyFrame(
   3260           1, msg_data.data(), msg_data_size, false));
   3261   scoped_ptr<SpdyFrame> window_update(
   3262       spdy_util_.ConstructSpdyWindowUpdate(
   3263           kSessionFlowControlStreamId, msg_data_size));
   3264   MockRead reads[] = {
   3265     CreateMockRead(*resp, 1),
   3266     CreateMockRead(*echo, 3),
   3267     MockRead(ASYNC, 0, 4)  // EOF
   3268   };
   3269 
   3270   // Create SpdySession and SpdyStream and send the request.
   3271   DeterministicSocketData data(reads, arraysize(reads),
   3272                                writes, arraysize(writes));
   3273   data.set_connect_data(connect_data);
   3274   session_deps_.host_resolver->set_synchronous_mode(true);
   3275   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3276 
   3277   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   3278   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3279 
   3280   CreateDeterministicNetworkSession();
   3281 
   3282   base::WeakPtr<SpdySession> session =
   3283       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3284 
   3285   GURL url(kStreamUrl);
   3286   base::WeakPtr<SpdyStream> stream =
   3287       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3288                                 session, url, MEDIUM, BoundNetLog());
   3289   ASSERT_TRUE(stream.get() != NULL);
   3290   EXPECT_EQ(0u, stream->stream_id());
   3291 
   3292   DropReceivedDataDelegate delegate(stream, msg_data);
   3293   stream->SetDelegate(&delegate);
   3294 
   3295   scoped_ptr<SpdyHeaderBlock> headers(
   3296       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
   3297   EXPECT_EQ(ERR_IO_PENDING,
   3298             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   3299   EXPECT_TRUE(stream->HasUrlFromHeaders());
   3300 
   3301   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3302   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3303 
   3304   data.RunFor(4);
   3305 
   3306   EXPECT_TRUE(data.at_write_eof());
   3307   EXPECT_TRUE(data.at_read_eof());
   3308 
   3309   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3310   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3311 
   3312   stream->Close();
   3313   EXPECT_EQ(NULL, stream.get());
   3314 
   3315   EXPECT_EQ(OK, delegate.WaitForClose());
   3316 
   3317   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3318   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3319 }
   3320 
   3321 // Send data back and forth but close the stream before its data frame
   3322 // can be written to the socket. The send window should then increase
   3323 // to its original value, i.e. we shouldn't "leak" send window bytes.
   3324 TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
   3325   if (GetParam() < kProtoSPDY31)
   3326     return;
   3327 
   3328   const char kStreamUrl[] = "http://www.google.com/";
   3329 
   3330   const int32 msg_data_size = 100;
   3331   const std::string msg_data(msg_data_size, 'a');
   3332 
   3333   MockConnect connect_data(SYNCHRONOUS, OK);
   3334 
   3335   scoped_ptr<SpdyFrame> req(
   3336       spdy_util_.ConstructSpdyPost(
   3337           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
   3338   MockWrite writes[] = {
   3339     CreateMockWrite(*req, 0),
   3340   };
   3341 
   3342   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3343   MockRead reads[] = {
   3344     CreateMockRead(*resp, 1),
   3345     MockRead(ASYNC, 0, 2)  // EOF
   3346   };
   3347 
   3348   // Create SpdySession and SpdyStream and send the request.
   3349   DeterministicSocketData data(reads, arraysize(reads),
   3350                                writes, arraysize(writes));
   3351   data.set_connect_data(connect_data);
   3352   session_deps_.host_resolver->set_synchronous_mode(true);
   3353   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3354 
   3355   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   3356   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3357 
   3358   CreateDeterministicNetworkSession();
   3359 
   3360   base::WeakPtr<SpdySession> session =
   3361       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3362 
   3363   GURL url(kStreamUrl);
   3364   base::WeakPtr<SpdyStream> stream =
   3365       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3366                                 session, url, MEDIUM, BoundNetLog());
   3367   ASSERT_TRUE(stream.get() != NULL);
   3368   EXPECT_EQ(0u, stream->stream_id());
   3369 
   3370   test::StreamDelegateSendImmediate delegate(stream, msg_data);
   3371   stream->SetDelegate(&delegate);
   3372 
   3373   scoped_ptr<SpdyHeaderBlock> headers(
   3374       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
   3375   EXPECT_EQ(ERR_IO_PENDING,
   3376             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   3377   EXPECT_TRUE(stream->HasUrlFromHeaders());
   3378 
   3379   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3380 
   3381   data.RunFor(1);
   3382 
   3383   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3384 
   3385   data.RunFor(1);
   3386 
   3387   EXPECT_TRUE(data.at_write_eof());
   3388   EXPECT_TRUE(data.at_read_eof());
   3389 
   3390   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3391             session->session_send_window_size_);
   3392 
   3393   // Closing the stream should increase the session's send window.
   3394   stream->Close();
   3395   EXPECT_EQ(NULL, stream.get());
   3396 
   3397   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3398 
   3399   EXPECT_EQ(OK, delegate.WaitForClose());
   3400 }
   3401 
   3402 // Send data back and forth; the send and receive windows should
   3403 // change appropriately.
   3404 TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
   3405   if (GetParam() < kProtoSPDY31)
   3406     return;
   3407 
   3408   const char kStreamUrl[] = "http://www.google.com/";
   3409 
   3410   const int32 msg_data_size = 100;
   3411   const std::string msg_data(msg_data_size, 'a');
   3412 
   3413   MockConnect connect_data(SYNCHRONOUS, OK);
   3414 
   3415   scoped_ptr<SpdyFrame> req(
   3416       spdy_util_.ConstructSpdyPost(
   3417           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
   3418   scoped_ptr<SpdyFrame> msg(
   3419       spdy_util_.ConstructSpdyBodyFrame(
   3420           1, msg_data.data(), msg_data_size, false));
   3421   MockWrite writes[] = {
   3422     CreateMockWrite(*req, 0),
   3423     CreateMockWrite(*msg, 2),
   3424   };
   3425 
   3426   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3427   scoped_ptr<SpdyFrame> echo(
   3428       spdy_util_.ConstructSpdyBodyFrame(
   3429           1, msg_data.data(), msg_data_size, false));
   3430   scoped_ptr<SpdyFrame> window_update(
   3431       spdy_util_.ConstructSpdyWindowUpdate(
   3432           kSessionFlowControlStreamId, msg_data_size));
   3433   MockRead reads[] = {
   3434     CreateMockRead(*resp, 1),
   3435     CreateMockRead(*echo, 3),
   3436     CreateMockRead(*window_update, 4),
   3437     MockRead(ASYNC, 0, 5)  // EOF
   3438   };
   3439 
   3440   // Create SpdySession and SpdyStream and send the request.
   3441   DeterministicSocketData data(reads, arraysize(reads),
   3442                                writes, arraysize(writes));
   3443   data.set_connect_data(connect_data);
   3444   session_deps_.host_resolver->set_synchronous_mode(true);
   3445   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3446 
   3447   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   3448   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3449 
   3450   CreateDeterministicNetworkSession();
   3451 
   3452   base::WeakPtr<SpdySession> session =
   3453       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3454 
   3455   GURL url(kStreamUrl);
   3456   base::WeakPtr<SpdyStream> stream =
   3457       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3458                                 session, url, MEDIUM, BoundNetLog());
   3459   ASSERT_TRUE(stream.get() != NULL);
   3460   EXPECT_EQ(0u, stream->stream_id());
   3461 
   3462   test::StreamDelegateSendImmediate delegate(stream, msg_data);
   3463   stream->SetDelegate(&delegate);
   3464 
   3465   scoped_ptr<SpdyHeaderBlock> headers(
   3466       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
   3467   EXPECT_EQ(ERR_IO_PENDING,
   3468             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   3469   EXPECT_TRUE(stream->HasUrlFromHeaders());
   3470 
   3471   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3472   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3473   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3474 
   3475   data.RunFor(1);
   3476 
   3477   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3478   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3479   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3480 
   3481   data.RunFor(1);
   3482 
   3483   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3484             session->session_send_window_size_);
   3485   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3486   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3487 
   3488   data.RunFor(1);
   3489 
   3490   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3491             session->session_send_window_size_);
   3492   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3493   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3494 
   3495   data.RunFor(1);
   3496 
   3497   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3498             session->session_send_window_size_);
   3499   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3500             session->session_recv_window_size_);
   3501   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3502 
   3503   data.RunFor(1);
   3504 
   3505   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3506   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3507             session->session_recv_window_size_);
   3508   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3509 
   3510   EXPECT_TRUE(data.at_write_eof());
   3511   EXPECT_TRUE(data.at_read_eof());
   3512 
   3513   EXPECT_EQ(msg_data, delegate.TakeReceivedData());
   3514 
   3515   // Draining the delegate's read queue should increase the session's
   3516   // receive window.
   3517   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3518   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3519   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3520 
   3521   stream->Close();
   3522   EXPECT_EQ(NULL, stream.get());
   3523 
   3524   EXPECT_EQ(OK, delegate.WaitForClose());
   3525 
   3526   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3527   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3528   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3529 }
   3530 
   3531 // Given a stall function and an unstall function, runs a test to make
   3532 // sure that a stream resumes after unstall.
   3533 void SpdySessionTest::RunResumeAfterUnstallTest(
   3534     const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function,
   3535     const base::Callback<void(SpdySession*, SpdyStream*, int32)>&
   3536         unstall_function) {
   3537   const char kStreamUrl[] = "http://www.google.com/";
   3538   GURL url(kStreamUrl);
   3539 
   3540   session_deps_.host_resolver->set_synchronous_mode(true);
   3541 
   3542   scoped_ptr<SpdyFrame> req(
   3543       spdy_util_.ConstructSpdyPost(
   3544           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   3545   scoped_ptr<SpdyFrame> body(
   3546       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
   3547   MockWrite writes[] = {
   3548     CreateMockWrite(*req, 0),
   3549     CreateMockWrite(*body, 1),
   3550   };
   3551 
   3552   scoped_ptr<SpdyFrame> resp(
   3553       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3554   scoped_ptr<SpdyFrame> echo(
   3555       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
   3556   MockRead reads[] = {
   3557     CreateMockRead(*resp, 2),
   3558     MockRead(ASYNC, 0, 0, 3), // EOF
   3559   };
   3560 
   3561   DeterministicSocketData data(reads, arraysize(reads),
   3562                                writes, arraysize(writes));
   3563   MockConnect connect_data(SYNCHRONOUS, OK);
   3564   data.set_connect_data(connect_data);
   3565 
   3566   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3567 
   3568   CreateDeterministicNetworkSession();
   3569   base::WeakPtr<SpdySession> session =
   3570       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3571   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3572             session->flow_control_state());
   3573 
   3574   base::WeakPtr<SpdyStream> stream =
   3575       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3576                                 session, url, LOWEST, BoundNetLog());
   3577   ASSERT_TRUE(stream.get() != NULL);
   3578 
   3579   test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece);
   3580   stream->SetDelegate(&delegate);
   3581 
   3582   EXPECT_FALSE(stream->HasUrlFromHeaders());
   3583   EXPECT_FALSE(stream->send_stalled_by_flow_control());
   3584 
   3585   scoped_ptr<SpdyHeaderBlock> headers(
   3586       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   3587   EXPECT_EQ(ERR_IO_PENDING,
   3588             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   3589   EXPECT_TRUE(stream->HasUrlFromHeaders());
   3590   EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
   3591 
   3592   stall_function.Run(session.get(), stream.get());
   3593 
   3594   data.RunFor(1);
   3595 
   3596   EXPECT_TRUE(stream->send_stalled_by_flow_control());
   3597 
   3598   unstall_function.Run(session.get(), stream.get(), kBodyDataSize);
   3599 
   3600   EXPECT_FALSE(stream->send_stalled_by_flow_control());
   3601 
   3602   data.RunFor(3);
   3603 
   3604   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
   3605 
   3606   EXPECT_TRUE(delegate.send_headers_completed());
   3607   EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
   3608   EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version"));
   3609   EXPECT_EQ(std::string(), delegate.TakeReceivedData());
   3610   EXPECT_TRUE(data.at_write_eof());
   3611 }
   3612 
   3613 // Run the resume-after-unstall test with all possible stall and
   3614 // unstall sequences.
   3615 
   3616 TEST_P(SpdySessionTest, ResumeAfterUnstallSession) {
   3617   if (GetParam() < kProtoSPDY31)
   3618     return;
   3619 
   3620   RunResumeAfterUnstallTest(
   3621       base::Bind(&SpdySessionTest::StallSessionOnly,
   3622                  base::Unretained(this)),
   3623       base::Bind(&SpdySessionTest::UnstallSessionOnly,
   3624                  base::Unretained(this)));
   3625 }
   3626 
   3627 // Equivalent to
   3628 // SpdyStreamTest.ResumeAfterSendWindowSizeIncrease.
   3629 TEST_P(SpdySessionTest, ResumeAfterUnstallStream) {
   3630   if (GetParam() < kProtoSPDY31)
   3631     return;
   3632 
   3633   RunResumeAfterUnstallTest(
   3634       base::Bind(&SpdySessionTest::StallStreamOnly,
   3635                  base::Unretained(this)),
   3636       base::Bind(&SpdySessionTest::UnstallStreamOnly,
   3637                  base::Unretained(this)));
   3638 }
   3639 
   3640 TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallSessionStream) {
   3641   if (GetParam() < kProtoSPDY31)
   3642     return;
   3643 
   3644   RunResumeAfterUnstallTest(
   3645       base::Bind(&SpdySessionTest::StallSessionStream,
   3646                  base::Unretained(this)),
   3647       base::Bind(&SpdySessionTest::UnstallSessionStream,
   3648                  base::Unretained(this)));
   3649 }
   3650 
   3651 TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallSessionStream) {
   3652   if (GetParam() < kProtoSPDY31)
   3653     return;
   3654 
   3655   RunResumeAfterUnstallTest(
   3656       base::Bind(&SpdySessionTest::StallStreamSession,
   3657                  base::Unretained(this)),
   3658       base::Bind(&SpdySessionTest::UnstallSessionStream,
   3659                  base::Unretained(this)));
   3660 }
   3661 
   3662 TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallStreamSession) {
   3663   if (GetParam() < kProtoSPDY31)
   3664     return;
   3665 
   3666   RunResumeAfterUnstallTest(
   3667       base::Bind(&SpdySessionTest::StallStreamSession,
   3668                  base::Unretained(this)),
   3669       base::Bind(&SpdySessionTest::UnstallStreamSession,
   3670                  base::Unretained(this)));
   3671 }
   3672 
   3673 TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) {
   3674   if (GetParam() < kProtoSPDY31)
   3675     return;
   3676 
   3677   RunResumeAfterUnstallTest(
   3678       base::Bind(&SpdySessionTest::StallSessionStream,
   3679                  base::Unretained(this)),
   3680       base::Bind(&SpdySessionTest::UnstallStreamSession,
   3681                  base::Unretained(this)));
   3682 }
   3683 
   3684 // Cause a stall by reducing the flow control send window to 0. The
   3685 // streams should resume in priority order when that window is then
   3686 // increased.
   3687 TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
   3688   if (GetParam() < kProtoSPDY31)
   3689     return;
   3690 
   3691   const char kStreamUrl[] = "http://www.google.com/";
   3692   GURL url(kStreamUrl);
   3693 
   3694   session_deps_.host_resolver->set_synchronous_mode(true);
   3695 
   3696   scoped_ptr<SpdyFrame> req1(
   3697       spdy_util_.ConstructSpdyPost(
   3698           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   3699   scoped_ptr<SpdyFrame> req2(
   3700       spdy_util_.ConstructSpdyPost(
   3701           kStreamUrl, 3, kBodyDataSize, MEDIUM, NULL, 0));
   3702   scoped_ptr<SpdyFrame> body1(
   3703       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
   3704   scoped_ptr<SpdyFrame> body2(
   3705       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
   3706   MockWrite writes[] = {
   3707     CreateMockWrite(*req1, 0),
   3708     CreateMockWrite(*req2, 1),
   3709     CreateMockWrite(*body2, 2),
   3710     CreateMockWrite(*body1, 3),
   3711   };
   3712 
   3713   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3714   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3715   MockRead reads[] = {
   3716     CreateMockRead(*resp1, 4),
   3717     CreateMockRead(*resp2, 5),
   3718     MockRead(ASYNC, 0, 0, 6), // EOF
   3719   };
   3720 
   3721   DeterministicSocketData data(reads, arraysize(reads),
   3722                                writes, arraysize(writes));
   3723   MockConnect connect_data(SYNCHRONOUS, OK);
   3724   data.set_connect_data(connect_data);
   3725 
   3726   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3727 
   3728   CreateDeterministicNetworkSession();
   3729   base::WeakPtr<SpdySession> session =
   3730       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3731   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3732             session->flow_control_state());
   3733 
   3734   base::WeakPtr<SpdyStream> stream1 =
   3735       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3736                                 session, url, LOWEST, BoundNetLog());
   3737   ASSERT_TRUE(stream1.get() != NULL);
   3738 
   3739   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
   3740   stream1->SetDelegate(&delegate1);
   3741 
   3742   EXPECT_FALSE(stream1->HasUrlFromHeaders());
   3743 
   3744   base::WeakPtr<SpdyStream> stream2 =
   3745       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3746                                 session, url, MEDIUM, BoundNetLog());
   3747   ASSERT_TRUE(stream2.get() != NULL);
   3748 
   3749   test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
   3750   stream2->SetDelegate(&delegate2);
   3751 
   3752   EXPECT_FALSE(stream2->HasUrlFromHeaders());
   3753 
   3754   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   3755   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   3756 
   3757   StallSessionSend(session.get());
   3758 
   3759   scoped_ptr<SpdyHeaderBlock> headers1(
   3760       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   3761   EXPECT_EQ(ERR_IO_PENDING,
   3762             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
   3763   EXPECT_TRUE(stream1->HasUrlFromHeaders());
   3764   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
   3765 
   3766   data.RunFor(1);
   3767   EXPECT_EQ(1u, stream1->stream_id());
   3768   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   3769 
   3770   scoped_ptr<SpdyHeaderBlock> headers2(
   3771       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   3772   EXPECT_EQ(ERR_IO_PENDING,
   3773             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
   3774   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   3775   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
   3776 
   3777   data.RunFor(1);
   3778   EXPECT_EQ(3u, stream2->stream_id());
   3779   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
   3780 
   3781   // This should unstall only stream2.
   3782   UnstallSessionSend(session.get(), kBodyDataSize);
   3783 
   3784   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   3785   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   3786 
   3787   data.RunFor(1);
   3788 
   3789   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   3790   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   3791 
   3792   // This should then unstall stream1.
   3793   UnstallSessionSend(session.get(), kBodyDataSize);
   3794 
   3795   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   3796   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   3797 
   3798   data.RunFor(4);
   3799 
   3800   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
   3801   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
   3802 
   3803   EXPECT_TRUE(delegate1.send_headers_completed());
   3804   EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
   3805   EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
   3806   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
   3807 
   3808   EXPECT_TRUE(delegate2.send_headers_completed());
   3809   EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
   3810   EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
   3811   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
   3812 
   3813   EXPECT_TRUE(data.at_write_eof());
   3814 }
   3815 
   3816 // Delegate that closes a given stream after sending its body.
   3817 class StreamClosingDelegate : public test::StreamDelegateWithBody {
   3818  public:
   3819   StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
   3820                         base::StringPiece data)
   3821       : StreamDelegateWithBody(stream, data) {}
   3822 
   3823   virtual ~StreamClosingDelegate() {}
   3824 
   3825   void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
   3826     stream_to_close_ = stream_to_close;
   3827   }
   3828 
   3829   virtual void OnDataSent() OVERRIDE {
   3830     test::StreamDelegateWithBody::OnDataSent();
   3831     if (stream_to_close_.get()) {
   3832       stream_to_close_->Close();
   3833       EXPECT_EQ(NULL, stream_to_close_.get());
   3834     }
   3835   }
   3836 
   3837  private:
   3838   base::WeakPtr<SpdyStream> stream_to_close_;
   3839 };
   3840 
   3841 // Cause a stall by reducing the flow control send window to
   3842 // 0. Unstalling the session should properly handle deleted streams.
   3843 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
   3844   if (GetParam() < kProtoSPDY31)
   3845     return;
   3846 
   3847   const char kStreamUrl[] = "http://www.google.com/";
   3848   GURL url(kStreamUrl);
   3849 
   3850   session_deps_.host_resolver->set_synchronous_mode(true);
   3851 
   3852   scoped_ptr<SpdyFrame> req1(
   3853       spdy_util_.ConstructSpdyPost(
   3854           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   3855   scoped_ptr<SpdyFrame> req2(
   3856       spdy_util_.ConstructSpdyPost(
   3857           kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
   3858   scoped_ptr<SpdyFrame> req3(
   3859       spdy_util_.ConstructSpdyPost(
   3860           kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0));
   3861   scoped_ptr<SpdyFrame> body2(
   3862       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
   3863   MockWrite writes[] = {
   3864     CreateMockWrite(*req1, 0),
   3865     CreateMockWrite(*req2, 1),
   3866     CreateMockWrite(*req3, 2),
   3867     CreateMockWrite(*body2, 3),
   3868   };
   3869 
   3870   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3871   MockRead reads[] = {
   3872     CreateMockRead(*resp2, 4),
   3873     MockRead(ASYNC, 0, 0, 5), // EOF
   3874   };
   3875 
   3876   DeterministicSocketData data(reads, arraysize(reads),
   3877                                writes, arraysize(writes));
   3878   MockConnect connect_data(SYNCHRONOUS, OK);
   3879   data.set_connect_data(connect_data);
   3880 
   3881   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3882 
   3883   CreateDeterministicNetworkSession();
   3884   base::WeakPtr<SpdySession> session =
   3885       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3886   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3887             session->flow_control_state());
   3888 
   3889   base::WeakPtr<SpdyStream> stream1 =
   3890       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3891                                 session, url, LOWEST, BoundNetLog());
   3892   ASSERT_TRUE(stream1.get() != NULL);
   3893 
   3894   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
   3895   stream1->SetDelegate(&delegate1);
   3896 
   3897   EXPECT_FALSE(stream1->HasUrlFromHeaders());
   3898 
   3899   base::WeakPtr<SpdyStream> stream2 =
   3900       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3901                                 session, url, LOWEST, BoundNetLog());
   3902   ASSERT_TRUE(stream2.get() != NULL);
   3903 
   3904   StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
   3905   stream2->SetDelegate(&delegate2);
   3906 
   3907   EXPECT_FALSE(stream2->HasUrlFromHeaders());
   3908 
   3909   base::WeakPtr<SpdyStream> stream3 =
   3910       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3911                                 session, url, LOWEST, BoundNetLog());
   3912   ASSERT_TRUE(stream3.get() != NULL);
   3913 
   3914   test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
   3915   stream3->SetDelegate(&delegate3);
   3916 
   3917   EXPECT_FALSE(stream3->HasUrlFromHeaders());
   3918 
   3919   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   3920   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   3921   EXPECT_FALSE(stream3->send_stalled_by_flow_control());
   3922 
   3923   StallSessionSend(session.get());
   3924 
   3925   scoped_ptr<SpdyHeaderBlock> headers1(
   3926       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   3927   EXPECT_EQ(ERR_IO_PENDING,
   3928             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
   3929   EXPECT_TRUE(stream1->HasUrlFromHeaders());
   3930   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
   3931 
   3932   data.RunFor(1);
   3933   EXPECT_EQ(1u, stream1->stream_id());
   3934   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   3935 
   3936   scoped_ptr<SpdyHeaderBlock> headers2(
   3937       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   3938   EXPECT_EQ(ERR_IO_PENDING,
   3939             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
   3940   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   3941   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
   3942 
   3943   data.RunFor(1);
   3944   EXPECT_EQ(3u, stream2->stream_id());
   3945   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
   3946 
   3947   scoped_ptr<SpdyHeaderBlock> headers3(
   3948       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   3949   EXPECT_EQ(ERR_IO_PENDING,
   3950             stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
   3951   EXPECT_TRUE(stream3->HasUrlFromHeaders());
   3952   EXPECT_EQ(kStreamUrl, stream3->GetUrlFromHeaders().spec());
   3953 
   3954   data.RunFor(1);
   3955   EXPECT_EQ(5u, stream3->stream_id());
   3956   EXPECT_TRUE(stream3->send_stalled_by_flow_control());
   3957 
   3958   SpdyStreamId stream_id1 = stream1->stream_id();
   3959   SpdyStreamId stream_id2 = stream2->stream_id();
   3960   SpdyStreamId stream_id3 = stream3->stream_id();
   3961 
   3962   // Close stream1 preemptively.
   3963   session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
   3964   EXPECT_EQ(NULL, stream1.get());
   3965 
   3966   EXPECT_FALSE(session->IsStreamActive(stream_id1));
   3967   EXPECT_TRUE(session->IsStreamActive(stream_id2));
   3968   EXPECT_TRUE(session->IsStreamActive(stream_id3));
   3969 
   3970   // Unstall stream2, which should then close stream3.
   3971   delegate2.set_stream_to_close(stream3);
   3972   UnstallSessionSend(session.get(), kBodyDataSize);
   3973 
   3974   data.RunFor(1);
   3975   EXPECT_EQ(NULL, stream3.get());
   3976 
   3977   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   3978   EXPECT_FALSE(session->IsStreamActive(stream_id1));
   3979   EXPECT_TRUE(session->IsStreamActive(stream_id2));
   3980   EXPECT_FALSE(session->IsStreamActive(stream_id3));
   3981 
   3982   data.RunFor(2);
   3983   EXPECT_EQ(NULL, stream2.get());
   3984 
   3985   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
   3986   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
   3987   EXPECT_EQ(OK, delegate3.WaitForClose());
   3988 
   3989   EXPECT_TRUE(delegate1.send_headers_completed());
   3990   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
   3991 
   3992   EXPECT_TRUE(delegate2.send_headers_completed());
   3993   EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
   3994   EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
   3995   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
   3996 
   3997   EXPECT_TRUE(delegate3.send_headers_completed());
   3998   EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
   3999 
   4000   EXPECT_TRUE(data.at_write_eof());
   4001 }
   4002 
   4003 // Cause a stall by reducing the flow control send window to
   4004 // 0. Unstalling the session should properly handle the session itself
   4005 // being closed.
   4006 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
   4007   if (GetParam() < kProtoSPDY31)
   4008     return;
   4009 
   4010   const char kStreamUrl[] = "http://www.google.com/";
   4011   GURL url(kStreamUrl);
   4012 
   4013   session_deps_.host_resolver->set_synchronous_mode(true);
   4014 
   4015   scoped_ptr<SpdyFrame> req1(
   4016       spdy_util_.ConstructSpdyPost(
   4017           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   4018   scoped_ptr<SpdyFrame> req2(
   4019       spdy_util_.ConstructSpdyPost(
   4020           kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
   4021   scoped_ptr<SpdyFrame> body1(
   4022       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
   4023   MockWrite writes[] = {
   4024     CreateMockWrite(*req1, 0),
   4025     CreateMockWrite(*req2, 1),
   4026   };
   4027 
   4028   MockRead reads[] = {
   4029     MockRead(ASYNC, 0, 0, 2), // EOF
   4030   };
   4031 
   4032   DeterministicSocketData data(reads, arraysize(reads),
   4033                                writes, arraysize(writes));
   4034   MockConnect connect_data(SYNCHRONOUS, OK);
   4035   data.set_connect_data(connect_data);
   4036 
   4037   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4038 
   4039   CreateDeterministicNetworkSession();
   4040   base::WeakPtr<SpdySession> session =
   4041       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4042   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   4043             session->flow_control_state());
   4044 
   4045   base::WeakPtr<SpdyStream> stream1 =
   4046       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4047                                 session, url, LOWEST, BoundNetLog());
   4048   ASSERT_TRUE(stream1.get() != NULL);
   4049 
   4050   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
   4051   stream1->SetDelegate(&delegate1);
   4052 
   4053   EXPECT_FALSE(stream1->HasUrlFromHeaders());
   4054 
   4055   base::WeakPtr<SpdyStream> stream2 =
   4056       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4057                                 session, url, LOWEST, BoundNetLog());
   4058   ASSERT_TRUE(stream2.get() != NULL);
   4059 
   4060   test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
   4061   stream2->SetDelegate(&delegate2);
   4062 
   4063   EXPECT_FALSE(stream2->HasUrlFromHeaders());
   4064 
   4065   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   4066   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4067 
   4068   StallSessionSend(session.get());
   4069 
   4070   scoped_ptr<SpdyHeaderBlock> headers1(
   4071       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4072   EXPECT_EQ(ERR_IO_PENDING,
   4073             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
   4074   EXPECT_TRUE(stream1->HasUrlFromHeaders());
   4075   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
   4076 
   4077   data.RunFor(1);
   4078   EXPECT_EQ(1u, stream1->stream_id());
   4079   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   4080 
   4081   scoped_ptr<SpdyHeaderBlock> headers2(
   4082       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4083   EXPECT_EQ(ERR_IO_PENDING,
   4084             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
   4085   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   4086   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
   4087 
   4088   data.RunFor(1);
   4089   EXPECT_EQ(3u, stream2->stream_id());
   4090   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
   4091 
   4092   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   4093 
   4094   // Unstall stream1.
   4095   UnstallSessionSend(session.get(), kBodyDataSize);
   4096 
   4097   // Close the session (since we can't do it from within the delegate
   4098   // method, since it's in the stream's loop).
   4099   session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
   4100   EXPECT_TRUE(session == NULL);
   4101 
   4102   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
   4103 
   4104   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
   4105   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
   4106 
   4107   EXPECT_TRUE(delegate1.send_headers_completed());
   4108   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
   4109 
   4110   EXPECT_TRUE(delegate2.send_headers_completed());
   4111   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
   4112 
   4113   EXPECT_TRUE(data.at_write_eof());
   4114 }
   4115 
   4116 }  // namespace net
   4117