OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/socket/socket_test_util.h" | |
6 | |
7 #include <algorithm> | |
8 #include <vector> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/bind.h" | |
12 #include "base/bind_helpers.h" | |
13 #include "base/callback_helpers.h" | |
14 #include "base/compiler_specific.h" | |
15 #include "base/message_loop/message_loop.h" | |
16 #include "base/run_loop.h" | |
17 #include "base/time/time.h" | |
18 #include "net/base/address_family.h" | |
19 #include "net/base/address_list.h" | |
20 #include "net/base/auth.h" | |
21 #include "net/base/load_timing_info.h" | |
22 #include "net/http/http_network_session.h" | |
23 #include "net/http/http_request_headers.h" | |
24 #include "net/http/http_response_headers.h" | |
25 #include "net/socket/client_socket_pool_histograms.h" | |
26 #include "net/socket/socket.h" | |
27 #include "net/socket/websocket_endpoint_lock_manager.h" | |
28 #include "net/ssl/ssl_cert_request_info.h" | |
29 #include "net/ssl/ssl_connection_status_flags.h" | |
30 #include "net/ssl/ssl_info.h" | |
31 #include "testing/gtest/include/gtest/gtest.h" | |
32 | |
33 // Socket events are easier to debug if you log individual reads and writes. | |
34 // Enable these if locally debugging, but they are too noisy for the waterfall. | |
35 #if 0 | |
36 #define NET_TRACE(level, s) DLOG(level) << s << __FUNCTION__ << "() " | |
37 #else | |
38 #define NET_TRACE(level, s) EAT_STREAM_PARAMETERS | |
39 #endif | |
40 | |
41 namespace net { | |
42 | |
43 namespace { | |
44 | |
45 inline char AsciifyHigh(char x) { | |
46 char nybble = static_cast<char>((x >> 4) & 0x0F); | |
47 return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10); | |
48 } | |
49 | |
50 inline char AsciifyLow(char x) { | |
51 char nybble = static_cast<char>((x >> 0) & 0x0F); | |
52 return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10); | |
53 } | |
54 | |
55 inline char Asciify(char x) { | |
56 if ((x < 0) || !isprint(x)) | |
57 return '.'; | |
58 return x; | |
59 } | |
60 | |
61 void DumpData(const char* data, int data_len) { | |
62 if (logging::LOG_INFO < logging::GetMinLogLevel()) | |
63 return; | |
64 DVLOG(1) << "Length: " << data_len; | |
65 const char* pfx = "Data: "; | |
66 if (!data || (data_len <= 0)) { | |
67 DVLOG(1) << pfx << "<None>"; | |
68 } else { | |
69 int i; | |
70 for (i = 0; i <= (data_len - 4); i += 4) { | |
71 DVLOG(1) << pfx | |
72 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
73 << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1]) | |
74 << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2]) | |
75 << AsciifyHigh(data[i + 3]) << AsciifyLow(data[i + 3]) | |
76 << " '" | |
77 << Asciify(data[i + 0]) | |
78 << Asciify(data[i + 1]) | |
79 << Asciify(data[i + 2]) | |
80 << Asciify(data[i + 3]) | |
81 << "'"; | |
82 pfx = " "; | |
83 } | |
84 // Take care of any 'trailing' bytes, if data_len was not a multiple of 4. | |
85 switch (data_len - i) { | |
86 case 3: | |
87 DVLOG(1) << pfx | |
88 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
89 << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1]) | |
90 << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2]) | |
91 << " '" | |
92 << Asciify(data[i + 0]) | |
93 << Asciify(data[i + 1]) | |
94 << Asciify(data[i + 2]) | |
95 << " '"; | |
96 break; | |
97 case 2: | |
98 DVLOG(1) << pfx | |
99 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
100 << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1]) | |
101 << " '" | |
102 << Asciify(data[i + 0]) | |
103 << Asciify(data[i + 1]) | |
104 << " '"; | |
105 break; | |
106 case 1: | |
107 DVLOG(1) << pfx | |
108 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
109 << " '" | |
110 << Asciify(data[i + 0]) | |
111 << " '"; | |
112 break; | |
113 } | |
114 } | |
115 } | |
116 | |
117 template <MockReadWriteType type> | |
118 void DumpMockReadWrite(const MockReadWrite<type>& r) { | |
119 if (logging::LOG_INFO < logging::GetMinLogLevel()) | |
120 return; | |
121 DVLOG(1) << "Async: " << (r.mode == ASYNC) | |
122 << "\nResult: " << r.result; | |
123 DumpData(r.data, r.data_len); | |
124 const char* stop = (r.sequence_number & MockRead::STOPLOOP) ? " (STOP)" : ""; | |
125 DVLOG(1) << "Stage: " << (r.sequence_number & ~MockRead::STOPLOOP) << stop | |
126 << "\nTime: " << r.time_stamp.ToInternalValue(); | |
127 } | |
128 | |
129 } // namespace | |
130 | |
131 MockConnect::MockConnect() : mode(ASYNC), result(OK) { | |
132 IPAddressNumber ip; | |
133 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | |
134 peer_addr = IPEndPoint(ip, 0); | |
135 } | |
136 | |
137 MockConnect::MockConnect(IoMode io_mode, int r) : mode(io_mode), result(r) { | |
138 IPAddressNumber ip; | |
139 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | |
140 peer_addr = IPEndPoint(ip, 0); | |
141 } | |
142 | |
143 MockConnect::MockConnect(IoMode io_mode, int r, IPEndPoint addr) : | |
144 mode(io_mode), | |
145 result(r), | |
146 peer_addr(addr) { | |
147 } | |
148 | |
149 MockConnect::~MockConnect() {} | |
150 | |
151 StaticSocketDataProvider::StaticSocketDataProvider() | |
152 : reads_(NULL), | |
153 read_index_(0), | |
154 read_count_(0), | |
155 writes_(NULL), | |
156 write_index_(0), | |
157 write_count_(0) { | |
158 } | |
159 | |
160 StaticSocketDataProvider::StaticSocketDataProvider(MockRead* reads, | |
161 size_t reads_count, | |
162 MockWrite* writes, | |
163 size_t writes_count) | |
164 : reads_(reads), | |
165 read_index_(0), | |
166 read_count_(reads_count), | |
167 writes_(writes), | |
168 write_index_(0), | |
169 write_count_(writes_count) { | |
170 } | |
171 | |
172 StaticSocketDataProvider::~StaticSocketDataProvider() {} | |
173 | |
174 const MockRead& StaticSocketDataProvider::PeekRead() const { | |
175 CHECK(!at_read_eof()); | |
176 return reads_[read_index_]; | |
177 } | |
178 | |
179 const MockWrite& StaticSocketDataProvider::PeekWrite() const { | |
180 CHECK(!at_write_eof()); | |
181 return writes_[write_index_]; | |
182 } | |
183 | |
184 const MockRead& StaticSocketDataProvider::PeekRead(size_t index) const { | |
185 CHECK_LT(index, read_count_); | |
186 return reads_[index]; | |
187 } | |
188 | |
189 const MockWrite& StaticSocketDataProvider::PeekWrite(size_t index) const { | |
190 CHECK_LT(index, write_count_); | |
191 return writes_[index]; | |
192 } | |
193 | |
194 MockRead StaticSocketDataProvider::GetNextRead() { | |
195 CHECK(!at_read_eof()); | |
196 reads_[read_index_].time_stamp = base::Time::Now(); | |
197 return reads_[read_index_++]; | |
198 } | |
199 | |
200 MockWriteResult StaticSocketDataProvider::OnWrite(const std::string& data) { | |
201 if (!writes_) { | |
202 // Not using mock writes; succeed synchronously. | |
203 return MockWriteResult(SYNCHRONOUS, data.length()); | |
204 } | |
205 EXPECT_FALSE(at_write_eof()); | |
206 if (at_write_eof()) { | |
207 // Show what the extra write actually consists of. | |
208 EXPECT_EQ("<unexpected write>", data); | |
209 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
210 } | |
211 | |
212 // Check that what we are writing matches the expectation. | |
213 // Then give the mocked return value. | |
214 MockWrite* w = &writes_[write_index_++]; | |
215 w->time_stamp = base::Time::Now(); | |
216 int result = w->result; | |
217 if (w->data) { | |
218 // Note - we can simulate a partial write here. If the expected data | |
219 // is a match, but shorter than the write actually written, that is legal. | |
220 // Example: | |
221 // Application writes "foobarbaz" (9 bytes) | |
222 // Expected write was "foo" (3 bytes) | |
223 // This is a success, and we return 3 to the application. | |
224 std::string expected_data(w->data, w->data_len); | |
225 EXPECT_GE(data.length(), expected_data.length()); | |
226 std::string actual_data(data.substr(0, w->data_len)); | |
227 EXPECT_EQ(expected_data, actual_data); | |
228 if (expected_data != actual_data) | |
229 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
230 if (result == OK) | |
231 result = w->data_len; | |
232 } | |
233 return MockWriteResult(w->mode, result); | |
234 } | |
235 | |
236 void StaticSocketDataProvider::Reset() { | |
237 read_index_ = 0; | |
238 write_index_ = 0; | |
239 } | |
240 | |
241 DynamicSocketDataProvider::DynamicSocketDataProvider() | |
242 : short_read_limit_(0), | |
243 allow_unconsumed_reads_(false) { | |
244 } | |
245 | |
246 DynamicSocketDataProvider::~DynamicSocketDataProvider() {} | |
247 | |
248 MockRead DynamicSocketDataProvider::GetNextRead() { | |
249 if (reads_.empty()) | |
250 return MockRead(SYNCHRONOUS, ERR_UNEXPECTED); | |
251 MockRead result = reads_.front(); | |
252 if (short_read_limit_ == 0 || result.data_len <= short_read_limit_) { | |
253 reads_.pop_front(); | |
254 } else { | |
255 result.data_len = short_read_limit_; | |
256 reads_.front().data += result.data_len; | |
257 reads_.front().data_len -= result.data_len; | |
258 } | |
259 return result; | |
260 } | |
261 | |
262 void DynamicSocketDataProvider::Reset() { | |
263 reads_.clear(); | |
264 } | |
265 | |
266 void DynamicSocketDataProvider::SimulateRead(const char* data, | |
267 const size_t length) { | |
268 if (!allow_unconsumed_reads_) { | |
269 EXPECT_TRUE(reads_.empty()) << "Unconsumed read: " << reads_.front().data; | |
270 } | |
271 reads_.push_back(MockRead(ASYNC, data, length)); | |
272 } | |
273 | |
274 SSLSocketDataProvider::SSLSocketDataProvider(IoMode mode, int result) | |
275 : connect(mode, result), | |
276 next_proto_status(SSLClientSocket::kNextProtoUnsupported), | |
277 was_npn_negotiated(false), | |
278 protocol_negotiated(kProtoUnknown), | |
279 client_cert_sent(false), | |
280 cert_request_info(NULL), | |
281 channel_id_sent(false), | |
282 connection_status(0), | |
283 should_pause_on_connect(false), | |
284 is_in_session_cache(false) { | |
285 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, | |
286 &connection_status); | |
287 // Set to TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 | |
288 SSLConnectionStatusSetCipherSuite(0xcc14, &connection_status); | |
289 } | |
290 | |
291 SSLSocketDataProvider::~SSLSocketDataProvider() { | |
292 } | |
293 | |
294 void SSLSocketDataProvider::SetNextProto(NextProto proto) { | |
295 was_npn_negotiated = true; | |
296 next_proto_status = SSLClientSocket::kNextProtoNegotiated; | |
297 protocol_negotiated = proto; | |
298 next_proto = SSLClientSocket::NextProtoToString(proto); | |
299 } | |
300 | |
301 DelayedSocketData::DelayedSocketData( | |
302 int write_delay, MockRead* reads, size_t reads_count, | |
303 MockWrite* writes, size_t writes_count) | |
304 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
305 write_delay_(write_delay), | |
306 read_in_progress_(false), | |
307 weak_factory_(this) { | |
308 DCHECK_GE(write_delay_, 0); | |
309 } | |
310 | |
311 DelayedSocketData::DelayedSocketData( | |
312 const MockConnect& connect, int write_delay, MockRead* reads, | |
313 size_t reads_count, MockWrite* writes, size_t writes_count) | |
314 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
315 write_delay_(write_delay), | |
316 read_in_progress_(false), | |
317 weak_factory_(this) { | |
318 DCHECK_GE(write_delay_, 0); | |
319 set_connect_data(connect); | |
320 } | |
321 | |
322 DelayedSocketData::~DelayedSocketData() { | |
323 } | |
324 | |
325 void DelayedSocketData::ForceNextRead() { | |
326 DCHECK(read_in_progress_); | |
327 write_delay_ = 0; | |
328 CompleteRead(); | |
329 } | |
330 | |
331 MockRead DelayedSocketData::GetNextRead() { | |
332 MockRead out = MockRead(ASYNC, ERR_IO_PENDING); | |
333 if (write_delay_ <= 0) | |
334 out = StaticSocketDataProvider::GetNextRead(); | |
335 read_in_progress_ = (out.result == ERR_IO_PENDING); | |
336 return out; | |
337 } | |
338 | |
339 MockWriteResult DelayedSocketData::OnWrite(const std::string& data) { | |
340 MockWriteResult rv = StaticSocketDataProvider::OnWrite(data); | |
341 // Now that our write has completed, we can allow reads to continue. | |
342 if (!--write_delay_ && read_in_progress_) | |
343 base::MessageLoop::current()->PostDelayedTask( | |
344 FROM_HERE, | |
345 base::Bind(&DelayedSocketData::CompleteRead, | |
346 weak_factory_.GetWeakPtr()), | |
347 base::TimeDelta::FromMilliseconds(100)); | |
348 return rv; | |
349 } | |
350 | |
351 void DelayedSocketData::Reset() { | |
352 set_socket(NULL); | |
353 read_in_progress_ = false; | |
354 weak_factory_.InvalidateWeakPtrs(); | |
355 StaticSocketDataProvider::Reset(); | |
356 } | |
357 | |
358 void DelayedSocketData::CompleteRead() { | |
359 if (socket() && read_in_progress_) | |
360 socket()->OnReadComplete(GetNextRead()); | |
361 } | |
362 | |
363 OrderedSocketData::OrderedSocketData( | |
364 MockRead* reads, size_t reads_count, MockWrite* writes, size_t writes_count) | |
365 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
366 sequence_number_(0), loop_stop_stage_(0), | |
367 blocked_(false), weak_factory_(this) { | |
368 } | |
369 | |
370 OrderedSocketData::OrderedSocketData( | |
371 const MockConnect& connect, | |
372 MockRead* reads, size_t reads_count, | |
373 MockWrite* writes, size_t writes_count) | |
374 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
375 sequence_number_(0), loop_stop_stage_(0), | |
376 blocked_(false), weak_factory_(this) { | |
377 set_connect_data(connect); | |
378 } | |
379 | |
380 void OrderedSocketData::EndLoop() { | |
381 // If we've already stopped the loop, don't do it again until we've advanced | |
382 // to the next sequence_number. | |
383 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ << ": EndLoop()"; | |
384 if (loop_stop_stage_ > 0) { | |
385 const MockRead& next_read = StaticSocketDataProvider::PeekRead(); | |
386 if ((next_read.sequence_number & ~MockRead::STOPLOOP) > | |
387 loop_stop_stage_) { | |
388 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
389 << ": Clearing stop index"; | |
390 loop_stop_stage_ = 0; | |
391 } else { | |
392 return; | |
393 } | |
394 } | |
395 // Record the sequence_number at which we stopped the loop. | |
396 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
397 << ": Posting Quit at read " << read_index(); | |
398 loop_stop_stage_ = sequence_number_; | |
399 } | |
400 | |
401 MockRead OrderedSocketData::GetNextRead() { | |
402 weak_factory_.InvalidateWeakPtrs(); | |
403 blocked_ = false; | |
404 const MockRead& next_read = StaticSocketDataProvider::PeekRead(); | |
405 if (next_read.sequence_number & MockRead::STOPLOOP) | |
406 EndLoop(); | |
407 if ((next_read.sequence_number & ~MockRead::STOPLOOP) <= | |
408 sequence_number_++) { | |
409 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1 | |
410 << ": Read " << read_index(); | |
411 DumpMockReadWrite(next_read); | |
412 blocked_ = (next_read.result == ERR_IO_PENDING); | |
413 return StaticSocketDataProvider::GetNextRead(); | |
414 } | |
415 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1 | |
416 << ": I/O Pending"; | |
417 MockRead result = MockRead(ASYNC, ERR_IO_PENDING); | |
418 DumpMockReadWrite(result); | |
419 blocked_ = true; | |
420 return result; | |
421 } | |
422 | |
423 MockWriteResult OrderedSocketData::OnWrite(const std::string& data) { | |
424 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
425 << ": Write " << write_index(); | |
426 DumpMockReadWrite(PeekWrite()); | |
427 ++sequence_number_; | |
428 if (blocked_) { | |
429 // TODO(willchan): This 100ms delay seems to work around some weirdness. We | |
430 // should probably fix the weirdness. One example is in SpdyStream, | |
431 // DoSendRequest() will return ERR_IO_PENDING, and there's a race. If the | |
432 // SYN_REPLY causes OnResponseReceived() to get called before | |
433 // SpdyStream::ReadResponseHeaders() is called, we hit a NOTREACHED(). | |
434 base::MessageLoop::current()->PostDelayedTask( | |
435 FROM_HERE, | |
436 base::Bind(&OrderedSocketData::CompleteRead, | |
437 weak_factory_.GetWeakPtr()), | |
438 base::TimeDelta::FromMilliseconds(100)); | |
439 } | |
440 return StaticSocketDataProvider::OnWrite(data); | |
441 } | |
442 | |
443 void OrderedSocketData::Reset() { | |
444 NET_TRACE(INFO, " *** ") << "Stage " | |
445 << sequence_number_ << ": Reset()"; | |
446 sequence_number_ = 0; | |
447 loop_stop_stage_ = 0; | |
448 set_socket(NULL); | |
449 weak_factory_.InvalidateWeakPtrs(); | |
450 StaticSocketDataProvider::Reset(); | |
451 } | |
452 | |
453 void OrderedSocketData::CompleteRead() { | |
454 if (socket() && blocked_) { | |
455 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_; | |
456 socket()->OnReadComplete(GetNextRead()); | |
457 } | |
458 } | |
459 | |
460 OrderedSocketData::~OrderedSocketData() {} | |
461 | |
462 DeterministicSocketData::DeterministicSocketData(MockRead* reads, | |
463 size_t reads_count, MockWrite* writes, size_t writes_count) | |
464 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
465 sequence_number_(0), | |
466 current_read_(), | |
467 current_write_(), | |
468 stopping_sequence_number_(0), | |
469 stopped_(false), | |
470 print_debug_(false), | |
471 is_running_(false) { | |
472 VerifyCorrectSequenceNumbers(reads, reads_count, writes, writes_count); | |
473 } | |
474 | |
475 DeterministicSocketData::~DeterministicSocketData() {} | |
476 | |
477 void DeterministicSocketData::Run() { | |
478 DCHECK(!is_running_); | |
479 is_running_ = true; | |
480 | |
481 SetStopped(false); | |
482 int counter = 0; | |
483 // Continue to consume data until all data has run out, or the stopped_ flag | |
484 // has been set. Consuming data requires two separate operations -- running | |
485 // the tasks in the message loop, and explicitly invoking the read/write | |
486 // callbacks (simulating network I/O). We check our conditions between each, | |
487 // since they can change in either. | |
488 while ((!at_write_eof() || !at_read_eof()) && !stopped()) { | |
489 if (counter % 2 == 0) | |
490 base::RunLoop().RunUntilIdle(); | |
491 if (counter % 2 == 1) { | |
492 InvokeCallbacks(); | |
493 } | |
494 counter++; | |
495 } | |
496 // We're done consuming new data, but it is possible there are still some | |
497 // pending callbacks which we expect to complete before returning. | |
498 while (delegate_.get() && | |
499 (delegate_->WritePending() || delegate_->ReadPending()) && | |
500 !stopped()) { | |
501 InvokeCallbacks(); | |
502 base::RunLoop().RunUntilIdle(); | |
503 } | |
504 SetStopped(false); | |
505 is_running_ = false; | |
506 } | |
507 | |
508 void DeterministicSocketData::RunFor(int steps) { | |
509 StopAfter(steps); | |
510 Run(); | |
511 } | |
512 | |
513 void DeterministicSocketData::SetStop(int seq) { | |
514 DCHECK_LT(sequence_number_, seq); | |
515 stopping_sequence_number_ = seq; | |
516 stopped_ = false; | |
517 } | |
518 | |
519 void DeterministicSocketData::StopAfter(int seq) { | |
520 SetStop(sequence_number_ + seq); | |
521 } | |
522 | |
523 MockRead DeterministicSocketData::GetNextRead() { | |
524 current_read_ = StaticSocketDataProvider::PeekRead(); | |
525 | |
526 // Synchronous read while stopped is an error | |
527 if (stopped() && current_read_.mode == SYNCHRONOUS) { | |
528 LOG(ERROR) << "Unable to perform synchronous IO while stopped"; | |
529 return MockRead(SYNCHRONOUS, ERR_UNEXPECTED); | |
530 } | |
531 | |
532 // Async read which will be called back in a future step. | |
533 if (sequence_number_ < current_read_.sequence_number) { | |
534 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
535 << ": I/O Pending"; | |
536 MockRead result = MockRead(SYNCHRONOUS, ERR_IO_PENDING); | |
537 if (current_read_.mode == SYNCHRONOUS) { | |
538 LOG(ERROR) << "Unable to perform synchronous read: " | |
539 << current_read_.sequence_number | |
540 << " at stage: " << sequence_number_; | |
541 result = MockRead(SYNCHRONOUS, ERR_UNEXPECTED); | |
542 } | |
543 if (print_debug_) | |
544 DumpMockReadWrite(result); | |
545 return result; | |
546 } | |
547 | |
548 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
549 << ": Read " << read_index(); | |
550 if (print_debug_) | |
551 DumpMockReadWrite(current_read_); | |
552 | |
553 // Increment the sequence number if IO is complete | |
554 if (current_read_.mode == SYNCHRONOUS) | |
555 NextStep(); | |
556 | |
557 DCHECK_NE(ERR_IO_PENDING, current_read_.result); | |
558 StaticSocketDataProvider::GetNextRead(); | |
559 | |
560 return current_read_; | |
561 } | |
562 | |
563 MockWriteResult DeterministicSocketData::OnWrite(const std::string& data) { | |
564 const MockWrite& next_write = StaticSocketDataProvider::PeekWrite(); | |
565 current_write_ = next_write; | |
566 | |
567 // Synchronous write while stopped is an error | |
568 if (stopped() && next_write.mode == SYNCHRONOUS) { | |
569 LOG(ERROR) << "Unable to perform synchronous IO while stopped"; | |
570 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
571 } | |
572 | |
573 // Async write which will be called back in a future step. | |
574 if (sequence_number_ < next_write.sequence_number) { | |
575 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
576 << ": I/O Pending"; | |
577 if (next_write.mode == SYNCHRONOUS) { | |
578 LOG(ERROR) << "Unable to perform synchronous write: " | |
579 << next_write.sequence_number << " at stage: " << sequence_number_; | |
580 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
581 } | |
582 } else { | |
583 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
584 << ": Write " << write_index(); | |
585 } | |
586 | |
587 if (print_debug_) | |
588 DumpMockReadWrite(next_write); | |
589 | |
590 // Move to the next step if I/O is synchronous, since the operation will | |
591 // complete when this method returns. | |
592 if (next_write.mode == SYNCHRONOUS) | |
593 NextStep(); | |
594 | |
595 // This is either a sync write for this step, or an async write. | |
596 return StaticSocketDataProvider::OnWrite(data); | |
597 } | |
598 | |
599 void DeterministicSocketData::Reset() { | |
600 NET_TRACE(INFO, " *** ") << "Stage " | |
601 << sequence_number_ << ": Reset()"; | |
602 sequence_number_ = 0; | |
603 StaticSocketDataProvider::Reset(); | |
604 NOTREACHED(); | |
605 } | |
606 | |
607 void DeterministicSocketData::InvokeCallbacks() { | |
608 if (delegate_.get() && delegate_->WritePending() && | |
609 (current_write().sequence_number == sequence_number())) { | |
610 NextStep(); | |
611 delegate_->CompleteWrite(); | |
612 return; | |
613 } | |
614 if (delegate_.get() && delegate_->ReadPending() && | |
615 (current_read().sequence_number == sequence_number())) { | |
616 NextStep(); | |
617 delegate_->CompleteRead(); | |
618 return; | |
619 } | |
620 } | |
621 | |
622 void DeterministicSocketData::NextStep() { | |
623 // Invariant: Can never move *past* the stopping step. | |
624 DCHECK_LT(sequence_number_, stopping_sequence_number_); | |
625 sequence_number_++; | |
626 if (sequence_number_ == stopping_sequence_number_) | |
627 SetStopped(true); | |
628 } | |
629 | |
630 void DeterministicSocketData::VerifyCorrectSequenceNumbers( | |
631 MockRead* reads, size_t reads_count, | |
632 MockWrite* writes, size_t writes_count) { | |
633 size_t read = 0; | |
634 size_t write = 0; | |
635 int expected = 0; | |
636 while (read < reads_count || write < writes_count) { | |
637 // Check to see that we have a read or write at the expected | |
638 // state. | |
639 if (read < reads_count && reads[read].sequence_number == expected) { | |
640 ++read; | |
641 ++expected; | |
642 continue; | |
643 } | |
644 if (write < writes_count && writes[write].sequence_number == expected) { | |
645 ++write; | |
646 ++expected; | |
647 continue; | |
648 } | |
649 NOTREACHED() << "Missing sequence number: " << expected; | |
650 return; | |
651 } | |
652 DCHECK_EQ(read, reads_count); | |
653 DCHECK_EQ(write, writes_count); | |
654 } | |
655 | |
656 MockClientSocketFactory::MockClientSocketFactory() {} | |
657 | |
658 MockClientSocketFactory::~MockClientSocketFactory() {} | |
659 | |
660 void MockClientSocketFactory::AddSocketDataProvider( | |
661 SocketDataProvider* data) { | |
662 mock_data_.Add(data); | |
663 } | |
664 | |
665 void MockClientSocketFactory::AddSSLSocketDataProvider( | |
666 SSLSocketDataProvider* data) { | |
667 mock_ssl_data_.Add(data); | |
668 } | |
669 | |
670 void MockClientSocketFactory::ResetNextMockIndexes() { | |
671 mock_data_.ResetNextIndex(); | |
672 mock_ssl_data_.ResetNextIndex(); | |
673 } | |
674 | |
675 scoped_ptr<DatagramClientSocket> | |
676 MockClientSocketFactory::CreateDatagramClientSocket( | |
677 DatagramSocket::BindType bind_type, | |
678 const RandIntCallback& rand_int_cb, | |
679 net::NetLog* net_log, | |
680 const net::NetLog::Source& source) { | |
681 SocketDataProvider* data_provider = mock_data_.GetNext(); | |
682 scoped_ptr<MockUDPClientSocket> socket( | |
683 new MockUDPClientSocket(data_provider, net_log)); | |
684 data_provider->set_socket(socket.get()); | |
685 if (bind_type == DatagramSocket::RANDOM_BIND) | |
686 socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535))); | |
687 return socket.Pass(); | |
688 } | |
689 | |
690 scoped_ptr<StreamSocket> MockClientSocketFactory::CreateTransportClientSocket( | |
691 const AddressList& addresses, | |
692 net::NetLog* net_log, | |
693 const net::NetLog::Source& source) { | |
694 SocketDataProvider* data_provider = mock_data_.GetNext(); | |
695 scoped_ptr<MockTCPClientSocket> socket( | |
696 new MockTCPClientSocket(addresses, net_log, data_provider)); | |
697 data_provider->set_socket(socket.get()); | |
698 return socket.Pass(); | |
699 } | |
700 | |
701 scoped_ptr<SSLClientSocket> MockClientSocketFactory::CreateSSLClientSocket( | |
702 scoped_ptr<ClientSocketHandle> transport_socket, | |
703 const HostPortPair& host_and_port, | |
704 const SSLConfig& ssl_config, | |
705 const SSLClientSocketContext& context) { | |
706 SSLSocketDataProvider* next_ssl_data = mock_ssl_data_.GetNext(); | |
707 if (!next_ssl_data->next_protos_expected_in_ssl_config.empty()) { | |
708 EXPECT_EQ(next_ssl_data->next_protos_expected_in_ssl_config.size(), | |
709 ssl_config.next_protos.size()); | |
710 EXPECT_TRUE( | |
711 std::equal(next_ssl_data->next_protos_expected_in_ssl_config.begin(), | |
712 next_ssl_data->next_protos_expected_in_ssl_config.end(), | |
713 ssl_config.next_protos.begin())); | |
714 } | |
715 scoped_ptr<MockSSLClientSocket> socket(new MockSSLClientSocket( | |
716 transport_socket.Pass(), host_and_port, ssl_config, next_ssl_data)); | |
717 ssl_client_sockets_.push_back(socket.get()); | |
718 return socket.Pass(); | |
719 } | |
720 | |
721 void MockClientSocketFactory::ClearSSLSessionCache() { | |
722 } | |
723 | |
724 const char MockClientSocket::kTlsUnique[] = "MOCK_TLSUNIQ"; | |
725 | |
726 MockClientSocket::MockClientSocket(const BoundNetLog& net_log) | |
727 : connected_(false), | |
728 net_log_(net_log), | |
729 weak_factory_(this) { | |
730 IPAddressNumber ip; | |
731 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | |
732 peer_addr_ = IPEndPoint(ip, 0); | |
733 } | |
734 | |
735 int MockClientSocket::SetReceiveBufferSize(int32 size) { | |
736 return OK; | |
737 } | |
738 | |
739 int MockClientSocket::SetSendBufferSize(int32 size) { | |
740 return OK; | |
741 } | |
742 | |
743 void MockClientSocket::Disconnect() { | |
744 connected_ = false; | |
745 } | |
746 | |
747 bool MockClientSocket::IsConnected() const { | |
748 return connected_; | |
749 } | |
750 | |
751 bool MockClientSocket::IsConnectedAndIdle() const { | |
752 return connected_; | |
753 } | |
754 | |
755 int MockClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
756 if (!IsConnected()) | |
757 return ERR_SOCKET_NOT_CONNECTED; | |
758 *address = peer_addr_; | |
759 return OK; | |
760 } | |
761 | |
762 int MockClientSocket::GetLocalAddress(IPEndPoint* address) const { | |
763 IPAddressNumber ip; | |
764 bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); | |
765 CHECK(rv); | |
766 *address = IPEndPoint(ip, 123); | |
767 return OK; | |
768 } | |
769 | |
770 const BoundNetLog& MockClientSocket::NetLog() const { | |
771 return net_log_; | |
772 } | |
773 | |
774 std::string MockClientSocket::GetSessionCacheKey() const { | |
775 NOTIMPLEMENTED(); | |
776 return std::string(); | |
777 } | |
778 | |
779 bool MockClientSocket::InSessionCache() const { | |
780 NOTIMPLEMENTED(); | |
781 return false; | |
782 } | |
783 | |
784 void MockClientSocket::SetHandshakeCompletionCallback(const base::Closure& cb) { | |
785 NOTIMPLEMENTED(); | |
786 } | |
787 | |
788 void MockClientSocket::GetSSLCertRequestInfo( | |
789 SSLCertRequestInfo* cert_request_info) { | |
790 } | |
791 | |
792 int MockClientSocket::ExportKeyingMaterial(const base::StringPiece& label, | |
793 bool has_context, | |
794 const base::StringPiece& context, | |
795 unsigned char* out, | |
796 unsigned int outlen) { | |
797 memset(out, 'A', outlen); | |
798 return OK; | |
799 } | |
800 | |
801 int MockClientSocket::GetTLSUniqueChannelBinding(std::string* out) { | |
802 out->assign(MockClientSocket::kTlsUnique); | |
803 return OK; | |
804 } | |
805 | |
806 ChannelIDService* MockClientSocket::GetChannelIDService() const { | |
807 NOTREACHED(); | |
808 return NULL; | |
809 } | |
810 | |
811 SSLClientSocket::NextProtoStatus | |
812 MockClientSocket::GetNextProto(std::string* proto) { | |
813 proto->clear(); | |
814 return SSLClientSocket::kNextProtoUnsupported; | |
815 } | |
816 | |
817 scoped_refptr<X509Certificate> | |
818 MockClientSocket::GetUnverifiedServerCertificateChain() const { | |
819 NOTREACHED(); | |
820 return NULL; | |
821 } | |
822 | |
823 MockClientSocket::~MockClientSocket() {} | |
824 | |
825 void MockClientSocket::RunCallbackAsync(const CompletionCallback& callback, | |
826 int result) { | |
827 base::MessageLoop::current()->PostTask( | |
828 FROM_HERE, | |
829 base::Bind(&MockClientSocket::RunCallback, | |
830 weak_factory_.GetWeakPtr(), | |
831 callback, | |
832 result)); | |
833 } | |
834 | |
835 void MockClientSocket::RunCallback(const net::CompletionCallback& callback, | |
836 int result) { | |
837 if (!callback.is_null()) | |
838 callback.Run(result); | |
839 } | |
840 | |
841 MockTCPClientSocket::MockTCPClientSocket(const AddressList& addresses, | |
842 net::NetLog* net_log, | |
843 SocketDataProvider* data) | |
844 : MockClientSocket(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)), | |
845 addresses_(addresses), | |
846 data_(data), | |
847 read_offset_(0), | |
848 read_data_(SYNCHRONOUS, ERR_UNEXPECTED), | |
849 need_read_data_(true), | |
850 peer_closed_connection_(false), | |
851 pending_buf_(NULL), | |
852 pending_buf_len_(0), | |
853 was_used_to_convey_data_(false) { | |
854 DCHECK(data_); | |
855 peer_addr_ = data->connect_data().peer_addr; | |
856 data_->Reset(); | |
857 } | |
858 | |
859 MockTCPClientSocket::~MockTCPClientSocket() {} | |
860 | |
861 int MockTCPClientSocket::Read(IOBuffer* buf, int buf_len, | |
862 const CompletionCallback& callback) { | |
863 if (!connected_) | |
864 return ERR_UNEXPECTED; | |
865 | |
866 // If the buffer is already in use, a read is already in progress! | |
867 DCHECK(pending_buf_.get() == NULL); | |
868 | |
869 // Store our async IO data. | |
870 pending_buf_ = buf; | |
871 pending_buf_len_ = buf_len; | |
872 pending_callback_ = callback; | |
873 | |
874 if (need_read_data_) { | |
875 read_data_ = data_->GetNextRead(); | |
876 if (read_data_.result == ERR_CONNECTION_CLOSED) { | |
877 // This MockRead is just a marker to instruct us to set | |
878 // peer_closed_connection_. | |
879 peer_closed_connection_ = true; | |
880 } | |
881 if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { | |
882 // This MockRead is just a marker to instruct us to set | |
883 // peer_closed_connection_. Skip it and get the next one. | |
884 read_data_ = data_->GetNextRead(); | |
885 peer_closed_connection_ = true; | |
886 } | |
887 // ERR_IO_PENDING means that the SocketDataProvider is taking responsibility | |
888 // to complete the async IO manually later (via OnReadComplete). | |
889 if (read_data_.result == ERR_IO_PENDING) { | |
890 // We need to be using async IO in this case. | |
891 DCHECK(!callback.is_null()); | |
892 return ERR_IO_PENDING; | |
893 } | |
894 need_read_data_ = false; | |
895 } | |
896 | |
897 return CompleteRead(); | |
898 } | |
899 | |
900 int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len, | |
901 const CompletionCallback& callback) { | |
902 DCHECK(buf); | |
903 DCHECK_GT(buf_len, 0); | |
904 | |
905 if (!connected_) | |
906 return ERR_UNEXPECTED; | |
907 | |
908 std::string data(buf->data(), buf_len); | |
909 MockWriteResult write_result = data_->OnWrite(data); | |
910 | |
911 was_used_to_convey_data_ = true; | |
912 | |
913 if (write_result.mode == ASYNC) { | |
914 RunCallbackAsync(callback, write_result.result); | |
915 return ERR_IO_PENDING; | |
916 } | |
917 | |
918 return write_result.result; | |
919 } | |
920 | |
921 int MockTCPClientSocket::Connect(const CompletionCallback& callback) { | |
922 if (connected_) | |
923 return OK; | |
924 connected_ = true; | |
925 peer_closed_connection_ = false; | |
926 if (data_->connect_data().mode == ASYNC) { | |
927 if (data_->connect_data().result == ERR_IO_PENDING) | |
928 pending_callback_ = callback; | |
929 else | |
930 RunCallbackAsync(callback, data_->connect_data().result); | |
931 return ERR_IO_PENDING; | |
932 } | |
933 return data_->connect_data().result; | |
934 } | |
935 | |
936 void MockTCPClientSocket::Disconnect() { | |
937 MockClientSocket::Disconnect(); | |
938 pending_callback_.Reset(); | |
939 } | |
940 | |
941 bool MockTCPClientSocket::IsConnected() const { | |
942 return connected_ && !peer_closed_connection_; | |
943 } | |
944 | |
945 bool MockTCPClientSocket::IsConnectedAndIdle() const { | |
946 return IsConnected(); | |
947 } | |
948 | |
949 int MockTCPClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
950 if (addresses_.empty()) | |
951 return MockClientSocket::GetPeerAddress(address); | |
952 | |
953 *address = addresses_[0]; | |
954 return OK; | |
955 } | |
956 | |
957 bool MockTCPClientSocket::WasEverUsed() const { | |
958 return was_used_to_convey_data_; | |
959 } | |
960 | |
961 bool MockTCPClientSocket::UsingTCPFastOpen() const { | |
962 return false; | |
963 } | |
964 | |
965 bool MockTCPClientSocket::WasNpnNegotiated() const { | |
966 return false; | |
967 } | |
968 | |
969 bool MockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | |
970 return false; | |
971 } | |
972 | |
973 void MockTCPClientSocket::OnReadComplete(const MockRead& data) { | |
974 // There must be a read pending. | |
975 DCHECK(pending_buf_.get()); | |
976 // You can't complete a read with another ERR_IO_PENDING status code. | |
977 DCHECK_NE(ERR_IO_PENDING, data.result); | |
978 // Since we've been waiting for data, need_read_data_ should be true. | |
979 DCHECK(need_read_data_); | |
980 | |
981 read_data_ = data; | |
982 need_read_data_ = false; | |
983 | |
984 // The caller is simulating that this IO completes right now. Don't | |
985 // let CompleteRead() schedule a callback. | |
986 read_data_.mode = SYNCHRONOUS; | |
987 | |
988 CompletionCallback callback = pending_callback_; | |
989 int rv = CompleteRead(); | |
990 RunCallback(callback, rv); | |
991 } | |
992 | |
993 void MockTCPClientSocket::OnConnectComplete(const MockConnect& data) { | |
994 CompletionCallback callback = pending_callback_; | |
995 RunCallback(callback, data.result); | |
996 } | |
997 | |
998 int MockTCPClientSocket::CompleteRead() { | |
999 DCHECK(pending_buf_.get()); | |
1000 DCHECK(pending_buf_len_ > 0); | |
1001 | |
1002 was_used_to_convey_data_ = true; | |
1003 | |
1004 // Save the pending async IO data and reset our |pending_| state. | |
1005 scoped_refptr<IOBuffer> buf = pending_buf_; | |
1006 int buf_len = pending_buf_len_; | |
1007 CompletionCallback callback = pending_callback_; | |
1008 pending_buf_ = NULL; | |
1009 pending_buf_len_ = 0; | |
1010 pending_callback_.Reset(); | |
1011 | |
1012 int result = read_data_.result; | |
1013 DCHECK(result != ERR_IO_PENDING); | |
1014 | |
1015 if (read_data_.data) { | |
1016 if (read_data_.data_len - read_offset_ > 0) { | |
1017 result = std::min(buf_len, read_data_.data_len - read_offset_); | |
1018 memcpy(buf->data(), read_data_.data + read_offset_, result); | |
1019 read_offset_ += result; | |
1020 if (read_offset_ == read_data_.data_len) { | |
1021 need_read_data_ = true; | |
1022 read_offset_ = 0; | |
1023 } | |
1024 } else { | |
1025 result = 0; // EOF | |
1026 } | |
1027 } | |
1028 | |
1029 if (read_data_.mode == ASYNC) { | |
1030 DCHECK(!callback.is_null()); | |
1031 RunCallbackAsync(callback, result); | |
1032 return ERR_IO_PENDING; | |
1033 } | |
1034 return result; | |
1035 } | |
1036 | |
1037 DeterministicSocketHelper::DeterministicSocketHelper( | |
1038 net::NetLog* net_log, | |
1039 DeterministicSocketData* data) | |
1040 : write_pending_(false), | |
1041 write_result_(0), | |
1042 read_data_(), | |
1043 read_buf_(NULL), | |
1044 read_buf_len_(0), | |
1045 read_pending_(false), | |
1046 data_(data), | |
1047 was_used_to_convey_data_(false), | |
1048 peer_closed_connection_(false), | |
1049 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)) { | |
1050 } | |
1051 | |
1052 DeterministicSocketHelper::~DeterministicSocketHelper() {} | |
1053 | |
1054 void DeterministicSocketHelper::CompleteWrite() { | |
1055 was_used_to_convey_data_ = true; | |
1056 write_pending_ = false; | |
1057 write_callback_.Run(write_result_); | |
1058 } | |
1059 | |
1060 int DeterministicSocketHelper::CompleteRead() { | |
1061 DCHECK_GT(read_buf_len_, 0); | |
1062 DCHECK_LE(read_data_.data_len, read_buf_len_); | |
1063 DCHECK(read_buf_); | |
1064 | |
1065 was_used_to_convey_data_ = true; | |
1066 | |
1067 if (read_data_.result == ERR_IO_PENDING) | |
1068 read_data_ = data_->GetNextRead(); | |
1069 DCHECK_NE(ERR_IO_PENDING, read_data_.result); | |
1070 // If read_data_.mode is ASYNC, we do not need to wait, since this is already | |
1071 // the callback. Therefore we don't even bother to check it. | |
1072 int result = read_data_.result; | |
1073 | |
1074 if (read_data_.data_len > 0) { | |
1075 DCHECK(read_data_.data); | |
1076 result = std::min(read_buf_len_, read_data_.data_len); | |
1077 memcpy(read_buf_->data(), read_data_.data, result); | |
1078 } | |
1079 | |
1080 if (read_pending_) { | |
1081 read_pending_ = false; | |
1082 read_callback_.Run(result); | |
1083 } | |
1084 | |
1085 return result; | |
1086 } | |
1087 | |
1088 int DeterministicSocketHelper::Write( | |
1089 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | |
1090 DCHECK(buf); | |
1091 DCHECK_GT(buf_len, 0); | |
1092 | |
1093 std::string data(buf->data(), buf_len); | |
1094 MockWriteResult write_result = data_->OnWrite(data); | |
1095 | |
1096 if (write_result.mode == ASYNC) { | |
1097 write_callback_ = callback; | |
1098 write_result_ = write_result.result; | |
1099 DCHECK(!write_callback_.is_null()); | |
1100 write_pending_ = true; | |
1101 return ERR_IO_PENDING; | |
1102 } | |
1103 | |
1104 was_used_to_convey_data_ = true; | |
1105 write_pending_ = false; | |
1106 return write_result.result; | |
1107 } | |
1108 | |
1109 int DeterministicSocketHelper::Read( | |
1110 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | |
1111 | |
1112 read_data_ = data_->GetNextRead(); | |
1113 // The buffer should always be big enough to contain all the MockRead data. To | |
1114 // use small buffers, split the data into multiple MockReads. | |
1115 DCHECK_LE(read_data_.data_len, buf_len); | |
1116 | |
1117 if (read_data_.result == ERR_CONNECTION_CLOSED) { | |
1118 // This MockRead is just a marker to instruct us to set | |
1119 // peer_closed_connection_. | |
1120 peer_closed_connection_ = true; | |
1121 } | |
1122 if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { | |
1123 // This MockRead is just a marker to instruct us to set | |
1124 // peer_closed_connection_. Skip it and get the next one. | |
1125 read_data_ = data_->GetNextRead(); | |
1126 peer_closed_connection_ = true; | |
1127 } | |
1128 | |
1129 read_buf_ = buf; | |
1130 read_buf_len_ = buf_len; | |
1131 read_callback_ = callback; | |
1132 | |
1133 if (read_data_.mode == ASYNC || (read_data_.result == ERR_IO_PENDING)) { | |
1134 read_pending_ = true; | |
1135 DCHECK(!read_callback_.is_null()); | |
1136 return ERR_IO_PENDING; | |
1137 } | |
1138 | |
1139 was_used_to_convey_data_ = true; | |
1140 return CompleteRead(); | |
1141 } | |
1142 | |
1143 DeterministicMockUDPClientSocket::DeterministicMockUDPClientSocket( | |
1144 net::NetLog* net_log, | |
1145 DeterministicSocketData* data) | |
1146 : connected_(false), | |
1147 helper_(net_log, data), | |
1148 source_port_(123) { | |
1149 } | |
1150 | |
1151 DeterministicMockUDPClientSocket::~DeterministicMockUDPClientSocket() {} | |
1152 | |
1153 bool DeterministicMockUDPClientSocket::WritePending() const { | |
1154 return helper_.write_pending(); | |
1155 } | |
1156 | |
1157 bool DeterministicMockUDPClientSocket::ReadPending() const { | |
1158 return helper_.read_pending(); | |
1159 } | |
1160 | |
1161 void DeterministicMockUDPClientSocket::CompleteWrite() { | |
1162 helper_.CompleteWrite(); | |
1163 } | |
1164 | |
1165 int DeterministicMockUDPClientSocket::CompleteRead() { | |
1166 return helper_.CompleteRead(); | |
1167 } | |
1168 | |
1169 int DeterministicMockUDPClientSocket::Connect(const IPEndPoint& address) { | |
1170 if (connected_) | |
1171 return OK; | |
1172 connected_ = true; | |
1173 peer_address_ = address; | |
1174 return helper_.data()->connect_data().result; | |
1175 }; | |
1176 | |
1177 int DeterministicMockUDPClientSocket::Write( | |
1178 IOBuffer* buf, | |
1179 int buf_len, | |
1180 const CompletionCallback& callback) { | |
1181 if (!connected_) | |
1182 return ERR_UNEXPECTED; | |
1183 | |
1184 return helper_.Write(buf, buf_len, callback); | |
1185 } | |
1186 | |
1187 int DeterministicMockUDPClientSocket::Read( | |
1188 IOBuffer* buf, | |
1189 int buf_len, | |
1190 const CompletionCallback& callback) { | |
1191 if (!connected_) | |
1192 return ERR_UNEXPECTED; | |
1193 | |
1194 return helper_.Read(buf, buf_len, callback); | |
1195 } | |
1196 | |
1197 int DeterministicMockUDPClientSocket::SetReceiveBufferSize(int32 size) { | |
1198 return OK; | |
1199 } | |
1200 | |
1201 int DeterministicMockUDPClientSocket::SetSendBufferSize(int32 size) { | |
1202 return OK; | |
1203 } | |
1204 | |
1205 void DeterministicMockUDPClientSocket::Close() { | |
1206 connected_ = false; | |
1207 } | |
1208 | |
1209 int DeterministicMockUDPClientSocket::GetPeerAddress( | |
1210 IPEndPoint* address) const { | |
1211 *address = peer_address_; | |
1212 return OK; | |
1213 } | |
1214 | |
1215 int DeterministicMockUDPClientSocket::GetLocalAddress( | |
1216 IPEndPoint* address) const { | |
1217 IPAddressNumber ip; | |
1218 bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); | |
1219 CHECK(rv); | |
1220 *address = IPEndPoint(ip, source_port_); | |
1221 return OK; | |
1222 } | |
1223 | |
1224 const BoundNetLog& DeterministicMockUDPClientSocket::NetLog() const { | |
1225 return helper_.net_log(); | |
1226 } | |
1227 | |
1228 void DeterministicMockUDPClientSocket::OnReadComplete(const MockRead& data) {} | |
1229 | |
1230 void DeterministicMockUDPClientSocket::OnConnectComplete( | |
1231 const MockConnect& data) { | |
1232 NOTIMPLEMENTED(); | |
1233 } | |
1234 | |
1235 DeterministicMockTCPClientSocket::DeterministicMockTCPClientSocket( | |
1236 net::NetLog* net_log, | |
1237 DeterministicSocketData* data) | |
1238 : MockClientSocket(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)), | |
1239 helper_(net_log, data) { | |
1240 peer_addr_ = data->connect_data().peer_addr; | |
1241 } | |
1242 | |
1243 DeterministicMockTCPClientSocket::~DeterministicMockTCPClientSocket() {} | |
1244 | |
1245 bool DeterministicMockTCPClientSocket::WritePending() const { | |
1246 return helper_.write_pending(); | |
1247 } | |
1248 | |
1249 bool DeterministicMockTCPClientSocket::ReadPending() const { | |
1250 return helper_.read_pending(); | |
1251 } | |
1252 | |
1253 void DeterministicMockTCPClientSocket::CompleteWrite() { | |
1254 helper_.CompleteWrite(); | |
1255 } | |
1256 | |
1257 int DeterministicMockTCPClientSocket::CompleteRead() { | |
1258 return helper_.CompleteRead(); | |
1259 } | |
1260 | |
1261 int DeterministicMockTCPClientSocket::Write( | |
1262 IOBuffer* buf, | |
1263 int buf_len, | |
1264 const CompletionCallback& callback) { | |
1265 if (!connected_) | |
1266 return ERR_UNEXPECTED; | |
1267 | |
1268 return helper_.Write(buf, buf_len, callback); | |
1269 } | |
1270 | |
1271 int DeterministicMockTCPClientSocket::Read( | |
1272 IOBuffer* buf, | |
1273 int buf_len, | |
1274 const CompletionCallback& callback) { | |
1275 if (!connected_) | |
1276 return ERR_UNEXPECTED; | |
1277 | |
1278 return helper_.Read(buf, buf_len, callback); | |
1279 } | |
1280 | |
1281 // TODO(erikchen): Support connect sequencing. | |
1282 int DeterministicMockTCPClientSocket::Connect( | |
1283 const CompletionCallback& callback) { | |
1284 if (connected_) | |
1285 return OK; | |
1286 connected_ = true; | |
1287 if (helper_.data()->connect_data().mode == ASYNC) { | |
1288 RunCallbackAsync(callback, helper_.data()->connect_data().result); | |
1289 return ERR_IO_PENDING; | |
1290 } | |
1291 return helper_.data()->connect_data().result; | |
1292 } | |
1293 | |
1294 void DeterministicMockTCPClientSocket::Disconnect() { | |
1295 MockClientSocket::Disconnect(); | |
1296 } | |
1297 | |
1298 bool DeterministicMockTCPClientSocket::IsConnected() const { | |
1299 return connected_ && !helper_.peer_closed_connection(); | |
1300 } | |
1301 | |
1302 bool DeterministicMockTCPClientSocket::IsConnectedAndIdle() const { | |
1303 return IsConnected(); | |
1304 } | |
1305 | |
1306 bool DeterministicMockTCPClientSocket::WasEverUsed() const { | |
1307 return helper_.was_used_to_convey_data(); | |
1308 } | |
1309 | |
1310 bool DeterministicMockTCPClientSocket::UsingTCPFastOpen() const { | |
1311 return false; | |
1312 } | |
1313 | |
1314 bool DeterministicMockTCPClientSocket::WasNpnNegotiated() const { | |
1315 return false; | |
1316 } | |
1317 | |
1318 bool DeterministicMockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | |
1319 return false; | |
1320 } | |
1321 | |
1322 void DeterministicMockTCPClientSocket::OnReadComplete(const MockRead& data) {} | |
1323 | |
1324 void DeterministicMockTCPClientSocket::OnConnectComplete( | |
1325 const MockConnect& data) {} | |
1326 | |
1327 MockSSLClientSocket::MockSSLClientSocket( | |
1328 scoped_ptr<ClientSocketHandle> transport_socket, | |
1329 const HostPortPair& host_port_pair, | |
1330 const SSLConfig& ssl_config, | |
1331 SSLSocketDataProvider* data) | |
1332 : MockClientSocket( | |
1333 // Have to use the right BoundNetLog for LoadTimingInfo regression | |
1334 // tests. | |
1335 transport_socket->socket()->NetLog()), | |
1336 transport_(transport_socket.Pass()), | |
1337 host_port_pair_(host_port_pair), | |
1338 data_(data), | |
1339 is_npn_state_set_(false), | |
1340 new_npn_value_(false), | |
1341 is_protocol_negotiated_set_(false), | |
1342 protocol_negotiated_(kProtoUnknown), | |
1343 next_connect_state_(STATE_NONE), | |
1344 reached_connect_(false), | |
1345 weak_factory_(this) { | |
1346 DCHECK(data_); | |
1347 peer_addr_ = data->connect.peer_addr; | |
1348 } | |
1349 | |
1350 MockSSLClientSocket::~MockSSLClientSocket() { | |
1351 Disconnect(); | |
1352 } | |
1353 | |
1354 int MockSSLClientSocket::Read(IOBuffer* buf, int buf_len, | |
1355 const CompletionCallback& callback) { | |
1356 return transport_->socket()->Read(buf, buf_len, callback); | |
1357 } | |
1358 | |
1359 int MockSSLClientSocket::Write(IOBuffer* buf, int buf_len, | |
1360 const CompletionCallback& callback) { | |
1361 return transport_->socket()->Write(buf, buf_len, callback); | |
1362 } | |
1363 | |
1364 int MockSSLClientSocket::Connect(const CompletionCallback& callback) { | |
1365 next_connect_state_ = STATE_SSL_CONNECT; | |
1366 reached_connect_ = true; | |
1367 int rv = DoConnectLoop(OK); | |
1368 if (rv == ERR_IO_PENDING) | |
1369 connect_callback_ = callback; | |
1370 return rv; | |
1371 } | |
1372 | |
1373 void MockSSLClientSocket::Disconnect() { | |
1374 weak_factory_.InvalidateWeakPtrs(); | |
1375 MockClientSocket::Disconnect(); | |
1376 if (transport_->socket() != NULL) | |
1377 transport_->socket()->Disconnect(); | |
1378 } | |
1379 | |
1380 bool MockSSLClientSocket::IsConnected() const { | |
1381 return transport_->socket()->IsConnected() && connected_; | |
1382 } | |
1383 | |
1384 bool MockSSLClientSocket::WasEverUsed() const { | |
1385 return transport_->socket()->WasEverUsed(); | |
1386 } | |
1387 | |
1388 bool MockSSLClientSocket::UsingTCPFastOpen() const { | |
1389 return transport_->socket()->UsingTCPFastOpen(); | |
1390 } | |
1391 | |
1392 int MockSSLClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
1393 return transport_->socket()->GetPeerAddress(address); | |
1394 } | |
1395 | |
1396 bool MockSSLClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | |
1397 ssl_info->Reset(); | |
1398 ssl_info->cert = data_->cert; | |
1399 ssl_info->client_cert_sent = data_->client_cert_sent; | |
1400 ssl_info->channel_id_sent = data_->channel_id_sent; | |
1401 ssl_info->connection_status = data_->connection_status; | |
1402 return true; | |
1403 } | |
1404 | |
1405 std::string MockSSLClientSocket::GetSessionCacheKey() const { | |
1406 // For the purposes of these tests, |host_and_port| will serve as the | |
1407 // cache key. | |
1408 return host_port_pair_.ToString(); | |
1409 } | |
1410 | |
1411 bool MockSSLClientSocket::InSessionCache() const { | |
1412 return data_->is_in_session_cache; | |
1413 } | |
1414 | |
1415 void MockSSLClientSocket::SetHandshakeCompletionCallback( | |
1416 const base::Closure& cb) { | |
1417 handshake_completion_callback_ = cb; | |
1418 } | |
1419 | |
1420 void MockSSLClientSocket::GetSSLCertRequestInfo( | |
1421 SSLCertRequestInfo* cert_request_info) { | |
1422 DCHECK(cert_request_info); | |
1423 if (data_->cert_request_info) { | |
1424 cert_request_info->host_and_port = | |
1425 data_->cert_request_info->host_and_port; | |
1426 cert_request_info->client_certs = data_->cert_request_info->client_certs; | |
1427 } else { | |
1428 cert_request_info->Reset(); | |
1429 } | |
1430 } | |
1431 | |
1432 SSLClientSocket::NextProtoStatus MockSSLClientSocket::GetNextProto( | |
1433 std::string* proto) { | |
1434 *proto = data_->next_proto; | |
1435 return data_->next_proto_status; | |
1436 } | |
1437 | |
1438 bool MockSSLClientSocket::set_was_npn_negotiated(bool negotiated) { | |
1439 is_npn_state_set_ = true; | |
1440 return new_npn_value_ = negotiated; | |
1441 } | |
1442 | |
1443 bool MockSSLClientSocket::WasNpnNegotiated() const { | |
1444 if (is_npn_state_set_) | |
1445 return new_npn_value_; | |
1446 return data_->was_npn_negotiated; | |
1447 } | |
1448 | |
1449 NextProto MockSSLClientSocket::GetNegotiatedProtocol() const { | |
1450 if (is_protocol_negotiated_set_) | |
1451 return protocol_negotiated_; | |
1452 return data_->protocol_negotiated; | |
1453 } | |
1454 | |
1455 void MockSSLClientSocket::set_protocol_negotiated( | |
1456 NextProto protocol_negotiated) { | |
1457 is_protocol_negotiated_set_ = true; | |
1458 protocol_negotiated_ = protocol_negotiated; | |
1459 } | |
1460 | |
1461 bool MockSSLClientSocket::WasChannelIDSent() const { | |
1462 return data_->channel_id_sent; | |
1463 } | |
1464 | |
1465 void MockSSLClientSocket::set_channel_id_sent(bool channel_id_sent) { | |
1466 data_->channel_id_sent = channel_id_sent; | |
1467 } | |
1468 | |
1469 ChannelIDService* MockSSLClientSocket::GetChannelIDService() const { | |
1470 return data_->channel_id_service; | |
1471 } | |
1472 | |
1473 void MockSSLClientSocket::OnReadComplete(const MockRead& data) { | |
1474 NOTIMPLEMENTED(); | |
1475 } | |
1476 | |
1477 void MockSSLClientSocket::OnConnectComplete(const MockConnect& data) { | |
1478 NOTIMPLEMENTED(); | |
1479 } | |
1480 | |
1481 void MockSSLClientSocket::RestartPausedConnect() { | |
1482 DCHECK(data_->should_pause_on_connect); | |
1483 DCHECK_EQ(next_connect_state_, STATE_SSL_CONNECT_COMPLETE); | |
1484 OnIOComplete(data_->connect.result); | |
1485 } | |
1486 | |
1487 void MockSSLClientSocket::OnIOComplete(int result) { | |
1488 int rv = DoConnectLoop(result); | |
1489 if (rv != ERR_IO_PENDING) | |
1490 base::ResetAndReturn(&connect_callback_).Run(rv); | |
1491 } | |
1492 | |
1493 int MockSSLClientSocket::DoConnectLoop(int result) { | |
1494 DCHECK_NE(next_connect_state_, STATE_NONE); | |
1495 | |
1496 int rv = result; | |
1497 do { | |
1498 ConnectState state = next_connect_state_; | |
1499 next_connect_state_ = STATE_NONE; | |
1500 switch (state) { | |
1501 case STATE_SSL_CONNECT: | |
1502 rv = DoSSLConnect(); | |
1503 break; | |
1504 case STATE_SSL_CONNECT_COMPLETE: | |
1505 rv = DoSSLConnectComplete(rv); | |
1506 break; | |
1507 default: | |
1508 NOTREACHED() << "bad state"; | |
1509 rv = ERR_UNEXPECTED; | |
1510 break; | |
1511 } | |
1512 } while (rv != ERR_IO_PENDING && next_connect_state_ != STATE_NONE); | |
1513 | |
1514 return rv; | |
1515 } | |
1516 | |
1517 int MockSSLClientSocket::DoSSLConnect() { | |
1518 next_connect_state_ = STATE_SSL_CONNECT_COMPLETE; | |
1519 | |
1520 if (data_->should_pause_on_connect) | |
1521 return ERR_IO_PENDING; | |
1522 | |
1523 if (data_->connect.mode == ASYNC) { | |
1524 base::MessageLoop::current()->PostTask( | |
1525 FROM_HERE, | |
1526 base::Bind(&MockSSLClientSocket::OnIOComplete, | |
1527 weak_factory_.GetWeakPtr(), | |
1528 data_->connect.result)); | |
1529 return ERR_IO_PENDING; | |
1530 } | |
1531 | |
1532 return data_->connect.result; | |
1533 } | |
1534 | |
1535 int MockSSLClientSocket::DoSSLConnectComplete(int result) { | |
1536 if (result == OK) | |
1537 connected_ = true; | |
1538 | |
1539 if (!handshake_completion_callback_.is_null()) | |
1540 base::ResetAndReturn(&handshake_completion_callback_).Run(); | |
1541 return result; | |
1542 } | |
1543 | |
1544 MockUDPClientSocket::MockUDPClientSocket(SocketDataProvider* data, | |
1545 net::NetLog* net_log) | |
1546 : connected_(false), | |
1547 data_(data), | |
1548 read_offset_(0), | |
1549 read_data_(SYNCHRONOUS, ERR_UNEXPECTED), | |
1550 need_read_data_(true), | |
1551 source_port_(123), | |
1552 pending_buf_(NULL), | |
1553 pending_buf_len_(0), | |
1554 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)), | |
1555 weak_factory_(this) { | |
1556 DCHECK(data_); | |
1557 data_->Reset(); | |
1558 peer_addr_ = data->connect_data().peer_addr; | |
1559 } | |
1560 | |
1561 MockUDPClientSocket::~MockUDPClientSocket() {} | |
1562 | |
1563 int MockUDPClientSocket::Read(IOBuffer* buf, | |
1564 int buf_len, | |
1565 const CompletionCallback& callback) { | |
1566 if (!connected_) | |
1567 return ERR_UNEXPECTED; | |
1568 | |
1569 // If the buffer is already in use, a read is already in progress! | |
1570 DCHECK(pending_buf_.get() == NULL); | |
1571 | |
1572 // Store our async IO data. | |
1573 pending_buf_ = buf; | |
1574 pending_buf_len_ = buf_len; | |
1575 pending_callback_ = callback; | |
1576 | |
1577 if (need_read_data_) { | |
1578 read_data_ = data_->GetNextRead(); | |
1579 // ERR_IO_PENDING means that the SocketDataProvider is taking responsibility | |
1580 // to complete the async IO manually later (via OnReadComplete). | |
1581 if (read_data_.result == ERR_IO_PENDING) { | |
1582 // We need to be using async IO in this case. | |
1583 DCHECK(!callback.is_null()); | |
1584 return ERR_IO_PENDING; | |
1585 } | |
1586 need_read_data_ = false; | |
1587 } | |
1588 | |
1589 return CompleteRead(); | |
1590 } | |
1591 | |
1592 int MockUDPClientSocket::Write(IOBuffer* buf, int buf_len, | |
1593 const CompletionCallback& callback) { | |
1594 DCHECK(buf); | |
1595 DCHECK_GT(buf_len, 0); | |
1596 | |
1597 if (!connected_) | |
1598 return ERR_UNEXPECTED; | |
1599 | |
1600 std::string data(buf->data(), buf_len); | |
1601 MockWriteResult write_result = data_->OnWrite(data); | |
1602 | |
1603 if (write_result.mode == ASYNC) { | |
1604 RunCallbackAsync(callback, write_result.result); | |
1605 return ERR_IO_PENDING; | |
1606 } | |
1607 return write_result.result; | |
1608 } | |
1609 | |
1610 int MockUDPClientSocket::SetReceiveBufferSize(int32 size) { | |
1611 return OK; | |
1612 } | |
1613 | |
1614 int MockUDPClientSocket::SetSendBufferSize(int32 size) { | |
1615 return OK; | |
1616 } | |
1617 | |
1618 void MockUDPClientSocket::Close() { | |
1619 connected_ = false; | |
1620 } | |
1621 | |
1622 int MockUDPClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
1623 *address = peer_addr_; | |
1624 return OK; | |
1625 } | |
1626 | |
1627 int MockUDPClientSocket::GetLocalAddress(IPEndPoint* address) const { | |
1628 IPAddressNumber ip; | |
1629 bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); | |
1630 CHECK(rv); | |
1631 *address = IPEndPoint(ip, source_port_); | |
1632 return OK; | |
1633 } | |
1634 | |
1635 const BoundNetLog& MockUDPClientSocket::NetLog() const { | |
1636 return net_log_; | |
1637 } | |
1638 | |
1639 int MockUDPClientSocket::Connect(const IPEndPoint& address) { | |
1640 connected_ = true; | |
1641 peer_addr_ = address; | |
1642 return data_->connect_data().result; | |
1643 } | |
1644 | |
1645 void MockUDPClientSocket::OnReadComplete(const MockRead& data) { | |
1646 // There must be a read pending. | |
1647 DCHECK(pending_buf_.get()); | |
1648 // You can't complete a read with another ERR_IO_PENDING status code. | |
1649 DCHECK_NE(ERR_IO_PENDING, data.result); | |
1650 // Since we've been waiting for data, need_read_data_ should be true. | |
1651 DCHECK(need_read_data_); | |
1652 | |
1653 read_data_ = data; | |
1654 need_read_data_ = false; | |
1655 | |
1656 // The caller is simulating that this IO completes right now. Don't | |
1657 // let CompleteRead() schedule a callback. | |
1658 read_data_.mode = SYNCHRONOUS; | |
1659 | |
1660 net::CompletionCallback callback = pending_callback_; | |
1661 int rv = CompleteRead(); | |
1662 RunCallback(callback, rv); | |
1663 } | |
1664 | |
1665 void MockUDPClientSocket::OnConnectComplete(const MockConnect& data) { | |
1666 NOTIMPLEMENTED(); | |
1667 } | |
1668 | |
1669 int MockUDPClientSocket::CompleteRead() { | |
1670 DCHECK(pending_buf_.get()); | |
1671 DCHECK(pending_buf_len_ > 0); | |
1672 | |
1673 // Save the pending async IO data and reset our |pending_| state. | |
1674 scoped_refptr<IOBuffer> buf = pending_buf_; | |
1675 int buf_len = pending_buf_len_; | |
1676 CompletionCallback callback = pending_callback_; | |
1677 pending_buf_ = NULL; | |
1678 pending_buf_len_ = 0; | |
1679 pending_callback_.Reset(); | |
1680 | |
1681 int result = read_data_.result; | |
1682 DCHECK(result != ERR_IO_PENDING); | |
1683 | |
1684 if (read_data_.data) { | |
1685 if (read_data_.data_len - read_offset_ > 0) { | |
1686 result = std::min(buf_len, read_data_.data_len - read_offset_); | |
1687 memcpy(buf->data(), read_data_.data + read_offset_, result); | |
1688 read_offset_ += result; | |
1689 if (read_offset_ == read_data_.data_len) { | |
1690 need_read_data_ = true; | |
1691 read_offset_ = 0; | |
1692 } | |
1693 } else { | |
1694 result = 0; // EOF | |
1695 } | |
1696 } | |
1697 | |
1698 if (read_data_.mode == ASYNC) { | |
1699 DCHECK(!callback.is_null()); | |
1700 RunCallbackAsync(callback, result); | |
1701 return ERR_IO_PENDING; | |
1702 } | |
1703 return result; | |
1704 } | |
1705 | |
1706 void MockUDPClientSocket::RunCallbackAsync(const CompletionCallback& callback, | |
1707 int result) { | |
1708 base::MessageLoop::current()->PostTask( | |
1709 FROM_HERE, | |
1710 base::Bind(&MockUDPClientSocket::RunCallback, | |
1711 weak_factory_.GetWeakPtr(), | |
1712 callback, | |
1713 result)); | |
1714 } | |
1715 | |
1716 void MockUDPClientSocket::RunCallback(const CompletionCallback& callback, | |
1717 int result) { | |
1718 if (!callback.is_null()) | |
1719 callback.Run(result); | |
1720 } | |
1721 | |
1722 TestSocketRequest::TestSocketRequest( | |
1723 std::vector<TestSocketRequest*>* request_order, size_t* completion_count) | |
1724 : request_order_(request_order), | |
1725 completion_count_(completion_count), | |
1726 callback_(base::Bind(&TestSocketRequest::OnComplete, | |
1727 base::Unretained(this))) { | |
1728 DCHECK(request_order); | |
1729 DCHECK(completion_count); | |
1730 } | |
1731 | |
1732 TestSocketRequest::~TestSocketRequest() { | |
1733 } | |
1734 | |
1735 void TestSocketRequest::OnComplete(int result) { | |
1736 SetResult(result); | |
1737 (*completion_count_)++; | |
1738 request_order_->push_back(this); | |
1739 } | |
1740 | |
1741 // static | |
1742 const int ClientSocketPoolTest::kIndexOutOfBounds = -1; | |
1743 | |
1744 // static | |
1745 const int ClientSocketPoolTest::kRequestNotFound = -2; | |
1746 | |
1747 ClientSocketPoolTest::ClientSocketPoolTest() : completion_count_(0) {} | |
1748 ClientSocketPoolTest::~ClientSocketPoolTest() {} | |
1749 | |
1750 int ClientSocketPoolTest::GetOrderOfRequest(size_t index) const { | |
1751 index--; | |
1752 if (index >= requests_.size()) | |
1753 return kIndexOutOfBounds; | |
1754 | |
1755 for (size_t i = 0; i < request_order_.size(); i++) | |
1756 if (requests_[index] == request_order_[i]) | |
1757 return i + 1; | |
1758 | |
1759 return kRequestNotFound; | |
1760 } | |
1761 | |
1762 bool ClientSocketPoolTest::ReleaseOneConnection(KeepAlive keep_alive) { | |
1763 ScopedVector<TestSocketRequest>::iterator i; | |
1764 for (i = requests_.begin(); i != requests_.end(); ++i) { | |
1765 if ((*i)->handle()->is_initialized()) { | |
1766 if (keep_alive == NO_KEEP_ALIVE) | |
1767 (*i)->handle()->socket()->Disconnect(); | |
1768 (*i)->handle()->Reset(); | |
1769 base::RunLoop().RunUntilIdle(); | |
1770 return true; | |
1771 } | |
1772 } | |
1773 return false; | |
1774 } | |
1775 | |
1776 void ClientSocketPoolTest::ReleaseAllConnections(KeepAlive keep_alive) { | |
1777 bool released_one; | |
1778 do { | |
1779 released_one = ReleaseOneConnection(keep_alive); | |
1780 } while (released_one); | |
1781 } | |
1782 | |
1783 MockTransportClientSocketPool::MockConnectJob::MockConnectJob( | |
1784 scoped_ptr<StreamSocket> socket, | |
1785 ClientSocketHandle* handle, | |
1786 const CompletionCallback& callback) | |
1787 : socket_(socket.Pass()), | |
1788 handle_(handle), | |
1789 user_callback_(callback) { | |
1790 } | |
1791 | |
1792 MockTransportClientSocketPool::MockConnectJob::~MockConnectJob() {} | |
1793 | |
1794 int MockTransportClientSocketPool::MockConnectJob::Connect() { | |
1795 int rv = socket_->Connect(base::Bind(&MockConnectJob::OnConnect, | |
1796 base::Unretained(this))); | |
1797 if (rv == OK) { | |
1798 user_callback_.Reset(); | |
1799 OnConnect(OK); | |
1800 } | |
1801 return rv; | |
1802 } | |
1803 | |
1804 bool MockTransportClientSocketPool::MockConnectJob::CancelHandle( | |
1805 const ClientSocketHandle* handle) { | |
1806 if (handle != handle_) | |
1807 return false; | |
1808 socket_.reset(); | |
1809 handle_ = NULL; | |
1810 user_callback_.Reset(); | |
1811 return true; | |
1812 } | |
1813 | |
1814 void MockTransportClientSocketPool::MockConnectJob::OnConnect(int rv) { | |
1815 if (!socket_.get()) | |
1816 return; | |
1817 if (rv == OK) { | |
1818 handle_->SetSocket(socket_.Pass()); | |
1819 | |
1820 // Needed for socket pool tests that layer other sockets on top of mock | |
1821 // sockets. | |
1822 LoadTimingInfo::ConnectTiming connect_timing; | |
1823 base::TimeTicks now = base::TimeTicks::Now(); | |
1824 connect_timing.dns_start = now; | |
1825 connect_timing.dns_end = now; | |
1826 connect_timing.connect_start = now; | |
1827 connect_timing.connect_end = now; | |
1828 handle_->set_connect_timing(connect_timing); | |
1829 } else { | |
1830 socket_.reset(); | |
1831 } | |
1832 | |
1833 handle_ = NULL; | |
1834 | |
1835 if (!user_callback_.is_null()) { | |
1836 CompletionCallback callback = user_callback_; | |
1837 user_callback_.Reset(); | |
1838 callback.Run(rv); | |
1839 } | |
1840 } | |
1841 | |
1842 MockTransportClientSocketPool::MockTransportClientSocketPool( | |
1843 int max_sockets, | |
1844 int max_sockets_per_group, | |
1845 ClientSocketPoolHistograms* histograms, | |
1846 ClientSocketFactory* socket_factory) | |
1847 : TransportClientSocketPool(max_sockets, max_sockets_per_group, histograms, | |
1848 NULL, NULL, NULL), | |
1849 client_socket_factory_(socket_factory), | |
1850 last_request_priority_(DEFAULT_PRIORITY), | |
1851 release_count_(0), | |
1852 cancel_count_(0) { | |
1853 } | |
1854 | |
1855 MockTransportClientSocketPool::~MockTransportClientSocketPool() {} | |
1856 | |
1857 int MockTransportClientSocketPool::RequestSocket( | |
1858 const std::string& group_name, const void* socket_params, | |
1859 RequestPriority priority, ClientSocketHandle* handle, | |
1860 const CompletionCallback& callback, const BoundNetLog& net_log) { | |
1861 last_request_priority_ = priority; | |
1862 scoped_ptr<StreamSocket> socket = | |
1863 client_socket_factory_->CreateTransportClientSocket( | |
1864 AddressList(), net_log.net_log(), net::NetLog::Source()); | |
1865 MockConnectJob* job = new MockConnectJob(socket.Pass(), handle, callback); | |
1866 job_list_.push_back(job); | |
1867 handle->set_pool_id(1); | |
1868 return job->Connect(); | |
1869 } | |
1870 | |
1871 void MockTransportClientSocketPool::CancelRequest(const std::string& group_name, | |
1872 ClientSocketHandle* handle) { | |
1873 std::vector<MockConnectJob*>::iterator i; | |
1874 for (i = job_list_.begin(); i != job_list_.end(); ++i) { | |
1875 if ((*i)->CancelHandle(handle)) { | |
1876 cancel_count_++; | |
1877 break; | |
1878 } | |
1879 } | |
1880 } | |
1881 | |
1882 void MockTransportClientSocketPool::ReleaseSocket( | |
1883 const std::string& group_name, | |
1884 scoped_ptr<StreamSocket> socket, | |
1885 int id) { | |
1886 EXPECT_EQ(1, id); | |
1887 release_count_++; | |
1888 } | |
1889 | |
1890 DeterministicMockClientSocketFactory::DeterministicMockClientSocketFactory() {} | |
1891 | |
1892 DeterministicMockClientSocketFactory::~DeterministicMockClientSocketFactory() {} | |
1893 | |
1894 void DeterministicMockClientSocketFactory::AddSocketDataProvider( | |
1895 DeterministicSocketData* data) { | |
1896 mock_data_.Add(data); | |
1897 } | |
1898 | |
1899 void DeterministicMockClientSocketFactory::AddSSLSocketDataProvider( | |
1900 SSLSocketDataProvider* data) { | |
1901 mock_ssl_data_.Add(data); | |
1902 } | |
1903 | |
1904 void DeterministicMockClientSocketFactory::ResetNextMockIndexes() { | |
1905 mock_data_.ResetNextIndex(); | |
1906 mock_ssl_data_.ResetNextIndex(); | |
1907 } | |
1908 | |
1909 MockSSLClientSocket* DeterministicMockClientSocketFactory:: | |
1910 GetMockSSLClientSocket(size_t index) const { | |
1911 DCHECK_LT(index, ssl_client_sockets_.size()); | |
1912 return ssl_client_sockets_[index]; | |
1913 } | |
1914 | |
1915 scoped_ptr<DatagramClientSocket> | |
1916 DeterministicMockClientSocketFactory::CreateDatagramClientSocket( | |
1917 DatagramSocket::BindType bind_type, | |
1918 const RandIntCallback& rand_int_cb, | |
1919 net::NetLog* net_log, | |
1920 const NetLog::Source& source) { | |
1921 DeterministicSocketData* data_provider = mock_data().GetNext(); | |
1922 scoped_ptr<DeterministicMockUDPClientSocket> socket( | |
1923 new DeterministicMockUDPClientSocket(net_log, data_provider)); | |
1924 data_provider->set_delegate(socket->AsWeakPtr()); | |
1925 udp_client_sockets().push_back(socket.get()); | |
1926 if (bind_type == DatagramSocket::RANDOM_BIND) | |
1927 socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535))); | |
1928 return socket.Pass(); | |
1929 } | |
1930 | |
1931 scoped_ptr<StreamSocket> | |
1932 DeterministicMockClientSocketFactory::CreateTransportClientSocket( | |
1933 const AddressList& addresses, | |
1934 net::NetLog* net_log, | |
1935 const net::NetLog::Source& source) { | |
1936 DeterministicSocketData* data_provider = mock_data().GetNext(); | |
1937 scoped_ptr<DeterministicMockTCPClientSocket> socket( | |
1938 new DeterministicMockTCPClientSocket(net_log, data_provider)); | |
1939 data_provider->set_delegate(socket->AsWeakPtr()); | |
1940 tcp_client_sockets().push_back(socket.get()); | |
1941 return socket.Pass(); | |
1942 } | |
1943 | |
1944 scoped_ptr<SSLClientSocket> | |
1945 DeterministicMockClientSocketFactory::CreateSSLClientSocket( | |
1946 scoped_ptr<ClientSocketHandle> transport_socket, | |
1947 const HostPortPair& host_and_port, | |
1948 const SSLConfig& ssl_config, | |
1949 const SSLClientSocketContext& context) { | |
1950 scoped_ptr<MockSSLClientSocket> socket( | |
1951 new MockSSLClientSocket(transport_socket.Pass(), | |
1952 host_and_port, ssl_config, | |
1953 mock_ssl_data_.GetNext())); | |
1954 ssl_client_sockets_.push_back(socket.get()); | |
1955 return socket.Pass(); | |
1956 } | |
1957 | |
1958 void DeterministicMockClientSocketFactory::ClearSSLSessionCache() { | |
1959 } | |
1960 | |
1961 MockSOCKSClientSocketPool::MockSOCKSClientSocketPool( | |
1962 int max_sockets, | |
1963 int max_sockets_per_group, | |
1964 ClientSocketPoolHistograms* histograms, | |
1965 TransportClientSocketPool* transport_pool) | |
1966 : SOCKSClientSocketPool(max_sockets, max_sockets_per_group, histograms, | |
1967 NULL, transport_pool, NULL), | |
1968 transport_pool_(transport_pool) { | |
1969 } | |
1970 | |
1971 MockSOCKSClientSocketPool::~MockSOCKSClientSocketPool() {} | |
1972 | |
1973 int MockSOCKSClientSocketPool::RequestSocket( | |
1974 const std::string& group_name, const void* socket_params, | |
1975 RequestPriority priority, ClientSocketHandle* handle, | |
1976 const CompletionCallback& callback, const BoundNetLog& net_log) { | |
1977 return transport_pool_->RequestSocket( | |
1978 group_name, socket_params, priority, handle, callback, net_log); | |
1979 } | |
1980 | |
1981 void MockSOCKSClientSocketPool::CancelRequest( | |
1982 const std::string& group_name, | |
1983 ClientSocketHandle* handle) { | |
1984 return transport_pool_->CancelRequest(group_name, handle); | |
1985 } | |
1986 | |
1987 void MockSOCKSClientSocketPool::ReleaseSocket(const std::string& group_name, | |
1988 scoped_ptr<StreamSocket> socket, | |
1989 int id) { | |
1990 return transport_pool_->ReleaseSocket(group_name, socket.Pass(), id); | |
1991 } | |
1992 | |
1993 ScopedWebSocketEndpointZeroUnlockDelay:: | |
1994 ScopedWebSocketEndpointZeroUnlockDelay() { | |
1995 old_delay_ = | |
1996 WebSocketEndpointLockManager::GetInstance()->SetUnlockDelayForTesting( | |
1997 base::TimeDelta()); | |
1998 } | |
1999 | |
2000 ScopedWebSocketEndpointZeroUnlockDelay:: | |
2001 ~ScopedWebSocketEndpointZeroUnlockDelay() { | |
2002 base::TimeDelta active_delay = | |
2003 WebSocketEndpointLockManager::GetInstance()->SetUnlockDelayForTesting( | |
2004 old_delay_); | |
2005 EXPECT_EQ(active_delay, base::TimeDelta()); | |
2006 } | |
2007 | |
2008 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; | |
2009 const int kSOCKS5GreetRequestLength = arraysize(kSOCKS5GreetRequest); | |
2010 | |
2011 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; | |
2012 const int kSOCKS5GreetResponseLength = arraysize(kSOCKS5GreetResponse); | |
2013 | |
2014 const char kSOCKS5OkRequest[] = | |
2015 { 0x05, 0x01, 0x00, 0x03, 0x04, 'h', 'o', 's', 't', 0x00, 0x50 }; | |
2016 const int kSOCKS5OkRequestLength = arraysize(kSOCKS5OkRequest); | |
2017 | |
2018 const char kSOCKS5OkResponse[] = | |
2019 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 }; | |
2020 const int kSOCKS5OkResponseLength = arraysize(kSOCKS5OkResponse); | |
2021 | |
2022 } // namespace net | |
OLD | NEW |