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