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.
5 #include "net/http/http_pipelined_host_impl.h"
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"
16 using testing::NiceMock
;
18 using testing::Return
;
19 using testing::ReturnNull
;
25 ClientSocketHandle
* kDummyConnection
=
26 reinterpret_cast<ClientSocketHandle
*>(84);
27 HttpPipelinedStream
* kDummyStream
=
28 reinterpret_cast<HttpPipelinedStream
*>(42);
30 class HttpPipelinedHostImplTest
: public testing::Test
{
32 HttpPipelinedHostImplTest()
33 : key_(HostPortPair("host", 123)),
34 factory_(new MockPipelineFactory
), // Owned by host_.
35 host_(new HttpPipelinedHostImpl(&delegate_
, key_
, factory_
,
39 void SetCapability(HttpPipelinedHostCapability capability
) {
40 factory_
= new MockPipelineFactory
;
41 host_
.reset(new HttpPipelinedHostImpl(
42 &delegate_
, key_
, factory_
, capability
));
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_
),
53 .WillOnce(Return(pipeline
));
54 EXPECT_CALL(*pipeline
, CreateNewStream())
56 .WillOnce(Return(kDummyStream
));
57 EXPECT_EQ(kDummyStream
, host_
->CreateStreamOnNewPipeline(
58 kDummyConnection
, ssl_config_
, proxy_info_
, net_log_
, true,
63 void ClearTestPipeline(MockPipeline
* pipeline
) {
64 pipeline
->SetState(0, true, true);
65 host_
->OnPipelineHasCapacity(pipeline
);
68 NiceMock
<MockHostDelegate
> delegate_
;
69 HttpPipelinedHost::Key key_
;
70 MockPipelineFactory
* factory_
;
71 scoped_ptr
<HttpPipelinedHostImpl
> host_
;
73 SSLConfig ssl_config_
;
74 ProxyInfo proxy_info_
;
78 TEST_F(HttpPipelinedHostImplTest
, Delegate
) {
79 EXPECT_TRUE(key_
.origin().Equals(host_
->GetKey().origin()));
82 TEST_F(HttpPipelinedHostImplTest
, OnUnusablePipelineHasCapacity
) {
83 MockPipeline
* pipeline
= AddTestPipeline(0, false, true);
85 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
87 EXPECT_CALL(delegate_
, OnHostIdle(host_
.get()))
89 host_
->OnPipelineHasCapacity(pipeline
);
92 TEST_F(HttpPipelinedHostImplTest
, OnUsablePipelineHasCapacity
) {
93 MockPipeline
* pipeline
= AddTestPipeline(1, true, true);
95 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
97 EXPECT_CALL(delegate_
, OnHostIdle(host_
.get()))
100 host_
->OnPipelineHasCapacity(pipeline
);
102 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
104 EXPECT_CALL(delegate_
, OnHostIdle(host_
.get()))
106 ClearTestPipeline(pipeline
);
109 TEST_F(HttpPipelinedHostImplTest
, IgnoresUnusablePipeline
) {
110 MockPipeline
* pipeline
= AddTestPipeline(1, false, true);
112 EXPECT_FALSE(host_
->IsExistingPipelineAvailable());
113 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
115 ClearTestPipeline(pipeline
);
118 TEST_F(HttpPipelinedHostImplTest
, IgnoresInactivePipeline
) {
119 MockPipeline
* pipeline
= AddTestPipeline(1, true, false);
121 EXPECT_FALSE(host_
->IsExistingPipelineAvailable());
122 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
124 ClearTestPipeline(pipeline
);
127 TEST_F(HttpPipelinedHostImplTest
, IgnoresFullPipeline
) {
128 MockPipeline
* pipeline
= AddTestPipeline(
129 HttpPipelinedHostImpl::max_pipeline_depth(), true, true);
131 EXPECT_FALSE(host_
->IsExistingPipelineAvailable());
132 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
134 ClearTestPipeline(pipeline
);
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);
144 EXPECT_TRUE(host_
->IsExistingPipelineAvailable());
145 EXPECT_CALL(*empty_pipeline
, CreateNewStream())
147 .WillOnce(ReturnNull());
148 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
150 ClearTestPipeline(full_pipeline
);
151 ClearTestPipeline(usable_pipeline
);
152 ClearTestPipeline(empty_pipeline
);
155 TEST_F(HttpPipelinedHostImplTest
, OpensUpOnPipelineSuccess
) {
156 SetCapability(PIPELINE_UNKNOWN
);
157 MockPipeline
* pipeline
= AddTestPipeline(1, true, true);
159 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
160 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
162 host_
->OnPipelineFeedback(pipeline
, HttpPipelinedConnection::OK
);
164 EXPECT_CALL(*pipeline
, CreateNewStream())
166 .WillOnce(Return(kDummyStream
));
167 EXPECT_EQ(kDummyStream
, host_
->CreateStreamOnExistingPipeline());
169 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
171 ClearTestPipeline(pipeline
);
174 TEST_F(HttpPipelinedHostImplTest
, OpensAllPipelinesOnPipelineSuccess
) {
175 SetCapability(PIPELINE_UNKNOWN
);
176 MockPipeline
* pipeline1
= AddTestPipeline(1, false, true);
177 MockPipeline
* pipeline2
= AddTestPipeline(1, true, true);
179 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
180 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
182 host_
->OnPipelineFeedback(pipeline1
, HttpPipelinedConnection::OK
);
184 EXPECT_CALL(*pipeline2
, CreateNewStream())
186 .WillOnce(Return(kDummyStream
));
187 EXPECT_EQ(kDummyStream
, host_
->CreateStreamOnExistingPipeline());
189 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
191 ClearTestPipeline(pipeline1
);
192 ClearTestPipeline(pipeline2
);
195 TEST_F(HttpPipelinedHostImplTest
, ShutsDownOnOldVersion
) {
196 SetCapability(PIPELINE_UNKNOWN
);
197 MockPipeline
* pipeline
= AddTestPipeline(1, true, true);
199 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
200 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
202 EXPECT_CALL(delegate_
,
203 OnHostDeterminedCapability(host_
.get(), PIPELINE_INCAPABLE
))
205 host_
->OnPipelineFeedback(pipeline
,
206 HttpPipelinedConnection::OLD_HTTP_VERSION
);
208 ClearTestPipeline(pipeline
);
209 EXPECT_EQ(NULL
, host_
->CreateStreamOnNewPipeline(
210 kDummyConnection
, ssl_config_
, proxy_info_
, net_log_
, true,
214 TEST_F(HttpPipelinedHostImplTest
, ShutsDownOnAuthenticationRequired
) {
215 SetCapability(PIPELINE_UNKNOWN
);
216 MockPipeline
* pipeline
= AddTestPipeline(1, true, true);
218 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
219 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
221 EXPECT_CALL(delegate_
,
222 OnHostDeterminedCapability(host_
.get(), PIPELINE_INCAPABLE
))
224 host_
->OnPipelineFeedback(pipeline
,
225 HttpPipelinedConnection::AUTHENTICATION_REQUIRED
);
227 ClearTestPipeline(pipeline
);
228 EXPECT_EQ(NULL
, host_
->CreateStreamOnNewPipeline(
229 kDummyConnection
, ssl_config_
, proxy_info_
, net_log_
, true,
233 TEST_F(HttpPipelinedHostImplTest
, ConnectionCloseHasNoEffect
) {
234 SetCapability(PIPELINE_UNKNOWN
);
235 MockPipeline
* pipeline
= AddTestPipeline(1, true, true);
237 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
239 EXPECT_CALL(delegate_
, OnHostDeterminedCapability(host_
.get(), _
))
241 host_
->OnPipelineFeedback(pipeline
,
242 HttpPipelinedConnection::MUST_CLOSE_CONNECTION
);
243 EXPECT_EQ(NULL
, host_
->CreateStreamOnExistingPipeline());
245 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
247 ClearTestPipeline(pipeline
);
250 TEST_F(HttpPipelinedHostImplTest
, SuccessesLeadToCapable
) {
251 SetCapability(PIPELINE_UNKNOWN
);
252 MockPipeline
* pipeline
= AddTestPipeline(1, true, true);
254 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
256 EXPECT_CALL(delegate_
,
257 OnHostDeterminedCapability(host_
.get(), PIPELINE_CAPABLE
))
259 host_
->OnPipelineFeedback(pipeline
, HttpPipelinedConnection::OK
);
261 pipeline
->SetState(3, true, true);
262 host_
->OnPipelineFeedback(pipeline
, HttpPipelinedConnection::OK
);
263 host_
->OnPipelineFeedback(pipeline
, HttpPipelinedConnection::OK
);
265 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
267 ClearTestPipeline(pipeline
);
270 TEST_F(HttpPipelinedHostImplTest
, IgnoresSocketErrorOnFirstRequest
) {
271 SetCapability(PIPELINE_UNKNOWN
);
272 MockPipeline
* pipeline
= AddTestPipeline(1, true, true);
274 EXPECT_CALL(delegate_
, OnHostDeterminedCapability(host_
.get(), _
))
276 host_
->OnPipelineFeedback(pipeline
,
277 HttpPipelinedConnection::PIPELINE_SOCKET_ERROR
);
279 EXPECT_CALL(delegate_
, OnHostHasAdditionalCapacity(host_
.get()))
281 host_
->OnPipelineFeedback(pipeline
,
282 HttpPipelinedConnection::OK
);
284 EXPECT_CALL(delegate_
,
285 OnHostDeterminedCapability(host_
.get(), PIPELINE_INCAPABLE
))
287 host_
->OnPipelineFeedback(pipeline
,
288 HttpPipelinedConnection::PIPELINE_SOCKET_ERROR
);
290 ClearTestPipeline(pipeline
);
293 TEST_F(HttpPipelinedHostImplTest
, HeedsSocketErrorOnFirstRequestWithPipeline
) {
294 SetCapability(PIPELINE_UNKNOWN
);
295 MockPipeline
* pipeline
= AddTestPipeline(2, true, true);
297 EXPECT_CALL(delegate_
,
298 OnHostDeterminedCapability(host_
.get(), PIPELINE_INCAPABLE
))
300 host_
->OnPipelineFeedback(pipeline
,
301 HttpPipelinedConnection::PIPELINE_SOCKET_ERROR
);
303 ClearTestPipeline(pipeline
);
306 } // anonymous namespace