Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: net/base/client_socket_pool_unittest.cc

Issue 118219: Reland my ClientSocketPool refactor again... (Closed)
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/base/client_socket_pool.cc ('k') | net/base/test_completion_callback.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/message_loop.h" 5 #include "base/message_loop.h"
6 #include "net/base/client_socket.h" 6 #include "net/base/client_socket.h"
7 #include "net/base/client_socket_factory.h"
7 #include "net/base/client_socket_handle.h" 8 #include "net/base/client_socket_handle.h"
8 #include "net/base/client_socket_pool.h" 9 #include "net/base/client_socket_pool.h"
10 #include "net/base/host_resolver_unittest.h"
9 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
12 #include "net/base/test_completion_callback.h"
10 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
11 14
15 namespace net {
16
12 namespace { 17 namespace {
13 18
14 const int kMaxSocketsPerGroup = 6; 19 const int kMaxSocketsPerGroup = 6;
15 20
16 // Note that the first and the last are the same, the first should be handled 21 // Note that the first and the last are the same, the first should be handled
17 // before the last, since it was inserted first. 22 // before the last, since it was inserted first.
18 const int kPriorities[10] = { 1, 7, 9, 5, 6, 2, 8, 3, 4, 1 }; 23 const int kPriorities[10] = { 1, 7, 9, 5, 6, 2, 8, 3, 4, 1 };
19 24
20 // This is the number of extra requests beyond the first few that use up all 25 // This is the number of extra requests beyond the first few that use up all
21 // available sockets in the socket group. 26 // available sockets in the socket group.
22 const int kNumPendingRequests = arraysize(kPriorities); 27 const int kNumPendingRequests = arraysize(kPriorities);
23 28
24 class MockClientSocket : public net::ClientSocket { 29 const int kNumRequests = kMaxSocketsPerGroup + kNumPendingRequests;
30
31 class MockClientSocket : public ClientSocket {
25 public: 32 public:
26 MockClientSocket() : connected_(false) { 33 MockClientSocket() : connected_(false) {}
27 allocation_count++;
28 }
29 34
30 // ClientSocket methods: 35 // ClientSocket methods:
31 virtual int Connect(net::CompletionCallback* callback) { 36 virtual int Connect(CompletionCallback* callback) {
32 connected_ = true; 37 connected_ = true;
33 return net::OK; 38 return OK;
34 } 39 }
35 virtual void Disconnect() { 40 virtual void Disconnect() {
36 connected_ = false; 41 connected_ = false;
37 } 42 }
38 virtual bool IsConnected() const { 43 virtual bool IsConnected() const {
39 return connected_; 44 return connected_;
40 } 45 }
41 virtual bool IsConnectedAndIdle() const { 46 virtual bool IsConnectedAndIdle() const {
42 return connected_; 47 return connected_;
43 } 48 }
44 49
45 // Socket methods: 50 // Socket methods:
46 virtual int Read(net::IOBuffer* buf, int buf_len, 51 virtual int Read(IOBuffer* buf, int buf_len,
47 net::CompletionCallback* callback) { 52 CompletionCallback* callback) {
48 return net::ERR_FAILED; 53 return ERR_FAILED;
49 } 54 }
50 virtual int Write(net::IOBuffer* buf, int buf_len, 55 virtual int Write(IOBuffer* buf, int buf_len,
51 net::CompletionCallback* callback) { 56 CompletionCallback* callback) {
52 return net::ERR_FAILED; 57 return ERR_FAILED;
53 } 58 }
54 59
55 static int allocation_count;
56
57 private: 60 private:
58 bool connected_; 61 bool connected_;
59 }; 62 };
60 63
61 int MockClientSocket::allocation_count = 0; 64 class MockFailingClientSocket : public ClientSocket {
65 public:
66 MockFailingClientSocket() {}
67
68 // ClientSocket methods:
69 virtual int Connect(CompletionCallback* callback) {
70 return ERR_CONNECTION_FAILED;
71 }
72
73 virtual void Disconnect() {}
74
75 virtual bool IsConnected() const {
76 return false;
77 }
78 virtual bool IsConnectedAndIdle() const {
79 return false;
80 }
81
82 // Socket methods:
83 virtual int Read(IOBuffer* buf, int buf_len,
84 CompletionCallback* callback) {
85 return ERR_FAILED;
86 }
87
88 virtual int Write(IOBuffer* buf, int buf_len,
89 CompletionCallback* callback) {
90 return ERR_FAILED;
91 }
92 };
93
94 class MockPendingClientSocket : public ClientSocket {
95 public:
96 MockPendingClientSocket() {}
97
98 // ClientSocket methods:
99 virtual int Connect(CompletionCallback* callback) {
100 return ERR_IO_PENDING;
101 }
102
103 virtual void Disconnect() {}
104
105 virtual bool IsConnected() const {
106 return false;
107 }
108 virtual bool IsConnectedAndIdle() const {
109 return false;
110 }
111
112 // Socket methods:
113 virtual int Read(IOBuffer* buf, int buf_len,
114 CompletionCallback* callback) {
115 return ERR_FAILED;
116 }
117
118 virtual int Write(IOBuffer* buf, int buf_len,
119 CompletionCallback* callback) {
120 return ERR_FAILED;
121 }
122 };
123
124 class MockClientSocketFactory : public ClientSocketFactory {
125 public:
126 enum ClientSocketType {
127 MOCK_CLIENT_SOCKET,
128 MOCK_FAILING_CLIENT_SOCKET,
129 MOCK_PENDING_CLIENT_SOCKET,
130 };
131
132 MockClientSocketFactory()
133 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET) {}
134
135 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
136 allocation_count_++;
137 switch (client_socket_type_) {
138 case MOCK_CLIENT_SOCKET:
139 return new MockClientSocket();
140 case MOCK_FAILING_CLIENT_SOCKET:
141 return new MockFailingClientSocket();
142 case MOCK_PENDING_CLIENT_SOCKET:
143 return new MockPendingClientSocket();
144 default:
145 NOTREACHED();
146 return new MockClientSocket();
147 }
148 }
149
150 virtual SSLClientSocket* CreateSSLClientSocket(
151 ClientSocket* transport_socket,
152 const std::string& hostname,
153 const SSLConfig& ssl_config) {
154 NOTIMPLEMENTED();
155 return NULL;
156 }
157
158 int allocation_count() const { return allocation_count_; }
159
160 void set_client_socket_type(ClientSocketType type) {
161 client_socket_type_ = type;
162 }
163
164 private:
165 int allocation_count_;
166 ClientSocketType client_socket_type_;
167 };
62 168
63 class TestSocketRequest : public CallbackRunner< Tuple1<int> > { 169 class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
64 public: 170 public:
65 TestSocketRequest( 171 TestSocketRequest(
66 net::ClientSocketPool* pool, 172 ClientSocketPool* pool,
67 std::vector<TestSocketRequest*>* request_order) 173 std::vector<TestSocketRequest*>* request_order)
68 : handle(pool), request_order_(request_order) {} 174 : handle(pool), request_order_(request_order) {}
69 175
70 net::ClientSocketHandle handle; 176 ClientSocketHandle handle;
71 177
72 void EnsureSocket() { 178 int WaitForResult() {
73 DCHECK(handle.is_initialized()); 179 return callback_.WaitForResult();
74 request_order_->push_back(this);
75 if (!handle.socket()) {
76 handle.set_socket(new MockClientSocket());
77 handle.socket()->Connect(NULL);
78 }
79 } 180 }
80 181
81 virtual void RunWithParams(const Tuple1<int>& params) { 182 virtual void RunWithParams(const Tuple1<int>& params) {
82 DCHECK(params.a == net::OK); 183 callback_.RunWithParams(params);
83 completion_count++; 184 completion_count++;
84 EnsureSocket(); 185 request_order_->push_back(this);
85 } 186 }
86 187
87 static int completion_count; 188 static int completion_count;
88 189
89 private: 190 private:
90 std::vector<TestSocketRequest*>* request_order_; 191 std::vector<TestSocketRequest*>* request_order_;
192 TestCompletionCallback callback_;
91 }; 193 };
92 194
93 int TestSocketRequest::completion_count = 0; 195 int TestSocketRequest::completion_count = 0;
94 196
95 class ClientSocketPoolTest : public testing::Test { 197 class ClientSocketPoolTest : public testing::Test {
96 protected: 198 protected:
97 ClientSocketPoolTest() 199 ClientSocketPoolTest()
98 : pool_(new net::ClientSocketPool(kMaxSocketsPerGroup)) {} 200 : pool_(new ClientSocketPool(kMaxSocketsPerGroup,
201 &client_socket_factory_)) {}
99 202
100 virtual void SetUp() { 203 virtual void SetUp() {
101 MockClientSocket::allocation_count = 0;
102 TestSocketRequest::completion_count = 0; 204 TestSocketRequest::completion_count = 0;
103 } 205 }
104 206
105 scoped_refptr<net::ClientSocketPool> pool_; 207 MockClientSocketFactory client_socket_factory_;
208 scoped_refptr<ClientSocketPool> pool_;
106 std::vector<TestSocketRequest*> request_order_; 209 std::vector<TestSocketRequest*> request_order_;
107 }; 210 };
108 211
109 TEST_F(ClientSocketPoolTest, Basic) { 212 TEST_F(ClientSocketPoolTest, Basic) {
110 TestSocketRequest r(pool_.get(), &request_order_); 213 TestCompletionCallback callback;
111 int rv; 214 ClientSocketHandle handle(pool_.get());
215 int rv = handle.Init("a", "www.google.com", 80, 0, &callback);
216 EXPECT_EQ(ERR_IO_PENDING, rv);
217 EXPECT_FALSE(handle.is_initialized());
218 EXPECT_FALSE(handle.socket());
112 219
113 rv = r.handle.Init("a", 0, &r); 220 EXPECT_EQ(OK, callback.WaitForResult());
114 EXPECT_EQ(net::OK, rv); 221 EXPECT_TRUE(handle.is_initialized());
115 EXPECT_TRUE(r.handle.is_initialized()); 222 EXPECT_TRUE(handle.socket());
116 223
117 r.handle.Reset(); 224 handle.Reset();
118 225
119 // The handle's Reset method may have posted a task. 226 // The handle's Reset method may have posted a task.
120 MessageLoop::current()->RunAllPending(); 227 MessageLoop::current()->RunAllPending();
121 } 228 }
122 229
123 TEST_F(ClientSocketPoolTest, WithIdleConnection) { 230 TEST_F(ClientSocketPoolTest, InitHostResolutionFailure) {
124 TestSocketRequest r(pool_.get(), &request_order_); 231 RuleBasedHostMapper* host_mapper = new RuleBasedHostMapper;
125 int rv; 232 host_mapper->AddSimulatedFailure("unresolvable.host.name");
233 ScopedHostMapper scoped_host_mapper(host_mapper);
234 TestSocketRequest req(pool_.get(), &request_order_);
235 EXPECT_EQ(ERR_IO_PENDING,
236 req.handle.Init("a", "unresolvable.host.name", 80, 5, &req));
237 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult());
238 }
126 239
127 rv = r.handle.Init("a", 0, &r); 240 TEST_F(ClientSocketPoolTest, InitConnectionFailure) {
128 EXPECT_EQ(net::OK, rv); 241 client_socket_factory_.set_client_socket_type(
129 EXPECT_TRUE(r.handle.is_initialized()); 242 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
130 243 TestSocketRequest req(pool_.get(), &request_order_);
131 // Create a socket. 244 EXPECT_EQ(ERR_IO_PENDING,
132 r.EnsureSocket(); 245 req.handle.Init("a", "unresolvable.host.name", 80, 5, &req));
133 246 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
134 // Release the socket. It should find its way into the idle list. We're
135 // testing that this does not trigger a crash.
136 r.handle.Reset();
137
138 // The handle's Reset method may have posted a task.
139 MessageLoop::current()->RunAllPending();
140 } 247 }
141 248
142 TEST_F(ClientSocketPoolTest, PendingRequests) { 249 TEST_F(ClientSocketPoolTest, PendingRequests) {
143 int rv; 250 int rv;
144 251
145 scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + kNumPendingRequests]; 252 scoped_ptr<TestSocketRequest> reqs[kNumRequests];
146 253
147 for (size_t i = 0; i < arraysize(reqs); ++i) 254 for (size_t i = 0; i < arraysize(reqs); ++i)
148 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 255 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
149 256
150 // Create connections or queue up requests. 257 // Create connections or queue up requests.
151 for (int i = 0; i < kMaxSocketsPerGroup; ++i) { 258 for (int i = 0; i < kMaxSocketsPerGroup; ++i) {
152 rv = reqs[i]->handle.Init("a", 5, reqs[i].get()); 259 rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get());
153 EXPECT_EQ(net::OK, rv); 260 EXPECT_EQ(ERR_IO_PENDING, rv);
154 reqs[i]->EnsureSocket(); 261 EXPECT_EQ(OK, reqs[i]->WaitForResult());
155 } 262 }
263
156 for (int i = 0; i < kNumPendingRequests; ++i) { 264 for (int i = 0; i < kNumPendingRequests; ++i) {
157 rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( 265 rv = reqs[kMaxSocketsPerGroup + i]->handle.Init(
158 "a", kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()); 266 "a", "www.google.com", 80, kPriorities[i],
159 EXPECT_EQ(net::ERR_IO_PENDING, rv); 267 reqs[kMaxSocketsPerGroup + i].get());
268 EXPECT_EQ(ERR_IO_PENDING, rv);
160 } 269 }
161 270
162 // Release any connections until we have no connections. 271 // Release any connections until we have no connections.
163 bool released_one; 272 bool released_one;
164 do { 273 do {
165 released_one = false; 274 released_one = false;
166 for (size_t i = 0; i < arraysize(reqs); ++i) { 275 for (size_t i = 0; i < arraysize(reqs); ++i) {
167 if (reqs[i]->handle.is_initialized()) { 276 if (reqs[i]->handle.is_initialized()) {
168 reqs[i]->handle.Reset(); 277 reqs[i]->handle.Reset();
169 MessageLoop::current()->RunAllPending(); 278 MessageLoop::current()->RunAllPending();
170 released_one = true; 279 released_one = true;
171 } 280 }
172 } 281 }
173 } while (released_one); 282 } while (released_one);
174 283
175 EXPECT_EQ(kMaxSocketsPerGroup, MockClientSocket::allocation_count); 284 EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count());
176 EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count); 285 EXPECT_EQ(kNumRequests, TestSocketRequest::completion_count);
177 286
178 for (int i = 0; i < kMaxSocketsPerGroup; ++i) { 287 for (int i = 0; i < kMaxSocketsPerGroup; ++i) {
179 EXPECT_EQ(request_order_[i], reqs[i].get()) << 288 EXPECT_EQ(request_order_[i], reqs[i].get()) <<
180 "Request " << i << " was not in order."; 289 "Request " << i << " was not in order.";
181 } 290 }
182 291
183 for (int i = 0; i < kNumPendingRequests - 1; ++i) { 292 for (int i = 0; i < kNumPendingRequests - 1; ++i) {
184 int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i]; 293 int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i];
185 EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue], 294 EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue],
186 reqs[kMaxSocketsPerGroup + i].get()) << 295 reqs[kMaxSocketsPerGroup + i].get()) <<
187 "Request " << kMaxSocketsPerGroup + i << " was not in order."; 296 "Request " << kMaxSocketsPerGroup + i << " was not in order.";
188 } 297 }
189 298
190 EXPECT_EQ(request_order_[arraysize(reqs) - 1], 299 EXPECT_EQ(request_order_[arraysize(reqs) - 1],
191 reqs[arraysize(reqs) - 1].get()) << 300 reqs[arraysize(reqs) - 1].get()) <<
192 "The last request with priority 1 should not have been inserted " 301 "The last request with priority 1 should not have been inserted "
193 "earlier into the queue."; 302 "earlier into the queue.";
194 } 303 }
195 304
196 TEST_F(ClientSocketPoolTest, PendingRequests_NoKeepAlive) { 305 TEST_F(ClientSocketPoolTest, PendingRequests_NoKeepAlive) {
197 int rv; 306 scoped_ptr<TestSocketRequest> reqs[kNumRequests];
198
199 scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + kNumPendingRequests];
200 for (size_t i = 0; i < arraysize(reqs); ++i) 307 for (size_t i = 0; i < arraysize(reqs); ++i)
201 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 308 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
202 309
203 // Create connections or queue up requests. 310 // Create connections or queue up requests.
204 for (size_t i = 0; i < arraysize(reqs); ++i) { 311 for (int i = 0; i < kMaxSocketsPerGroup; ++i) {
205 rv = reqs[i]->handle.Init("a", 0, reqs[i].get()); 312 int rv = reqs[i]->handle.Init("a", "www.google.com", 80, 0, reqs[i].get());
206 if (rv != net::ERR_IO_PENDING) { 313 EXPECT_EQ(ERR_IO_PENDING, rv);
207 EXPECT_EQ(net::OK, rv); 314 EXPECT_EQ(OK, reqs[i]->WaitForResult());
208 reqs[i]->EnsureSocket(); 315 }
209 } 316
317 for (int i = 0; i < kNumPendingRequests; ++i) {
318 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init(
319 "a", "www.google.com", 80, 0, reqs[kMaxSocketsPerGroup + i].get()));
210 } 320 }
211 321
212 // Release any connections until we have no connections. 322 // Release any connections until we have no connections.
213 bool released_one; 323
214 do { 324 while (TestSocketRequest::completion_count < kNumRequests) {
215 released_one = false; 325 int num_released = 0;
216 for (size_t i = 0; i < arraysize(reqs); ++i) { 326 for (size_t i = 0; i < arraysize(reqs); ++i) {
217 if (reqs[i]->handle.is_initialized()) { 327 if (reqs[i]->handle.is_initialized()) {
218 reqs[i]->handle.socket()->Disconnect(); 328 reqs[i]->handle.socket()->Disconnect();
219 reqs[i]->handle.Reset(); 329 reqs[i]->handle.Reset();
220 MessageLoop::current()->RunAllPending(); 330 num_released++;
221 released_one = true;
222 } 331 }
223 } 332 }
224 } while (released_one); 333 int curr_num_completed = TestSocketRequest::completion_count;
334 for (int i = 0;
335 (i < num_released) && (i + curr_num_completed < kNumRequests); ++i) {
336 EXPECT_EQ(OK, reqs[i + curr_num_completed]->WaitForResult());
337 }
338 }
225 339
226 EXPECT_EQ(kMaxSocketsPerGroup + kNumPendingRequests, 340 EXPECT_EQ(kNumRequests, client_socket_factory_.allocation_count());
227 MockClientSocket::allocation_count); 341 EXPECT_EQ(kNumRequests, TestSocketRequest::completion_count);
228 EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count); 342 }
343
344 // This test will start up a RequestSocket() and then immediately Cancel() it.
345 // The pending host resolution will eventually complete, and destroy the
346 // ClientSocketPool which will crash if the group was not cleared properly.
347 TEST_F(ClientSocketPoolTest, CancelRequestClearGroup) {
348 TestSocketRequest req(pool_.get(), &request_order_);
349 EXPECT_EQ(ERR_IO_PENDING,
350 req.handle.Init("a", "www.google.com", 80, 5, &req));
351 req.handle.Reset();
352
353 PlatformThread::Sleep(100);
354
355 // There is a race condition here. If the worker pool doesn't post the task
356 // before we get here, then this might not run ConnectingSocket::OnIOComplete
357 // and therefore leak the canceled ConnectingSocket. However, other tests
358 // after this will call MessageLoop::RunAllPending() which should prevent a
359 // leak, unless the worker thread takes longer than all of them.
360 MessageLoop::current()->RunAllPending();
361 }
362
363 TEST_F(ClientSocketPoolTest, TwoRequestsCancelOne) {
364 TestSocketRequest req(pool_.get(), &request_order_);
365 TestSocketRequest req2(pool_.get(), &request_order_);
366
367 EXPECT_EQ(ERR_IO_PENDING,
368 req.handle.Init("a", "www.google.com", 80, 5, &req));
369 EXPECT_EQ(ERR_IO_PENDING,
370 req2.handle.Init("a", "www.google.com", 80, 5, &req));
371
372 req.handle.Reset();
373 PlatformThread::Sleep(100);
374
375 // There is a benign race condition here. The worker pool may or may not post
376 // the tasks before we get here. It won't test the case properly if it
377 // doesn't, but 100ms should be enough most of the time.
378 MessageLoop::current()->RunAllPending();
379
380 req2.handle.Reset();
381 // The handle's Reset method may have posted a task.
382 MessageLoop::current()->RunAllPending();
383 }
384
385 TEST_F(ClientSocketPoolTest, ConnectCancelConnect) {
386 client_socket_factory_.set_client_socket_type(
387 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
388 TestSocketRequest req(pool_.get(), &request_order_);
389
390 EXPECT_EQ(ERR_IO_PENDING,
391 req.handle.Init("a", "www.google.com", 80, 5, &req));
392
393 req.handle.Reset();
394
395 EXPECT_EQ(ERR_IO_PENDING,
396 req.handle.Init("a", "www.google.com", 80, 5, &req));
397
398 // There is a benign race condition here. The worker pool may or may not post
399 // the tasks before we get here. It won't test the case properly if it
400 // doesn't, but 100ms should be enough most of the time.
401
402 // Let the first ConnectingSocket for the handle run. This should have been
403 // canceled, so it shouldn't update the state of any Request.
404 PlatformThread::Sleep(100);
405 MessageLoop::current()->RunAllPending();
406
407 // Let the second ConnectingSocket for the handle run. If the first
408 // ConnectingSocket updated the state of any request, this will crash.
409 PlatformThread::Sleep(100);
410 MessageLoop::current()->RunAllPending();
411
412 req.handle.Reset();
413 // The handle's Reset method may have posted a task.
414 MessageLoop::current()->RunAllPending();
229 } 415 }
230 416
231 TEST_F(ClientSocketPoolTest, CancelRequest) { 417 TEST_F(ClientSocketPoolTest, CancelRequest) {
232 int rv; 418 scoped_ptr<TestSocketRequest> reqs[kNumRequests];
233
234 scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + kNumPendingRequests];
235 419
236 for (size_t i = 0; i < arraysize(reqs); ++i) 420 for (size_t i = 0; i < arraysize(reqs); ++i)
237 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 421 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
238 422
239 // Create connections or queue up requests. 423 // Create connections or queue up requests.
240 for (int i = 0; i < kMaxSocketsPerGroup; ++i) { 424 for (int i = 0; i < kMaxSocketsPerGroup; ++i) {
241 rv = reqs[i]->handle.Init("a", 5, reqs[i].get()); 425 int rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get());
242 EXPECT_EQ(net::OK, rv); 426 EXPECT_EQ(ERR_IO_PENDING, rv);
243 reqs[i]->EnsureSocket(); 427 EXPECT_EQ(OK, reqs[i]->WaitForResult());
244 } 428 }
429
245 for (int i = 0; i < kNumPendingRequests; ++i) { 430 for (int i = 0; i < kNumPendingRequests; ++i) {
246 rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( 431 int rv = reqs[kMaxSocketsPerGroup + i]->handle.Init(
247 "a", kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()); 432 "a", "www.google.com", 80, kPriorities[i],
248 EXPECT_EQ(net::ERR_IO_PENDING, rv); 433 reqs[kMaxSocketsPerGroup + i].get());
434 EXPECT_EQ(ERR_IO_PENDING, rv);
249 } 435 }
250 436
251 // Cancel a request. 437 // Cancel a request.
252 size_t index_to_cancel = kMaxSocketsPerGroup + 2; 438 size_t index_to_cancel = kMaxSocketsPerGroup + 2;
253 EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized()); 439 EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized());
254 reqs[index_to_cancel]->handle.Reset(); 440 reqs[index_to_cancel]->handle.Reset();
255 441
256 // Release any connections until we have no connections. 442 // Release any connections until we have no connections.
257 bool released_one; 443 bool released_one;
258 do { 444 do {
259 released_one = false; 445 released_one = false;
260 for (size_t i = 0; i < arraysize(reqs); ++i) { 446 for (size_t i = 0; i < arraysize(reqs); ++i) {
261 if (reqs[i]->handle.is_initialized()) { 447 if (reqs[i]->handle.is_initialized()) {
262 reqs[i]->handle.Reset(); 448 reqs[i]->handle.Reset();
263 MessageLoop::current()->RunAllPending(); 449 MessageLoop::current()->RunAllPending();
264 released_one = true; 450 released_one = true;
265 } 451 }
266 } 452 }
267 } while (released_one); 453 } while (released_one);
268 454
269 EXPECT_EQ(kMaxSocketsPerGroup, MockClientSocket::allocation_count); 455 EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count());
270 EXPECT_EQ(kNumPendingRequests - 1, TestSocketRequest::completion_count); 456 EXPECT_EQ(kNumRequests - 1, TestSocketRequest::completion_count);
271 for (int i = 0; i < kMaxSocketsPerGroup; ++i) { 457 for (int i = 0; i < kMaxSocketsPerGroup; ++i) {
272 EXPECT_EQ(request_order_[i], reqs[i].get()) << 458 EXPECT_EQ(request_order_[i], reqs[i].get()) <<
273 "Request " << i << " was not in order."; 459 "Request " << i << " was not in order.";
274 } 460 }
275 461
276 for (int i = 0; i < kNumPendingRequests - 1; ++i) { 462 for (int i = 0; i < kNumPendingRequests - 1; ++i) {
277 if (i == 2) continue; 463 if (i == 2) continue;
278 int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i]; 464 int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i];
279 if (kPriorities[i] < kPriorities[index_to_cancel - kMaxSocketsPerGroup]) 465 if (kPriorities[i] < kPriorities[index_to_cancel - kMaxSocketsPerGroup])
280 index_in_queue--; 466 index_in_queue--;
281 EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue], 467 EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue],
282 reqs[kMaxSocketsPerGroup + i].get()) << 468 reqs[kMaxSocketsPerGroup + i].get()) <<
283 "Request " << kMaxSocketsPerGroup + i << " was not in order."; 469 "Request " << kMaxSocketsPerGroup + i << " was not in order.";
284 } 470 }
285 471
286 EXPECT_EQ(request_order_[arraysize(reqs) - 2], 472 EXPECT_EQ(request_order_[arraysize(reqs) - 2],
287 reqs[arraysize(reqs) - 1].get()) << 473 reqs[arraysize(reqs) - 1].get()) <<
288 "The last request with priority 1 should not have been inserted " 474 "The last request with priority 1 should not have been inserted "
289 "earlier into the queue."; 475 "earlier into the queue.";
290 } 476 }
291 477
292 } // namespace 478 } // namespace
479
480 } // namespace net
OLDNEW
« no previous file with comments | « net/base/client_socket_pool.cc ('k') | net/base/test_completion_callback.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698