Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / net / socket / socks_client_socket_pool_unittest.cc
blobb2b8655ee220b7794287130cfe981f4720f75ef1
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/client_socket_pool_histograms.h"
18 #include "net/socket/socket_test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace net {
23 namespace {
25 const int kMaxSockets = 32;
26 const int kMaxSocketsPerGroup = 6;
28 // Make sure |handle|'s load times are set correctly. Only connect times should
29 // be set.
30 void TestLoadTimingInfo(const ClientSocketHandle& handle) {
31 LoadTimingInfo load_timing_info;
32 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
34 // None of these tests use a NetLog.
35 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
37 EXPECT_FALSE(load_timing_info.socket_reused);
39 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
40 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
41 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
45 scoped_refptr<TransportSocketParams> CreateProxyHostParams() {
46 return new TransportSocketParams(
47 HostPortPair("proxy", 80), false, false,
48 OnHostResolutionCallback());
51 scoped_refptr<SOCKSSocketParams> CreateSOCKSv4Params() {
52 return new SOCKSSocketParams(
53 CreateProxyHostParams(), false /* socks_v5 */,
54 HostPortPair("host", 80));
57 scoped_refptr<SOCKSSocketParams> CreateSOCKSv5Params() {
58 return new SOCKSSocketParams(
59 CreateProxyHostParams(), true /* socks_v5 */,
60 HostPortPair("host", 80));
63 class SOCKSClientSocketPoolTest : public testing::Test {
64 protected:
65 class SOCKS5MockData {
66 public:
67 explicit SOCKS5MockData(IoMode mode) {
68 writes_.reset(new MockWrite[3]);
69 writes_[0] = MockWrite(mode, kSOCKS5GreetRequest,
70 kSOCKS5GreetRequestLength);
71 writes_[1] = MockWrite(mode, kSOCKS5OkRequest, kSOCKS5OkRequestLength);
72 writes_[2] = MockWrite(mode, 0);
74 reads_.reset(new MockRead[3]);
75 reads_[0] = MockRead(mode, kSOCKS5GreetResponse,
76 kSOCKS5GreetResponseLength);
77 reads_[1] = MockRead(mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength);
78 reads_[2] = MockRead(mode, 0);
80 data_.reset(new StaticSocketDataProvider(reads_.get(), 3,
81 writes_.get(), 3));
84 SocketDataProvider* data_provider() { return data_.get(); }
86 private:
87 scoped_ptr<StaticSocketDataProvider> data_;
88 scoped_ptr<MockWrite[]> writes_;
89 scoped_ptr<MockRead[]> reads_;
92 SOCKSClientSocketPoolTest()
93 : transport_histograms_("MockTCP"),
94 transport_socket_pool_(
95 kMaxSockets, kMaxSocketsPerGroup,
96 &transport_histograms_,
97 &transport_client_socket_factory_),
98 socks_histograms_("SOCKSUnitTest"),
99 pool_(kMaxSockets, kMaxSocketsPerGroup,
100 &socks_histograms_,
101 &host_resolver_,
102 &transport_socket_pool_,
103 NULL) {
106 virtual ~SOCKSClientSocketPoolTest() {}
108 int StartRequestV5(const std::string& group_name, RequestPriority priority) {
109 return test_base_.StartRequestUsingPool(
110 &pool_, group_name, priority, CreateSOCKSv5Params());
113 int GetOrderOfRequest(size_t index) const {
114 return test_base_.GetOrderOfRequest(index);
117 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
119 ClientSocketPoolHistograms transport_histograms_;
120 MockClientSocketFactory transport_client_socket_factory_;
121 MockTransportClientSocketPool transport_socket_pool_;
123 ClientSocketPoolHistograms socks_histograms_;
124 MockHostResolver host_resolver_;
125 SOCKSClientSocketPool pool_;
126 ClientSocketPoolTest test_base_;
129 TEST_F(SOCKSClientSocketPoolTest, Simple) {
130 SOCKS5MockData data(SYNCHRONOUS);
131 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
132 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
134 ClientSocketHandle handle;
135 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, CompletionCallback(),
136 &pool_, BoundNetLog());
137 EXPECT_EQ(OK, rv);
138 EXPECT_TRUE(handle.is_initialized());
139 EXPECT_TRUE(handle.socket());
140 TestLoadTimingInfo(handle);
143 // Make sure that SOCKSConnectJob passes on its priority to its
144 // socket request on Init.
145 TEST_F(SOCKSClientSocketPoolTest, SetSocketRequestPriorityOnInit) {
146 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
147 RequestPriority priority = static_cast<RequestPriority>(i);
148 SOCKS5MockData data(SYNCHRONOUS);
149 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
150 transport_client_socket_factory_.AddSocketDataProvider(
151 data.data_provider());
153 ClientSocketHandle handle;
154 EXPECT_EQ(OK,
155 handle.Init("a", CreateSOCKSv5Params(), priority,
156 CompletionCallback(), &pool_, BoundNetLog()));
157 EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
158 handle.socket()->Disconnect();
162 // Make sure that SOCKSConnectJob passes on its priority to its
163 // HostResolver request (for non-SOCKS5) on Init.
164 TEST_F(SOCKSClientSocketPoolTest, SetResolvePriorityOnInit) {
165 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
166 RequestPriority priority = static_cast<RequestPriority>(i);
167 SOCKS5MockData data(SYNCHRONOUS);
168 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
169 transport_client_socket_factory_.AddSocketDataProvider(
170 data.data_provider());
172 ClientSocketHandle handle;
173 EXPECT_EQ(ERR_IO_PENDING,
174 handle.Init("a", CreateSOCKSv4Params(), priority,
175 CompletionCallback(), &pool_, BoundNetLog()));
176 EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
177 EXPECT_EQ(priority, host_resolver_.last_request_priority());
178 EXPECT_TRUE(handle.socket() == NULL);
182 TEST_F(SOCKSClientSocketPoolTest, Async) {
183 SOCKS5MockData data(ASYNC);
184 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
186 TestCompletionCallback callback;
187 ClientSocketHandle handle;
188 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, callback.callback(),
189 &pool_, BoundNetLog());
190 EXPECT_EQ(ERR_IO_PENDING, rv);
191 EXPECT_FALSE(handle.is_initialized());
192 EXPECT_FALSE(handle.socket());
194 EXPECT_EQ(OK, callback.WaitForResult());
195 EXPECT_TRUE(handle.is_initialized());
196 EXPECT_TRUE(handle.socket());
197 TestLoadTimingInfo(handle);
200 TEST_F(SOCKSClientSocketPoolTest, TransportConnectError) {
201 StaticSocketDataProvider socket_data;
202 socket_data.set_connect_data(MockConnect(SYNCHRONOUS,
203 ERR_CONNECTION_REFUSED));
204 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
206 ClientSocketHandle handle;
207 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, CompletionCallback(),
208 &pool_, BoundNetLog());
209 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
210 EXPECT_FALSE(handle.is_initialized());
211 EXPECT_FALSE(handle.socket());
214 TEST_F(SOCKSClientSocketPoolTest, AsyncTransportConnectError) {
215 StaticSocketDataProvider socket_data;
216 socket_data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
217 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
219 TestCompletionCallback callback;
220 ClientSocketHandle handle;
221 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, callback.callback(),
222 &pool_, BoundNetLog());
223 EXPECT_EQ(ERR_IO_PENDING, rv);
224 EXPECT_FALSE(handle.is_initialized());
225 EXPECT_FALSE(handle.socket());
227 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult());
228 EXPECT_FALSE(handle.is_initialized());
229 EXPECT_FALSE(handle.socket());
232 TEST_F(SOCKSClientSocketPoolTest, SOCKSConnectError) {
233 MockRead failed_read[] = {
234 MockRead(SYNCHRONOUS, 0),
236 StaticSocketDataProvider socket_data(
237 failed_read, arraysize(failed_read), NULL, 0);
238 socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
239 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
241 ClientSocketHandle handle;
242 EXPECT_EQ(0, transport_socket_pool_.release_count());
243 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, CompletionCallback(),
244 &pool_, BoundNetLog());
245 EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, rv);
246 EXPECT_FALSE(handle.is_initialized());
247 EXPECT_FALSE(handle.socket());
248 EXPECT_EQ(1, transport_socket_pool_.release_count());
251 TEST_F(SOCKSClientSocketPoolTest, AsyncSOCKSConnectError) {
252 MockRead failed_read[] = {
253 MockRead(ASYNC, 0),
255 StaticSocketDataProvider socket_data(
256 failed_read, arraysize(failed_read), NULL, 0);
257 socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
258 transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
260 TestCompletionCallback callback;
261 ClientSocketHandle handle;
262 EXPECT_EQ(0, transport_socket_pool_.release_count());
263 int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, callback.callback(),
264 &pool_, BoundNetLog());
265 EXPECT_EQ(ERR_IO_PENDING, rv);
266 EXPECT_FALSE(handle.is_initialized());
267 EXPECT_FALSE(handle.socket());
269 EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, callback.WaitForResult());
270 EXPECT_FALSE(handle.is_initialized());
271 EXPECT_FALSE(handle.socket());
272 EXPECT_EQ(1, transport_socket_pool_.release_count());
275 TEST_F(SOCKSClientSocketPoolTest, CancelDuringTransportConnect) {
276 SOCKS5MockData data(SYNCHRONOUS);
277 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
278 // We need two connections because the pool base lets one cancelled
279 // connect job proceed for potential future use.
280 SOCKS5MockData data2(SYNCHRONOUS);
281 transport_client_socket_factory_.AddSocketDataProvider(data2.data_provider());
283 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
284 int rv = StartRequestV5("a", LOW);
285 EXPECT_EQ(ERR_IO_PENDING, rv);
287 rv = StartRequestV5("a", LOW);
288 EXPECT_EQ(ERR_IO_PENDING, rv);
290 pool_.CancelRequest("a", (*requests())[0]->handle());
291 pool_.CancelRequest("a", (*requests())[1]->handle());
292 // Requests in the connect phase don't actually get cancelled.
293 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
295 // Now wait for the TCP sockets to connect.
296 base::MessageLoop::current()->RunUntilIdle();
298 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(1));
299 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(2));
300 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
301 EXPECT_EQ(2, pool_.IdleSocketCount());
303 (*requests())[0]->handle()->Reset();
304 (*requests())[1]->handle()->Reset();
307 TEST_F(SOCKSClientSocketPoolTest, CancelDuringSOCKSConnect) {
308 SOCKS5MockData data(ASYNC);
309 data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
310 transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
311 // We need two connections because the pool base lets one cancelled
312 // connect job proceed for potential future use.
313 SOCKS5MockData data2(ASYNC);
314 data2.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
315 transport_client_socket_factory_.AddSocketDataProvider(data2.data_provider());
317 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
318 EXPECT_EQ(0, transport_socket_pool_.release_count());
319 int rv = StartRequestV5("a", LOW);
320 EXPECT_EQ(ERR_IO_PENDING, rv);
322 rv = StartRequestV5("a", LOW);
323 EXPECT_EQ(ERR_IO_PENDING, rv);
325 pool_.CancelRequest("a", (*requests())[0]->handle());
326 pool_.CancelRequest("a", (*requests())[1]->handle());
327 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
328 // Requests in the connect phase don't actually get cancelled.
329 EXPECT_EQ(0, transport_socket_pool_.release_count());
331 // Now wait for the async data to reach the SOCKS connect jobs.
332 base::MessageLoop::current()->RunUntilIdle();
334 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(1));
335 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(2));
336 EXPECT_EQ(0, transport_socket_pool_.cancel_count());
337 EXPECT_EQ(0, transport_socket_pool_.release_count());
338 EXPECT_EQ(2, pool_.IdleSocketCount());
340 (*requests())[0]->handle()->Reset();
341 (*requests())[1]->handle()->Reset();
344 // It would be nice to also test the timeouts in SOCKSClientSocketPool.
346 } // namespace
348 } // namespace net