Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / socket / socks_client_socket_pool_unittest.cc
blobe841c83635d7fc3813e1b08a7f01c5156481bbc2
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/socket/socks_client_socket_pool.h"
7 #include "base/callback.h"
8 #include "base/compiler_specific.h"
9 #include "base/time/time.h"
10 #include "net/base/load_timing_info.h"
11 #include "net/base/load_timing_info_test_util.h"
12 #include "net/base/net_errors.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/dns/mock_host_resolver.h"
15 #include "net/socket/client_socket_factory.h"
16 #include "net/socket/client_socket_handle.h"
17 #include "net/socket/socket_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace net {
22 namespace {
24 const int kMaxSockets = 32;
25 const int kMaxSocketsPerGroup = 6;
27 // Make sure |handle|'s load times are set correctly. Only connect times should
28 // be set.
29 void TestLoadTimingInfo(const ClientSocketHandle& handle) {
30 LoadTimingInfo load_timing_info;
31 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
33 // None of these tests use a NetLog.
34 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
36 EXPECT_FALSE(load_timing_info.socket_reused);
38 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
39 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
40 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
44 scoped_refptr<TransportSocketParams> CreateProxyHostParams() {
45 return new TransportSocketParams(
46 HostPortPair("proxy", 80), false, false, OnHostResolutionCallback(),
47 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT);
50 scoped_refptr<SOCKSSocketParams> CreateSOCKSv4Params() {
51 return new SOCKSSocketParams(
52 CreateProxyHostParams(), false /* socks_v5 */,
53 HostPortPair("host", 80));
56 scoped_refptr<SOCKSSocketParams> CreateSOCKSv5Params() {
57 return new SOCKSSocketParams(
58 CreateProxyHostParams(), true /* socks_v5 */,
59 HostPortPair("host", 80));
62 class SOCKSClientSocketPoolTest : public testing::Test {
63 protected:
64 class SOCKS5MockData {
65 public:
66 explicit SOCKS5MockData(IoMode mode) {
67 writes_.reset(new MockWrite[3]);
68 writes_[0] = MockWrite(mode, kSOCKS5GreetRequest,
69 kSOCKS5GreetRequestLength);
70 writes_[1] = MockWrite(mode, kSOCKS5OkRequest, kSOCKS5OkRequestLength);
71 writes_[2] = MockWrite(mode, 0);
73 reads_.reset(new MockRead[3]);
74 reads_[0] = MockRead(mode, kSOCKS5GreetResponse,
75 kSOCKS5GreetResponseLength);
76 reads_[1] = MockRead(mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength);
77 reads_[2] = MockRead(mode, 0);
79 data_.reset(new StaticSocketDataProvider(reads_.get(), 3,
80 writes_.get(), 3));
83 SocketDataProvider* data_provider() { return data_.get(); }
85 private:
86 scoped_ptr<StaticSocketDataProvider> data_;
87 scoped_ptr<MockWrite[]> writes_;
88 scoped_ptr<MockRead[]> reads_;
91 SOCKSClientSocketPoolTest()
92 : transport_socket_pool_(kMaxSockets,
93 kMaxSocketsPerGroup,
94 &transport_client_socket_factory_),
95 pool_(kMaxSockets,
96 kMaxSocketsPerGroup,
97 &host_resolver_,
98 &transport_socket_pool_,
99 NULL) {}
101 ~SOCKSClientSocketPoolTest() override {}
103 int StartRequestV5(const std::string& group_name, RequestPriority priority) {
104 return test_base_.StartRequestUsingPool(
105 &pool_, group_name, priority, CreateSOCKSv5Params());
108 int GetOrderOfRequest(size_t index) const {
109 return test_base_.GetOrderOfRequest(index);
112 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
114 MockClientSocketFactory transport_client_socket_factory_;
115 MockTransportClientSocketPool transport_socket_pool_;
117 MockHostResolver host_resolver_;
118 SOCKSClientSocketPool pool_;
119 ClientSocketPoolTest test_base_;
122 TEST_F(SOCKSClientSocketPoolTest, Simple) {
123 SOCKS5MockData data(SYNCHRONOUS);
124 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
125 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
127 ClientSocketHandle handle;
128 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, CompletionCallback(),
129 &pool_, BoundNetLog());
130 EXPECT_EQ(OK, rv);
131 EXPECT_TRUE(handle.is_initialized());
132 EXPECT_TRUE(handle.socket());
133 TestLoadTimingInfo(handle);
136 // Make sure that SOCKSConnectJob passes on its priority to its
137 // socket request on Init.
138 TEST_F(SOCKSClientSocketPoolTest, SetSocketRequestPriorityOnInit) {
139 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
140 RequestPriority priority = static_cast<RequestPriority>(i);
141 SOCKS5MockData data(SYNCHRONOUS);
142 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
143 transport_client_socket_factory_.AddSocketDataProvider(
144 data.data_provider());
146 ClientSocketHandle handle;
147 EXPECT_EQ(OK,
148 handle.Init("a", CreateSOCKSv5Params(), priority,
149 CompletionCallback(), &pool_, BoundNetLog()));
150 EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
151 handle.socket()->Disconnect();
155 // Make sure that SOCKSConnectJob passes on its priority to its
156 // HostResolver request (for non-SOCKS5) on Init.
157 TEST_F(SOCKSClientSocketPoolTest, SetResolvePriorityOnInit) {
158 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
159 RequestPriority priority = static_cast<RequestPriority>(i);
160 SOCKS5MockData data(SYNCHRONOUS);
161 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
162 transport_client_socket_factory_.AddSocketDataProvider(
163 data.data_provider());
165 ClientSocketHandle handle;
166 EXPECT_EQ(ERR_IO_PENDING,
167 handle.Init("a", CreateSOCKSv4Params(), priority,
168 CompletionCallback(), &pool_, BoundNetLog()));
169 EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
170 EXPECT_EQ(priority, host_resolver_.last_request_priority());
171 EXPECT_TRUE(handle.socket() == NULL);
175 TEST_F(SOCKSClientSocketPoolTest, Async) {
176 SOCKS5MockData data(ASYNC);
177 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
179 TestCompletionCallback callback;
180 ClientSocketHandle handle;
181 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, callback.callback(),
182 &pool_, BoundNetLog());
183 EXPECT_EQ(ERR_IO_PENDING, rv);
184 EXPECT_FALSE(handle.is_initialized());
185 EXPECT_FALSE(handle.socket());
187 EXPECT_EQ(OK, callback.WaitForResult());
188 EXPECT_TRUE(handle.is_initialized());
189 EXPECT_TRUE(handle.socket());
190 TestLoadTimingInfo(handle);
193 TEST_F(SOCKSClientSocketPoolTest, TransportConnectError) {
194 StaticSocketDataProvider socket_data;
195 socket_data.set_connect_data(MockConnect(SYNCHRONOUS,
196 ERR_CONNECTION_REFUSED));
197 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
199 ClientSocketHandle handle;
200 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, CompletionCallback(),
201 &pool_, BoundNetLog());
202 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
203 EXPECT_FALSE(handle.is_initialized());
204 EXPECT_FALSE(handle.socket());
207 TEST_F(SOCKSClientSocketPoolTest, AsyncTransportConnectError) {
208 StaticSocketDataProvider socket_data;
209 socket_data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
210 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
212 TestCompletionCallback callback;
213 ClientSocketHandle handle;
214 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, callback.callback(),
215 &pool_, BoundNetLog());
216 EXPECT_EQ(ERR_IO_PENDING, rv);
217 EXPECT_FALSE(handle.is_initialized());
218 EXPECT_FALSE(handle.socket());
220 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult());
221 EXPECT_FALSE(handle.is_initialized());
222 EXPECT_FALSE(handle.socket());
225 TEST_F(SOCKSClientSocketPoolTest, SOCKSConnectError) {
226 MockRead failed_read[] = {
227 MockRead(SYNCHRONOUS, 0),
229 StaticSocketDataProvider socket_data(
230 failed_read, arraysize(failed_read), NULL, 0);
231 socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
232 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
234 ClientSocketHandle handle;
235 EXPECT_EQ(0, transport_socket_pool_.release_count());
236 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, CompletionCallback(),
237 &pool_, BoundNetLog());
238 EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, rv);
239 EXPECT_FALSE(handle.is_initialized());
240 EXPECT_FALSE(handle.socket());
241 EXPECT_EQ(1, transport_socket_pool_.release_count());
244 TEST_F(SOCKSClientSocketPoolTest, AsyncSOCKSConnectError) {
245 MockRead failed_read[] = {
246 MockRead(ASYNC, 0),
248 StaticSocketDataProvider socket_data(
249 failed_read, arraysize(failed_read), NULL, 0);
250 socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
251 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
253 TestCompletionCallback callback;
254 ClientSocketHandle handle;
255 EXPECT_EQ(0, transport_socket_pool_.release_count());
256 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, callback.callback(),
257 &pool_, BoundNetLog());
258 EXPECT_EQ(ERR_IO_PENDING, rv);
259 EXPECT_FALSE(handle.is_initialized());
260 EXPECT_FALSE(handle.socket());
262 EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, callback.WaitForResult());
263 EXPECT_FALSE(handle.is_initialized());
264 EXPECT_FALSE(handle.socket());
265 EXPECT_EQ(1, transport_socket_pool_.release_count());
268 TEST_F(SOCKSClientSocketPoolTest, CancelDuringTransportConnect) {
269 SOCKS5MockData data(SYNCHRONOUS);
270 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
271 // We need two connections because the pool base lets one cancelled
272 // connect job proceed for potential future use.
273 SOCKS5MockData data2(SYNCHRONOUS);
274 transport_client_socket_factory_.AddSocketDataProvider(data2.data_provider());
276 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
277 int rv = StartRequestV5("a", LOW);
278 EXPECT_EQ(ERR_IO_PENDING, rv);
280 rv = StartRequestV5("a", LOW);
281 EXPECT_EQ(ERR_IO_PENDING, rv);
283 pool_.CancelRequest("a", (*requests())[0]->handle());
284 pool_.CancelRequest("a", (*requests())[1]->handle());
285 // Requests in the connect phase don't actually get cancelled.
286 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
288 // Now wait for the TCP sockets to connect.
289 base::MessageLoop::current()->RunUntilIdle();
291 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(1));
292 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(2));
293 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
294 EXPECT_EQ(2, pool_.IdleSocketCount());
296 (*requests())[0]->handle()->Reset();
297 (*requests())[1]->handle()->Reset();
300 TEST_F(SOCKSClientSocketPoolTest, CancelDuringSOCKSConnect) {
301 SOCKS5MockData data(ASYNC);
302 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
303 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
304 // We need two connections because the pool base lets one cancelled
305 // connect job proceed for potential future use.
306 SOCKS5MockData data2(ASYNC);
307 data2.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
308 transport_client_socket_factory_.AddSocketDataProvider(data2.data_provider());
310 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
311 EXPECT_EQ(0, transport_socket_pool_.release_count());
312 int rv = StartRequestV5("a", LOW);
313 EXPECT_EQ(ERR_IO_PENDING, rv);
315 rv = StartRequestV5("a", LOW);
316 EXPECT_EQ(ERR_IO_PENDING, rv);
318 pool_.CancelRequest("a", (*requests())[0]->handle());
319 pool_.CancelRequest("a", (*requests())[1]->handle());
320 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
321 // Requests in the connect phase don't actually get cancelled.
322 EXPECT_EQ(0, transport_socket_pool_.release_count());
324 // Now wait for the async data to reach the SOCKS connect jobs.
325 base::MessageLoop::current()->RunUntilIdle();
327 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(1));
328 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(2));
329 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
330 EXPECT_EQ(0, transport_socket_pool_.release_count());
331 EXPECT_EQ(2, pool_.IdleSocketCount());
333 (*requests())[0]->handle()->Reset();
334 (*requests())[1]->handle()->Reset();
337 // It would be nice to also test the timeouts in SOCKSClientSocketPool.
339 } // namespace
341 } // namespace net