Home | History | Annotate | Download | only in http
      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/http/http_pipelined_host_impl.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "net/http/http_pipelined_connection.h"
      9 #include "net/http/http_pipelined_host_test_util.h"
     10 #include "net/proxy/proxy_info.h"
     11 #include "net/ssl/ssl_config_service.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using testing::_;
     16 using testing::NiceMock;
     17 using testing::Ref;
     18 using testing::Return;
     19 using testing::ReturnNull;
     20 
     21 namespace net {
     22 
     23 namespace {
     24 
     25 ClientSocketHandle* kDummyConnection =
     26     reinterpret_cast<ClientSocketHandle*>(84);
     27 HttpPipelinedStream* kDummyStream =
     28     reinterpret_cast<HttpPipelinedStream*>(42);
     29 
     30 class HttpPipelinedHostImplTest : public testing::Test {
     31  public:
     32   HttpPipelinedHostImplTest()
     33       : key_(HostPortPair("host", 123)),
     34         factory_(new MockPipelineFactory),  // Owned by host_.
     35         host_(new HttpPipelinedHostImpl(&delegate_, key_, factory_,
     36                                         PIPELINE_CAPABLE)) {
     37   }
     38 
     39   void SetCapability(HttpPipelinedHostCapability capability) {
     40     factory_ = new MockPipelineFactory;
     41     host_.reset(new HttpPipelinedHostImpl(
     42         &delegate_, key_, factory_, capability));
     43   }
     44 
     45   MockPipeline* AddTestPipeline(int depth, bool usable, bool active) {
     46     MockPipeline* pipeline = new MockPipeline(depth, usable, active);
     47     EXPECT_CALL(*factory_, CreateNewPipeline(kDummyConnection, host_.get(),
     48                                              MatchesOrigin(key_.origin()),
     49                                              Ref(ssl_config_), Ref(proxy_info_),
     50                                              Ref(net_log_), true,
     51                                              kProtoSPDY3))
     52         .Times(1)
     53         .WillOnce(Return(pipeline));
     54     EXPECT_CALL(*pipeline, CreateNewStream())
     55         .Times(1)
     56         .WillOnce(Return(kDummyStream));
     57     EXPECT_EQ(kDummyStream, host_->CreateStreamOnNewPipeline(
     58         kDummyConnection, ssl_config_, proxy_info_, net_log_, true,
     59         kProtoSPDY3));
     60     return pipeline;
     61   }
     62 
     63   void ClearTestPipeline(MockPipeline* pipeline) {
     64     pipeline->SetState(0, true, true);
     65     host_->OnPipelineHasCapacity(pipeline);
     66   }
     67 
     68   NiceMock<MockHostDelegate> delegate_;
     69   HttpPipelinedHost::Key key_;
     70   MockPipelineFactory* factory_;
     71   scoped_ptr<HttpPipelinedHostImpl> host_;
     72 
     73   SSLConfig ssl_config_;
     74   ProxyInfo proxy_info_;
     75   BoundNetLog net_log_;
     76 };
     77 
     78 TEST_F(HttpPipelinedHostImplTest, Delegate) {
     79   EXPECT_TRUE(key_.origin().Equals(host_->GetKey().origin()));
     80 }
     81 
     82 TEST_F(HttpPipelinedHostImplTest, OnUnusablePipelineHasCapacity) {
     83   MockPipeline* pipeline = AddTestPipeline(0, false, true);
     84 
     85   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
     86       .Times(0);
     87   EXPECT_CALL(delegate_, OnHostIdle(host_.get()))
     88       .Times(1);
     89   host_->OnPipelineHasCapacity(pipeline);
     90 }
     91 
     92 TEST_F(HttpPipelinedHostImplTest, OnUsablePipelineHasCapacity) {
     93   MockPipeline* pipeline = AddTestPipeline(1, true, true);
     94 
     95   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
     96       .Times(1);
     97   EXPECT_CALL(delegate_, OnHostIdle(host_.get()))
     98       .Times(0);
     99 
    100   host_->OnPipelineHasCapacity(pipeline);
    101 
    102   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    103       .Times(1);
    104   EXPECT_CALL(delegate_, OnHostIdle(host_.get()))
    105       .Times(1);
    106   ClearTestPipeline(pipeline);
    107 }
    108 
    109 TEST_F(HttpPipelinedHostImplTest, IgnoresUnusablePipeline) {
    110   MockPipeline* pipeline = AddTestPipeline(1, false, true);
    111 
    112   EXPECT_FALSE(host_->IsExistingPipelineAvailable());
    113   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    114 
    115   ClearTestPipeline(pipeline);
    116 }
    117 
    118 TEST_F(HttpPipelinedHostImplTest, IgnoresInactivePipeline) {
    119   MockPipeline* pipeline = AddTestPipeline(1, true, false);
    120 
    121   EXPECT_FALSE(host_->IsExistingPipelineAvailable());
    122   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    123 
    124   ClearTestPipeline(pipeline);
    125 }
    126 
    127 TEST_F(HttpPipelinedHostImplTest, IgnoresFullPipeline) {
    128   MockPipeline* pipeline = AddTestPipeline(
    129       HttpPipelinedHostImpl::max_pipeline_depth(), true, true);
    130 
    131   EXPECT_FALSE(host_->IsExistingPipelineAvailable());
    132   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    133 
    134   ClearTestPipeline(pipeline);
    135 }
    136 
    137 TEST_F(HttpPipelinedHostImplTest, PicksLeastLoadedPipeline) {
    138   MockPipeline* full_pipeline = AddTestPipeline(
    139       HttpPipelinedHostImpl::max_pipeline_depth(), true, true);
    140   MockPipeline* usable_pipeline = AddTestPipeline(
    141       HttpPipelinedHostImpl::max_pipeline_depth() - 1, true, true);
    142   MockPipeline* empty_pipeline = AddTestPipeline(0, true, true);
    143 
    144   EXPECT_TRUE(host_->IsExistingPipelineAvailable());
    145   EXPECT_CALL(*empty_pipeline, CreateNewStream())
    146       .Times(1)
    147       .WillOnce(ReturnNull());
    148   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    149 
    150   ClearTestPipeline(full_pipeline);
    151   ClearTestPipeline(usable_pipeline);
    152   ClearTestPipeline(empty_pipeline);
    153 }
    154 
    155 TEST_F(HttpPipelinedHostImplTest, OpensUpOnPipelineSuccess) {
    156   SetCapability(PIPELINE_UNKNOWN);
    157   MockPipeline* pipeline = AddTestPipeline(1, true, true);
    158 
    159   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    160   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    161       .Times(1);
    162   host_->OnPipelineFeedback(pipeline, HttpPipelinedConnection::OK);
    163 
    164   EXPECT_CALL(*pipeline, CreateNewStream())
    165       .Times(1)
    166       .WillOnce(Return(kDummyStream));
    167   EXPECT_EQ(kDummyStream, host_->CreateStreamOnExistingPipeline());
    168 
    169   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    170       .Times(1);
    171   ClearTestPipeline(pipeline);
    172 }
    173 
    174 TEST_F(HttpPipelinedHostImplTest, OpensAllPipelinesOnPipelineSuccess) {
    175   SetCapability(PIPELINE_UNKNOWN);
    176   MockPipeline* pipeline1 = AddTestPipeline(1, false, true);
    177   MockPipeline* pipeline2 = AddTestPipeline(1, true, true);
    178 
    179   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    180   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    181       .Times(1);
    182   host_->OnPipelineFeedback(pipeline1, HttpPipelinedConnection::OK);
    183 
    184   EXPECT_CALL(*pipeline2, CreateNewStream())
    185       .Times(1)
    186       .WillOnce(Return(kDummyStream));
    187   EXPECT_EQ(kDummyStream, host_->CreateStreamOnExistingPipeline());
    188 
    189   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    190       .Times(2);
    191   ClearTestPipeline(pipeline1);
    192   ClearTestPipeline(pipeline2);
    193 }
    194 
    195 TEST_F(HttpPipelinedHostImplTest, ShutsDownOnOldVersion) {
    196   SetCapability(PIPELINE_UNKNOWN);
    197   MockPipeline* pipeline = AddTestPipeline(1, true, true);
    198 
    199   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    200   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    201       .Times(0);
    202   EXPECT_CALL(delegate_,
    203               OnHostDeterminedCapability(host_.get(), PIPELINE_INCAPABLE))
    204       .Times(1);
    205   host_->OnPipelineFeedback(pipeline,
    206                             HttpPipelinedConnection::OLD_HTTP_VERSION);
    207 
    208   ClearTestPipeline(pipeline);
    209   EXPECT_EQ(NULL, host_->CreateStreamOnNewPipeline(
    210       kDummyConnection, ssl_config_, proxy_info_, net_log_, true,
    211       kProtoSPDY3));
    212 }
    213 
    214 TEST_F(HttpPipelinedHostImplTest, ShutsDownOnAuthenticationRequired) {
    215   SetCapability(PIPELINE_UNKNOWN);
    216   MockPipeline* pipeline = AddTestPipeline(1, true, true);
    217 
    218   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    219   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    220       .Times(0);
    221   EXPECT_CALL(delegate_,
    222               OnHostDeterminedCapability(host_.get(), PIPELINE_INCAPABLE))
    223       .Times(1);
    224   host_->OnPipelineFeedback(pipeline,
    225                             HttpPipelinedConnection::AUTHENTICATION_REQUIRED);
    226 
    227   ClearTestPipeline(pipeline);
    228   EXPECT_EQ(NULL, host_->CreateStreamOnNewPipeline(
    229       kDummyConnection, ssl_config_, proxy_info_, net_log_, true,
    230       kProtoSPDY3));
    231 }
    232 
    233 TEST_F(HttpPipelinedHostImplTest, ConnectionCloseHasNoEffect) {
    234   SetCapability(PIPELINE_UNKNOWN);
    235   MockPipeline* pipeline = AddTestPipeline(1, true, true);
    236 
    237   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    238       .Times(0);
    239   EXPECT_CALL(delegate_, OnHostDeterminedCapability(host_.get(), _))
    240       .Times(0);
    241   host_->OnPipelineFeedback(pipeline,
    242                             HttpPipelinedConnection::MUST_CLOSE_CONNECTION);
    243   EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
    244 
    245   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    246       .Times(1);
    247   ClearTestPipeline(pipeline);
    248 }
    249 
    250 TEST_F(HttpPipelinedHostImplTest, SuccessesLeadToCapable) {
    251   SetCapability(PIPELINE_UNKNOWN);
    252   MockPipeline* pipeline = AddTestPipeline(1, true, true);
    253 
    254   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    255       .Times(1);
    256   EXPECT_CALL(delegate_,
    257               OnHostDeterminedCapability(host_.get(), PIPELINE_CAPABLE))
    258       .Times(1);
    259   host_->OnPipelineFeedback(pipeline, HttpPipelinedConnection::OK);
    260 
    261   pipeline->SetState(3, true, true);
    262   host_->OnPipelineFeedback(pipeline, HttpPipelinedConnection::OK);
    263   host_->OnPipelineFeedback(pipeline, HttpPipelinedConnection::OK);
    264 
    265   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    266       .Times(1);
    267   ClearTestPipeline(pipeline);
    268 }
    269 
    270 TEST_F(HttpPipelinedHostImplTest, IgnoresSocketErrorOnFirstRequest) {
    271   SetCapability(PIPELINE_UNKNOWN);
    272   MockPipeline* pipeline = AddTestPipeline(1, true, true);
    273 
    274   EXPECT_CALL(delegate_, OnHostDeterminedCapability(host_.get(), _))
    275       .Times(0);
    276   host_->OnPipelineFeedback(pipeline,
    277                             HttpPipelinedConnection::PIPELINE_SOCKET_ERROR);
    278 
    279   EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
    280       .Times(1);
    281   host_->OnPipelineFeedback(pipeline,
    282                             HttpPipelinedConnection::OK);
    283 
    284   EXPECT_CALL(delegate_,
    285               OnHostDeterminedCapability(host_.get(), PIPELINE_INCAPABLE))
    286       .Times(1);
    287   host_->OnPipelineFeedback(pipeline,
    288                             HttpPipelinedConnection::PIPELINE_SOCKET_ERROR);
    289 
    290   ClearTestPipeline(pipeline);
    291 }
    292 
    293 TEST_F(HttpPipelinedHostImplTest, HeedsSocketErrorOnFirstRequestWithPipeline) {
    294   SetCapability(PIPELINE_UNKNOWN);
    295   MockPipeline* pipeline = AddTestPipeline(2, true, true);
    296 
    297   EXPECT_CALL(delegate_,
    298               OnHostDeterminedCapability(host_.get(), PIPELINE_INCAPABLE))
    299       .Times(1);
    300   host_->OnPipelineFeedback(pipeline,
    301                             HttpPipelinedConnection::PIPELINE_SOCKET_ERROR);
    302 
    303   ClearTestPipeline(pipeline);
    304 }
    305 
    306 }  // anonymous namespace
    307 
    308 }  // namespace net
    309