OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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.h" | |
6 | |
7 #include "net/base/ssl_config_service.h" | |
8 #include "net/http/http_pipelined_connection.h" | |
9 #include "net/proxy/proxy_info.h" | |
10 #include "testing/gmock/include/gmock/gmock.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 using testing::_; | |
14 using testing::NiceMock; | |
15 using testing::Ref; | |
16 using testing::Return; | |
17 using testing::ReturnNull; | |
18 | |
19 static const int kMaxCapacity = 3; | |
20 | |
21 namespace net { | |
22 | |
23 static ClientSocketHandle* kDummyConnection = | |
24 reinterpret_cast<ClientSocketHandle*>(84); | |
25 static HttpPipelinedStream* kDummyStream = | |
26 reinterpret_cast<HttpPipelinedStream*>(42); | |
27 | |
28 class MockHostDelegate : public HttpPipelinedHost::Delegate { | |
29 public: | |
30 MOCK_METHOD1(OnHostIdle, void(HttpPipelinedHost* host)); | |
31 MOCK_METHOD1(OnHostHasAdditionalCapacity, void(HttpPipelinedHost* host)); | |
32 }; | |
33 | |
34 class MockPipelineFactory : public HttpPipelinedConnection::Factory { | |
35 public: | |
36 MOCK_METHOD6(CreateNewPipeline, HttpPipelinedConnection*( | |
37 ClientSocketHandle* connection, | |
38 HttpPipelinedConnection::Delegate* delegate, | |
39 const SSLConfig& used_ssl_config, | |
40 const ProxyInfo& used_proxy_info, | |
41 const BoundNetLog& net_log, | |
42 bool was_npn_negotiated)); | |
43 }; | |
44 | |
45 class MockPipeline : public HttpPipelinedConnection { | |
46 public: | |
47 MockPipeline(int depth, bool usable, bool active) | |
48 : depth_(depth), | |
49 usable_(usable), | |
50 active_(active) { | |
51 } | |
52 | |
53 void SetState(int depth, bool usable, bool active) { | |
54 depth_ = depth; | |
55 usable_ = usable; | |
56 active_ = active; | |
57 } | |
58 | |
59 virtual int depth() const OVERRIDE { return depth_; } | |
60 virtual bool usable() const OVERRIDE { return usable_; } | |
61 virtual bool active() const OVERRIDE { return active_; } | |
62 | |
63 MOCK_METHOD0(CreateNewStream, HttpPipelinedStream*()); | |
64 MOCK_METHOD1(OnStreamDeleted, void(int pipeline_id)); | |
65 MOCK_CONST_METHOD0(used_ssl_config, const SSLConfig&()); | |
66 MOCK_CONST_METHOD0(used_proxy_info, const ProxyInfo&()); | |
67 MOCK_CONST_METHOD0(source, const NetLog::Source&()); | |
68 MOCK_CONST_METHOD0(was_npn_negotiated, bool()); | |
69 | |
70 private: | |
71 int depth_; | |
72 bool usable_; | |
73 bool active_; | |
74 }; | |
75 | |
76 class HttpPipelinedHostTest : public testing::Test { | |
77 public: | |
78 HttpPipelinedHostTest() | |
79 : origin_("host", 123), | |
80 factory_(new MockPipelineFactory), // Owned by host_. | |
81 host_(&delegate_, origin_, factory_) { | |
82 } | |
83 | |
84 MockPipeline* AddTestPipeline(int depth, bool usable, bool active) { | |
85 MockPipeline* pipeline = new MockPipeline(depth, usable, active); | |
86 EXPECT_CALL(*factory_, CreateNewPipeline(kDummyConnection, &host_, | |
87 Ref(ssl_config_), Ref(proxy_info_), | |
88 Ref(net_log_), true)) | |
89 .Times(1) | |
90 .WillOnce(Return(pipeline)); | |
91 EXPECT_CALL(*pipeline, CreateNewStream()) | |
92 .Times(1) | |
93 .WillOnce(Return(kDummyStream)); | |
94 EXPECT_EQ(kDummyStream, host_.CreateStreamOnNewPipeline( | |
95 kDummyConnection, ssl_config_, proxy_info_, net_log_, true)); | |
96 return pipeline; | |
97 } | |
98 | |
99 void ClearTestPipeline(MockPipeline* pipeline) { | |
100 pipeline->SetState(0, true, true); | |
101 host_.OnPipelineHasCapacity(pipeline); | |
102 } | |
103 | |
104 NiceMock<MockHostDelegate> delegate_; | |
105 HostPortPair origin_; | |
106 MockPipelineFactory* factory_; | |
107 HttpPipelinedHost host_; | |
108 | |
109 SSLConfig ssl_config_; | |
110 ProxyInfo proxy_info_; | |
111 BoundNetLog net_log_; | |
112 }; | |
113 | |
114 TEST_F(HttpPipelinedHostTest, Delegate) { | |
115 EXPECT_TRUE(origin_.Equals(host_.origin())); | |
116 } | |
117 | |
118 TEST_F(HttpPipelinedHostTest, OnHostIdle) { | |
119 MockPipeline* pipeline = AddTestPipeline(0, false, true); | |
120 | |
121 EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(&host_)) | |
122 .Times(0); | |
123 EXPECT_CALL(delegate_, OnHostIdle(&host_)) | |
124 .Times(1); | |
125 host_.OnPipelineHasCapacity(pipeline); | |
126 } | |
127 | |
128 TEST_F(HttpPipelinedHostTest, OnHostHasAdditionalCapacity) { | |
129 MockPipeline* pipeline = AddTestPipeline(1, true, true); | |
130 | |
131 EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(&host_)) | |
132 .Times(2); | |
133 EXPECT_CALL(delegate_, OnHostIdle(&host_)) | |
134 .Times(0); | |
135 | |
136 host_.OnPipelineHasCapacity(pipeline); | |
137 | |
138 EXPECT_CALL(delegate_, OnHostIdle(&host_)) | |
139 .Times(1); | |
140 ClearTestPipeline(pipeline); | |
141 } | |
142 | |
143 TEST_F(HttpPipelinedHostTest, IgnoresUnusablePipeline) { | |
144 MockPipeline* pipeline = AddTestPipeline(1, false, true); | |
145 | |
146 EXPECT_FALSE(host_.IsExistingPipelineAvailable()); | |
147 EXPECT_EQ(NULL, host_.CreateStreamOnExistingPipeline()); | |
148 | |
149 ClearTestPipeline(pipeline); | |
150 } | |
151 | |
152 TEST_F(HttpPipelinedHostTest, IgnoresInactivePipeline) { | |
153 MockPipeline* pipeline = AddTestPipeline(1, true, false); | |
154 | |
155 EXPECT_FALSE(host_.IsExistingPipelineAvailable()); | |
156 EXPECT_EQ(NULL, host_.CreateStreamOnExistingPipeline()); | |
157 | |
158 ClearTestPipeline(pipeline); | |
159 } | |
160 | |
161 TEST_F(HttpPipelinedHostTest, IgnoresFullPipeline) { | |
162 MockPipeline* pipeline = AddTestPipeline(kMaxCapacity, true, true); | |
163 | |
164 EXPECT_FALSE(host_.IsExistingPipelineAvailable()); | |
165 EXPECT_EQ(NULL, host_.CreateStreamOnExistingPipeline()); | |
166 | |
167 ClearTestPipeline(pipeline); | |
168 } | |
169 | |
170 TEST_F(HttpPipelinedHostTest, PicksLeastLoadedPipeline) { | |
171 MockPipeline* full_pipeline = AddTestPipeline(kMaxCapacity, true, true); | |
172 MockPipeline* usable_pipeline = AddTestPipeline(kMaxCapacity - 1, true, true); | |
173 MockPipeline* empty_pipeline = AddTestPipeline(0, true, true); | |
174 | |
175 EXPECT_TRUE(host_.IsExistingPipelineAvailable()); | |
176 EXPECT_CALL(*empty_pipeline, CreateNewStream()) | |
177 .Times(1) | |
178 .WillOnce(ReturnNull()); | |
179 EXPECT_EQ(NULL, host_.CreateStreamOnExistingPipeline()); | |
180 | |
181 ClearTestPipeline(full_pipeline); | |
182 ClearTestPipeline(usable_pipeline); | |
183 ClearTestPipeline(empty_pipeline); | |
184 } | |
185 | |
186 TEST_F(HttpPipelinedHostTest, EmptyPipelineIsRemoved) { | |
187 MockPipeline* empty_pipeline = AddTestPipeline(0, true, true); | |
188 | |
189 EXPECT_TRUE(host_.IsExistingPipelineAvailable()); | |
190 EXPECT_CALL(*empty_pipeline, CreateNewStream()) | |
191 .Times(1) | |
192 .WillOnce(Return(kDummyStream)); | |
193 EXPECT_EQ(kDummyStream, host_.CreateStreamOnExistingPipeline()); | |
194 | |
195 ClearTestPipeline(empty_pipeline); | |
196 | |
197 EXPECT_FALSE(host_.IsExistingPipelineAvailable()); | |
198 EXPECT_EQ(NULL, host_.CreateStreamOnExistingPipeline()); | |
199 } | |
200 | |
201 } // namespace net | |
OLD | NEW |