OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 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 "jingle/glue/pseudotcp_adapter.h" | 5 #include "jingle/glue/pseudotcp_adapter.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "jingle/glue/thread_wrapper.h" | 12 #include "jingle/glue/thread_wrapper.h" |
13 #include "net/base/completion_callback.h" | |
14 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
15 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
16 #include "net/base/test_completion_callback.h" | 15 #include "net/base/test_completion_callback.h" |
17 #include "net/udp/udp_socket.h" | 16 #include "net/udp/udp_socket.h" |
18 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
20 | 19 |
21 | 20 |
22 namespace jingle_glue { | 21 namespace jingle_glue { |
23 namespace { | 22 namespace { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 private: | 73 private: |
75 double volume_; | 74 double volume_; |
76 double rate_; | 75 double rate_; |
77 double level_; | 76 double level_; |
78 base::TimeTicks last_update_; | 77 base::TimeTicks last_update_; |
79 }; | 78 }; |
80 | 79 |
81 class FakeSocket : public net::Socket { | 80 class FakeSocket : public net::Socket { |
82 public: | 81 public: |
83 FakeSocket() | 82 FakeSocket() |
84 : old_read_callback_(NULL), | 83 : rate_limiter_(NULL), |
85 rate_limiter_(NULL), | |
86 latency_ms_(0) { | 84 latency_ms_(0) { |
87 } | 85 } |
88 virtual ~FakeSocket() { } | 86 virtual ~FakeSocket() { } |
89 | 87 |
90 void AppendInputPacket(const std::vector<char>& data) { | 88 void AppendInputPacket(const std::vector<char>& data) { |
91 if (rate_limiter_ && rate_limiter_->DropNextPacket()) | 89 if (rate_limiter_ && rate_limiter_->DropNextPacket()) |
92 return; // Lose the packet. | 90 return; // Lose the packet. |
93 | 91 |
94 if (old_read_callback_ || !read_callback_.is_null()) { | 92 if (!read_callback_.is_null()) { |
95 int size = std::min(read_buffer_size_, static_cast<int>(data.size())); | 93 int size = std::min(read_buffer_size_, static_cast<int>(data.size())); |
96 memcpy(read_buffer_->data(), &data[0], data.size()); | 94 memcpy(read_buffer_->data(), &data[0], data.size()); |
97 if (old_read_callback_) { | 95 net::CompletionCallback cb = read_callback_; |
98 net::OldCompletionCallback* cb = old_read_callback_; | 96 read_callback_.Reset(); |
99 old_read_callback_ = NULL; | 97 read_buffer_ = NULL; |
100 read_buffer_ = NULL; | 98 cb.Run(size); |
101 cb->Run(size); | |
102 } else { | |
103 net::CompletionCallback cb = read_callback_; | |
104 read_callback_.Reset(); | |
105 read_buffer_ = NULL; | |
106 cb.Run(size); | |
107 } | |
108 } else { | 99 } else { |
109 incoming_packets_.push_back(data); | 100 incoming_packets_.push_back(data); |
110 } | 101 } |
111 } | 102 } |
112 | 103 |
113 void Connect(FakeSocket* peer_socket) { | 104 void Connect(FakeSocket* peer_socket) { |
114 peer_socket_ = peer_socket; | 105 peer_socket_ = peer_socket; |
115 } | 106 } |
116 | 107 |
117 void set_rate_limiter(RateLimiter* rate_limiter) { | 108 void set_rate_limiter(RateLimiter* rate_limiter) { |
118 rate_limiter_ = rate_limiter; | 109 rate_limiter_ = rate_limiter; |
119 }; | 110 }; |
120 | 111 |
121 void set_latency(int latency_ms) { latency_ms_ = latency_ms; }; | 112 void set_latency(int latency_ms) { latency_ms_ = latency_ms; }; |
122 | 113 |
123 // net::Socket implementation. | 114 // net::Socket interface. |
124 virtual int Read(net::IOBuffer* buf, int buf_len, | 115 virtual int Read(net::IOBuffer* buf, int buf_len, |
125 net::OldCompletionCallback* callback) { | 116 const net::CompletionCallback& callback) { |
126 CHECK(!old_read_callback_ && read_callback_.is_null()); | 117 CHECK(read_callback_.is_null()); |
127 CHECK(buf); | 118 CHECK(buf); |
128 | 119 |
129 if (incoming_packets_.size() > 0) { | 120 if (incoming_packets_.size() > 0) { |
130 scoped_refptr<net::IOBuffer> buffer(buf); | |
131 int size = std::min( | |
132 static_cast<int>(incoming_packets_.front().size()), buf_len); | |
133 memcpy(buffer->data(), &*incoming_packets_.front().begin(), size); | |
134 incoming_packets_.pop_front(); | |
135 return size; | |
136 } else { | |
137 old_read_callback_ = callback; | |
138 read_buffer_ = buf; | |
139 read_buffer_size_ = buf_len; | |
140 return net::ERR_IO_PENDING; | |
141 } | |
142 } | |
143 virtual int Read(net::IOBuffer* buf, int buf_len, | |
144 const net::CompletionCallback& callback) { | |
145 CHECK(!old_read_callback_ && read_callback_.is_null()); | |
146 CHECK(buf); | |
147 | |
148 if (incoming_packets_.size() > 0) { | |
149 scoped_refptr<net::IOBuffer> buffer(buf); | 121 scoped_refptr<net::IOBuffer> buffer(buf); |
150 int size = std::min( | 122 int size = std::min( |
151 static_cast<int>(incoming_packets_.front().size()), buf_len); | 123 static_cast<int>(incoming_packets_.front().size()), buf_len); |
152 memcpy(buffer->data(), &*incoming_packets_.front().begin(), size); | 124 memcpy(buffer->data(), &*incoming_packets_.front().begin(), size); |
153 incoming_packets_.pop_front(); | 125 incoming_packets_.pop_front(); |
154 return size; | 126 return size; |
155 } else { | 127 } else { |
156 read_callback_ = callback; | 128 read_callback_ = callback; |
157 read_buffer_ = buf; | 129 read_buffer_ = buf; |
158 read_buffer_size_ = buf_len; | 130 read_buffer_size_ = buf_len; |
159 return net::ERR_IO_PENDING; | 131 return net::ERR_IO_PENDING; |
160 } | 132 } |
161 } | 133 } |
162 | 134 |
163 virtual int Write(net::IOBuffer* buf, int buf_len, | 135 virtual int Write(net::IOBuffer* buf, int buf_len, |
164 net::OldCompletionCallback* callback) OVERRIDE { | 136 const net::CompletionCallback& callback) OVERRIDE { |
165 DCHECK(buf); | 137 DCHECK(buf); |
166 if (peer_socket_) { | 138 if (peer_socket_) { |
167 MessageLoop::current()->PostDelayedTask( | 139 MessageLoop::current()->PostDelayedTask( |
168 FROM_HERE, | 140 FROM_HERE, |
169 base::Bind(&FakeSocket::AppendInputPacket, | 141 base::Bind(&FakeSocket::AppendInputPacket, |
170 base::Unretained(peer_socket_), | 142 base::Unretained(peer_socket_), |
171 std::vector<char>(buf->data(), buf->data() + buf_len)), | 143 std::vector<char>(buf->data(), buf->data() + buf_len)), |
172 latency_ms_); | 144 latency_ms_); |
173 } | 145 } |
174 | 146 |
175 return buf_len; | 147 return buf_len; |
176 } | 148 } |
177 | 149 |
178 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { | 150 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { |
179 NOTIMPLEMENTED(); | 151 NOTIMPLEMENTED(); |
180 return false; | 152 return false; |
181 } | 153 } |
182 virtual bool SetSendBufferSize(int32 size) OVERRIDE { | 154 virtual bool SetSendBufferSize(int32 size) OVERRIDE { |
183 NOTIMPLEMENTED(); | 155 NOTIMPLEMENTED(); |
184 return false; | 156 return false; |
185 } | 157 } |
186 | 158 |
187 private: | 159 private: |
188 scoped_refptr<net::IOBuffer> read_buffer_; | 160 scoped_refptr<net::IOBuffer> read_buffer_; |
189 int read_buffer_size_; | 161 int read_buffer_size_; |
190 net::OldCompletionCallback* old_read_callback_; | |
191 net::CompletionCallback read_callback_; | 162 net::CompletionCallback read_callback_; |
192 | 163 |
193 std::deque<std::vector<char> > incoming_packets_; | 164 std::deque<std::vector<char> > incoming_packets_; |
194 | 165 |
195 FakeSocket* peer_socket_; | 166 FakeSocket* peer_socket_; |
196 RateLimiter* rate_limiter_; | 167 RateLimiter* rate_limiter_; |
197 int latency_ms_; | 168 int latency_ms_; |
198 }; | 169 }; |
199 | 170 |
200 class TCPChannelTester : public base::RefCountedThreadSafe<TCPChannelTester> { | 171 class TCPChannelTester : public base::RefCountedThreadSafe<TCPChannelTester> { |
201 public: | 172 public: |
202 TCPChannelTester(MessageLoop* message_loop, | 173 TCPChannelTester(MessageLoop* message_loop, |
203 net::Socket* client_socket, | 174 net::Socket* client_socket, |
204 net::Socket* host_socket) | 175 net::Socket* host_socket) |
205 : message_loop_(message_loop), | 176 : message_loop_(message_loop), |
206 host_socket_(host_socket), | 177 host_socket_(host_socket), |
207 client_socket_(client_socket), | 178 client_socket_(client_socket), |
208 done_(false), | 179 done_(false), |
209 ALLOW_THIS_IN_INITIALIZER_LIST( | |
210 write_cb_(this, &TCPChannelTester::OnWritten)), | |
211 ALLOW_THIS_IN_INITIALIZER_LIST( | |
212 read_cb_(this, &TCPChannelTester::OnRead)), | |
213 write_errors_(0), | 180 write_errors_(0), |
214 read_errors_(0) { | 181 read_errors_(0) { |
215 } | 182 } |
216 | 183 |
217 virtual ~TCPChannelTester() { } | 184 virtual ~TCPChannelTester() { } |
218 | 185 |
219 void Start() { | 186 void Start() { |
220 message_loop_->PostTask( | 187 message_loop_->PostTask( |
221 FROM_HERE, base::Bind(&TCPChannelTester::DoStart, this)); | 188 FROM_HERE, base::Bind(&TCPChannelTester::DoStart, this)); |
222 } | 189 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 } | 224 } |
258 | 225 |
259 void DoWrite() { | 226 void DoWrite() { |
260 int result = 1; | 227 int result = 1; |
261 while (result > 0) { | 228 while (result > 0) { |
262 if (output_buffer_->BytesRemaining() == 0) | 229 if (output_buffer_->BytesRemaining() == 0) |
263 break; | 230 break; |
264 | 231 |
265 int bytes_to_write = std::min(output_buffer_->BytesRemaining(), | 232 int bytes_to_write = std::min(output_buffer_->BytesRemaining(), |
266 kMessageSize); | 233 kMessageSize); |
267 result = client_socket_->Write(output_buffer_, bytes_to_write, | 234 result = client_socket_->Write( |
268 &write_cb_); | 235 output_buffer_, bytes_to_write, |
| 236 base::Bind(&TCPChannelTester::OnWritten, base::Unretained(this))); |
269 HandleWriteResult(result); | 237 HandleWriteResult(result); |
270 } | 238 } |
271 } | 239 } |
272 | 240 |
273 void OnWritten(int result) { | 241 void OnWritten(int result) { |
274 HandleWriteResult(result); | 242 HandleWriteResult(result); |
275 DoWrite(); | 243 DoWrite(); |
276 } | 244 } |
277 | 245 |
278 void HandleWriteResult(int result) { | 246 void HandleWriteResult(int result) { |
279 if (result <= 0 && result != net::ERR_IO_PENDING) { | 247 if (result <= 0 && result != net::ERR_IO_PENDING) { |
280 LOG(ERROR) << "Received error " << result << " when trying to write"; | 248 LOG(ERROR) << "Received error " << result << " when trying to write"; |
281 write_errors_++; | 249 write_errors_++; |
282 Done(); | 250 Done(); |
283 } else if (result > 0) { | 251 } else if (result > 0) { |
284 output_buffer_->DidConsume(result); | 252 output_buffer_->DidConsume(result); |
285 } | 253 } |
286 } | 254 } |
287 | 255 |
288 void DoRead() { | 256 void DoRead() { |
289 int result = 1; | 257 int result = 1; |
290 while (result > 0) { | 258 while (result > 0) { |
291 input_buffer_->set_offset(input_buffer_->capacity() - kMessageSize); | 259 input_buffer_->set_offset(input_buffer_->capacity() - kMessageSize); |
292 | 260 |
293 result = host_socket_->Read(input_buffer_, kMessageSize, &read_cb_); | 261 result = host_socket_->Read(input_buffer_, kMessageSize, |
| 262 base::Bind(&TCPChannelTester::OnRead, |
| 263 base::Unretained(this))); |
294 HandleReadResult(result); | 264 HandleReadResult(result); |
295 }; | 265 }; |
296 } | 266 } |
297 | 267 |
298 void OnRead(int result) { | 268 void OnRead(int result) { |
299 HandleReadResult(result); | 269 HandleReadResult(result); |
300 DoRead(); | 270 DoRead(); |
301 } | 271 } |
302 | 272 |
303 void HandleReadResult(int result) { | 273 void HandleReadResult(int result) { |
(...skipping 13 matching lines...) Expand all Loading... |
317 | 287 |
318 private: | 288 private: |
319 MessageLoop* message_loop_; | 289 MessageLoop* message_loop_; |
320 net::Socket* host_socket_; | 290 net::Socket* host_socket_; |
321 net::Socket* client_socket_; | 291 net::Socket* client_socket_; |
322 bool done_; | 292 bool done_; |
323 | 293 |
324 scoped_refptr<net::DrainableIOBuffer> output_buffer_; | 294 scoped_refptr<net::DrainableIOBuffer> output_buffer_; |
325 scoped_refptr<net::GrowableIOBuffer> input_buffer_; | 295 scoped_refptr<net::GrowableIOBuffer> input_buffer_; |
326 | 296 |
327 net::OldCompletionCallbackImpl<TCPChannelTester> write_cb_; | |
328 net::OldCompletionCallbackImpl<TCPChannelTester> read_cb_; | |
329 int write_errors_; | 297 int write_errors_; |
330 int read_errors_; | 298 int read_errors_; |
331 }; | 299 }; |
332 | 300 |
333 class PseudoTcpAdapterTest : public testing::Test { | 301 class PseudoTcpAdapterTest : public testing::Test { |
334 protected: | 302 protected: |
335 virtual void SetUp() OVERRIDE { | 303 virtual void SetUp() OVERRIDE { |
336 JingleThreadWrapper::EnsureForCurrentThread(); | 304 JingleThreadWrapper::EnsureForCurrentThread(); |
337 | 305 |
338 host_socket_ = new FakeSocket(); | 306 host_socket_ = new FakeSocket(); |
339 client_socket_ = new FakeSocket(); | 307 client_socket_ = new FakeSocket(); |
340 | 308 |
341 host_socket_->Connect(client_socket_); | 309 host_socket_->Connect(client_socket_); |
342 client_socket_->Connect(host_socket_); | 310 client_socket_->Connect(host_socket_); |
343 | 311 |
344 host_pseudotcp_.reset(new PseudoTcpAdapter(host_socket_)); | 312 host_pseudotcp_.reset(new PseudoTcpAdapter(host_socket_)); |
345 client_pseudotcp_.reset(new PseudoTcpAdapter(client_socket_)); | 313 client_pseudotcp_.reset(new PseudoTcpAdapter(client_socket_)); |
346 } | 314 } |
347 | 315 |
348 FakeSocket* host_socket_; | 316 FakeSocket* host_socket_; |
349 FakeSocket* client_socket_; | 317 FakeSocket* client_socket_; |
350 | 318 |
351 scoped_ptr<PseudoTcpAdapter> host_pseudotcp_; | 319 scoped_ptr<PseudoTcpAdapter> host_pseudotcp_; |
352 scoped_ptr<PseudoTcpAdapter> client_pseudotcp_; | 320 scoped_ptr<PseudoTcpAdapter> client_pseudotcp_; |
353 MessageLoop message_loop_; | 321 MessageLoop message_loop_; |
354 }; | 322 }; |
355 | 323 |
356 TEST_F(PseudoTcpAdapterTest, DataTransfer) { | 324 TEST_F(PseudoTcpAdapterTest, DataTransfer) { |
357 TestOldCompletionCallback host_connect_cb; | 325 net::TestCompletionCallback host_connect_cb; |
358 TestOldCompletionCallback client_connect_cb; | 326 net::TestCompletionCallback client_connect_cb; |
359 | 327 |
360 int rv1 = host_pseudotcp_->Connect(&host_connect_cb); | 328 int rv1 = host_pseudotcp_->Connect(host_connect_cb.callback()); |
361 int rv2 = client_pseudotcp_->Connect(&client_connect_cb); | 329 int rv2 = client_pseudotcp_->Connect(client_connect_cb.callback()); |
362 | 330 |
363 if (rv1 == net::ERR_IO_PENDING) | 331 if (rv1 == net::ERR_IO_PENDING) |
364 rv1 = host_connect_cb.WaitForResult(); | 332 rv1 = host_connect_cb.WaitForResult(); |
365 if (rv2 == net::ERR_IO_PENDING) | 333 if (rv2 == net::ERR_IO_PENDING) |
366 rv2 = client_connect_cb.WaitForResult(); | 334 rv2 = client_connect_cb.WaitForResult(); |
367 ASSERT_EQ(net::OK, rv1); | 335 ASSERT_EQ(net::OK, rv1); |
368 ASSERT_EQ(net::OK, rv2); | 336 ASSERT_EQ(net::OK, rv2); |
369 | 337 |
370 scoped_refptr<TCPChannelTester> tester = | 338 scoped_refptr<TCPChannelTester> tester = |
371 new TCPChannelTester(&message_loop_, host_pseudotcp_.get(), | 339 new TCPChannelTester(&message_loop_, host_pseudotcp_.get(), |
(...skipping 10 matching lines...) Expand all Loading... |
382 const int kBurstPackets = 10; | 350 const int kBurstPackets = 10; |
383 | 351 |
384 LeakyBucket host_limiter(kBurstPackets, kPacketsPerSecond); | 352 LeakyBucket host_limiter(kBurstPackets, kPacketsPerSecond); |
385 host_socket_->set_latency(kLatencyMs); | 353 host_socket_->set_latency(kLatencyMs); |
386 host_socket_->set_rate_limiter(&host_limiter); | 354 host_socket_->set_rate_limiter(&host_limiter); |
387 | 355 |
388 LeakyBucket client_limiter(kBurstPackets, kPacketsPerSecond); | 356 LeakyBucket client_limiter(kBurstPackets, kPacketsPerSecond); |
389 host_socket_->set_latency(kLatencyMs); | 357 host_socket_->set_latency(kLatencyMs); |
390 client_socket_->set_rate_limiter(&client_limiter); | 358 client_socket_->set_rate_limiter(&client_limiter); |
391 | 359 |
392 TestOldCompletionCallback host_connect_cb; | 360 net::TestCompletionCallback host_connect_cb; |
393 TestOldCompletionCallback client_connect_cb; | 361 net::TestCompletionCallback client_connect_cb; |
394 | 362 |
395 int rv1 = host_pseudotcp_->Connect(&host_connect_cb); | 363 int rv1 = host_pseudotcp_->Connect(host_connect_cb.callback()); |
396 int rv2 = client_pseudotcp_->Connect(&client_connect_cb); | 364 int rv2 = client_pseudotcp_->Connect(client_connect_cb.callback()); |
397 | 365 |
398 if (rv1 == net::ERR_IO_PENDING) | 366 if (rv1 == net::ERR_IO_PENDING) |
399 rv1 = host_connect_cb.WaitForResult(); | 367 rv1 = host_connect_cb.WaitForResult(); |
400 if (rv2 == net::ERR_IO_PENDING) | 368 if (rv2 == net::ERR_IO_PENDING) |
401 rv2 = client_connect_cb.WaitForResult(); | 369 rv2 = client_connect_cb.WaitForResult(); |
402 ASSERT_EQ(net::OK, rv1); | 370 ASSERT_EQ(net::OK, rv1); |
403 ASSERT_EQ(net::OK, rv2); | 371 ASSERT_EQ(net::OK, rv2); |
404 | 372 |
405 scoped_refptr<TCPChannelTester> tester = | 373 scoped_refptr<TCPChannelTester> tester = |
406 new TCPChannelTester(&message_loop_, host_pseudotcp_.get(), | 374 new TCPChannelTester(&message_loop_, host_pseudotcp_.get(), |
(...skipping 14 matching lines...) Expand all Loading... |
421 message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 389 message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
422 } | 390 } |
423 MessageLoop* message_loop_; | 391 MessageLoop* message_loop_; |
424 scoped_ptr<PseudoTcpAdapter>* adapter_; | 392 scoped_ptr<PseudoTcpAdapter>* adapter_; |
425 }; | 393 }; |
426 | 394 |
427 TEST_F(PseudoTcpAdapterTest, DeleteOnConnected) { | 395 TEST_F(PseudoTcpAdapterTest, DeleteOnConnected) { |
428 // This test verifies that deleting the adapter mid-callback doesn't lead | 396 // This test verifies that deleting the adapter mid-callback doesn't lead |
429 // to deleted structures being touched as the stack unrolls, so the failure | 397 // to deleted structures being touched as the stack unrolls, so the failure |
430 // mode is a crash rather than a normal test failure. | 398 // mode is a crash rather than a normal test failure. |
431 TestOldCompletionCallback client_connect_cb; | 399 net::TestCompletionCallback client_connect_cb; |
432 DeleteOnConnected host_delete(&message_loop_, &host_pseudotcp_); | 400 DeleteOnConnected host_delete(&message_loop_, &host_pseudotcp_); |
433 net::OldCompletionCallbackImpl<DeleteOnConnected> | |
434 host_connect_cb(&host_delete, &DeleteOnConnected::OnConnected); | |
435 | 401 |
436 host_pseudotcp_->Connect(&host_connect_cb); | 402 host_pseudotcp_->Connect(base::Bind(&DeleteOnConnected::OnConnected, |
437 client_pseudotcp_->Connect(&client_connect_cb); | 403 base::Unretained(&host_delete))); |
| 404 client_pseudotcp_->Connect(client_connect_cb.callback()); |
438 message_loop_.Run(); | 405 message_loop_.Run(); |
439 | 406 |
440 ASSERT_EQ(NULL, host_pseudotcp_.get()); | 407 ASSERT_EQ(NULL, host_pseudotcp_.get()); |
441 } | 408 } |
442 | 409 |
443 } // namespace | 410 } // namespace |
444 | 411 |
445 } // namespace jingle_glue | 412 } // namespace jingle_glue |
OLD | NEW |