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