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

Side by Side Diff: content/renderer/p2p/p2p_transport_impl_unittest.cc

Issue 10854131: Remove obsolete webkit_glue::P2PTransport interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
(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 "content/renderer/p2p/p2p_transport_impl.h"
6
7 #include "base/bind.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop.h"
11 #include "base/test/test_timeouts.h"
12 #include "jingle/glue/fake_network_manager.h"
13 #include "jingle/glue/fake_socket_factory.h"
14 #include "jingle/glue/thread_wrapper.h"
15 #include "net/base/completion_callback.h"
16 #include "net/base/io_buffer.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/net_util.h"
19 #include "net/socket/socket.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using testing::_;
24 using testing::AtMost;
25 using testing::Exactly;
26 using testing::InvokeWithoutArgs;
27
28 using webkit_glue::P2PTransport;
29
30 namespace {
31 const char kTestAddress1[] = "192.168.15.12";
32 const char kTestAddress2[] = "192.168.15.33";
33
34 const char kTransportName1[] = "tr1";
35 const char kTransportName2[] = "tr2";
36
37 // Send 10 packets 10 bytes each. Packets are sent with 10ms delay
38 // between packets (about 100 ms for 10 messages).
39 const int kMessageSize = 10;
40 const int kMessages = 10;
41 const int kUdpWriteDelayMs = 10;
42 const int kTcpDataSize = 10 * 1024;
43 const int kTcpWriteDelayMs = 1;
44
45 class UdpChannelTester : public base::RefCountedThreadSafe<UdpChannelTester> {
46 public:
47 UdpChannelTester(MessageLoop* message_loop,
48 net::Socket* write_socket,
49 net::Socket* read_socket)
50 : message_loop_(message_loop),
51 write_socket_(write_socket),
52 read_socket_(read_socket),
53 done_(false),
54 write_errors_(0),
55 read_errors_(0),
56 packets_sent_(0),
57 packets_received_(0),
58 broken_packets_(0) {
59 }
60
61 void Start() {
62 message_loop_->PostTask(
63 FROM_HERE, base::Bind(&UdpChannelTester::DoStart, this));
64 }
65
66 void CheckResults() {
67 EXPECT_EQ(0, write_errors_);
68 EXPECT_EQ(0, read_errors_);
69
70 EXPECT_EQ(0, broken_packets_);
71
72 // Verify that we've received at least one packet.
73 EXPECT_GT(packets_received_, 0);
74 LOG(INFO) << "Received " << packets_received_ << " packets out of "
75 << kMessages;
76 }
77
78 protected:
79 friend class base::RefCountedThreadSafe<UdpChannelTester>;
80 virtual ~UdpChannelTester() {}
81
82 void Done() {
83 done_ = true;
84 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
85 }
86
87 void DoStart() {
88 DoRead();
89 DoWrite();
90 }
91
92 void DoWrite() {
93 if (packets_sent_ >= kMessages) {
94 Done();
95 return;
96 }
97
98 scoped_refptr<net::IOBuffer> packet(new net::IOBuffer(kMessageSize));
99 memset(packet->data(), 123, kMessageSize);
100 sent_packets_[packets_sent_] = packet;
101 // Put index of this packet in the beginning of the packet body.
102 memcpy(packet->data(), &packets_sent_, sizeof(packets_sent_));
103
104 int result = write_socket_->Write(packet, kMessageSize,
105 base::Bind(&UdpChannelTester::OnWritten,
106 base::Unretained(this)));
107 HandleWriteResult(result);
108 }
109
110 void OnWritten(int result) {
111 HandleWriteResult(result);
112 }
113
114 void HandleWriteResult(int result) {
115 if (result <= 0 && result != net::ERR_IO_PENDING) {
116 LOG(ERROR) << "Received error " << result << " when trying to write";
117 write_errors_++;
118 Done();
119 } else if (result > 0) {
120 EXPECT_EQ(kMessageSize, result);
121 packets_sent_++;
122 message_loop_->PostDelayedTask(
123 FROM_HERE, base::Bind(&UdpChannelTester::DoWrite, this),
124 base::TimeDelta::FromMilliseconds(kUdpWriteDelayMs));
125 }
126 }
127
128 void DoRead() {
129 int result = 1;
130 while (result > 0) {
131 int kReadSize = kMessageSize * 2;
132 read_buffer_ = new net::IOBuffer(kReadSize);
133
134 result = read_socket_->Read(read_buffer_, kReadSize,
135 base::Bind(&UdpChannelTester::OnRead,
136 base::Unretained(this)));
137 HandleReadResult(result);
138 };
139 }
140
141 void OnRead(int result) {
142 HandleReadResult(result);
143 DoRead();
144 }
145
146 void HandleReadResult(int result) {
147 if (result <= 0 && result != net::ERR_IO_PENDING) {
148 // Error will be received after the socket is closed.
149 if (!done_) {
150 LOG(ERROR) << "Received error " << result << " when trying to read";
151 read_errors_++;
152 Done();
153 }
154 } else if (result > 0) {
155 packets_received_++;
156 if (kMessageSize != result) {
157 // Invalid packet size;
158 broken_packets_++;
159 } else {
160 // Validate packet body.
161 int packet_id;
162 memcpy(&packet_id, read_buffer_->data(), sizeof(packet_id));
163 if (packet_id < 0 || packet_id >= kMessages) {
164 broken_packets_++;
165 } else {
166 if (memcmp(read_buffer_->data(), sent_packets_[packet_id]->data(),
167 kMessageSize) != 0)
168 broken_packets_++;
169 }
170 }
171 }
172 }
173
174 private:
175 MessageLoop* message_loop_;
176 net::Socket* write_socket_;
177 net::Socket* read_socket_;
178 bool done_;
179
180 scoped_refptr<net::IOBuffer> sent_packets_[kMessages];
181 scoped_refptr<net::IOBuffer> read_buffer_;
182
183 int write_errors_;
184 int read_errors_;
185 int packets_sent_;
186 int packets_received_;
187 int broken_packets_;
188 };
189
190 class TcpChannelTester : public base::RefCountedThreadSafe<TcpChannelTester> {
191 public:
192 TcpChannelTester(MessageLoop* message_loop,
193 net::Socket* write_socket,
194 net::Socket* read_socket)
195 : message_loop_(message_loop),
196 write_socket_(write_socket),
197 read_socket_(read_socket),
198 done_(false),
199 write_errors_(0),
200 read_errors_(0) {
201 }
202
203 void Init() {
204 // Initialize |send_buffer_|.
205 send_buffer_ = new net::DrainableIOBuffer(new net::IOBuffer(kTcpDataSize),
206 kTcpDataSize);
207 for (int i = 0; i < kTcpDataSize; ++i) {
208 send_buffer_->data()[i] = rand() % 256;
209 }
210 }
211
212 void StartRead() {
213 message_loop_->PostTask(
214 FROM_HERE, base::Bind(&TcpChannelTester::DoRead, this));
215 }
216
217 void StartWrite() {
218 message_loop_->PostTask(
219 FROM_HERE, base::Bind(&TcpChannelTester::DoWrite, this));
220 }
221
222 void CheckResults() {
223 EXPECT_EQ(0, write_errors_);
224 EXPECT_EQ(0, read_errors_);
225
226 EXPECT_EQ(0, send_buffer_->BytesRemaining());
227
228 send_buffer_->SetOffset(0);
229 EXPECT_EQ(kTcpDataSize, static_cast<int>(received_data_.size()));
230 EXPECT_EQ(0, memcmp(send_buffer_->data(),
231 &received_data_[0], received_data_.size()));
232 }
233
234 protected:
235 friend class base::RefCountedThreadSafe<TcpChannelTester>;
236 virtual ~TcpChannelTester() {}
237
238 void Done() {
239 done_ = true;
240 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
241 }
242
243 void DoWrite() {
244 if (send_buffer_->BytesRemaining() == 0) {
245 return;
246 }
247
248 int result = write_socket_->Write(
249 send_buffer_, send_buffer_->BytesRemaining(),
250 base::Bind(&TcpChannelTester::OnWritten, base::Unretained(this)));
251 HandleWriteResult(result);
252 }
253
254 void OnWritten(int result) {
255 HandleWriteResult(result);
256 }
257
258 void HandleWriteResult(int result) {
259 if (result <= 0 && result != net::ERR_IO_PENDING) {
260 LOG(ERROR) << "Received error " << result << " when trying to write";
261 write_errors_++;
262 Done();
263 } else if (result > 0) {
264 send_buffer_->DidConsume(result);
265 message_loop_->PostDelayedTask(
266 FROM_HERE, base::Bind(&TcpChannelTester::DoWrite, this),
267 base::TimeDelta::FromMilliseconds(kTcpWriteDelayMs));
268 }
269 }
270
271 void DoRead() {
272 int result = 1;
273 while (result > 0) {
274 int kReadSize = kMessageSize * 2;
275 read_buffer_ = new net::IOBuffer(kReadSize);
276
277 result = read_socket_->Read(
278 read_buffer_, kReadSize,
279 base::Bind(&TcpChannelTester::OnRead, base::Unretained(this)));
280 HandleReadResult(result);
281 };
282 }
283
284 void OnRead(int result) {
285 HandleReadResult(result);
286 DoRead();
287 }
288
289 void HandleReadResult(int result) {
290 if (result <= 0 && result != net::ERR_IO_PENDING) {
291 // Error will be received after the socket is closed.
292 if (!done_) {
293 LOG(ERROR) << "Received error " << result << " when trying to read";
294 read_errors_++;
295 Done();
296 }
297 } else if (result > 0) {
298 received_data_.insert(received_data_.end(), read_buffer_->data(),
299 read_buffer_->data() + result);
300 if (static_cast<int>(received_data_.size()) == kTcpDataSize)
301 Done();
302 }
303 }
304
305 private:
306 MessageLoop* message_loop_;
307 net::Socket* write_socket_;
308 net::Socket* read_socket_;
309 bool done_;
310
311 scoped_refptr<net::DrainableIOBuffer> send_buffer_;
312 scoped_refptr<net::IOBuffer> read_buffer_;
313
314 std::vector<char> sent_data_;
315 std::vector<char> received_data_;
316
317 int write_errors_;
318 int read_errors_;
319 };
320
321 } // namespace
322
323 namespace content {
324
325 class MockP2PEventHandler : public P2PTransport::EventHandler {
326 public:
327 MOCK_METHOD1(OnCandidateReady, void(const std::string& address));
328 MOCK_METHOD1(OnStateChange, void(P2PTransport::State state));
329 MOCK_METHOD1(OnError, void(int error));
330 };
331
332 class P2PTransportImplTest : public testing::Test {
333 public:
334 void DestroyTransport() {
335 transport1_.reset();
336 transport2_.reset();
337 }
338
339 protected:
340 virtual void SetUp() OVERRIDE {
341 socket_manager_ = new jingle_glue::FakeSocketManager();
342
343 net::IPAddressNumber ip;
344 ASSERT_TRUE(net::ParseIPLiteralToNumber(kTestAddress1, &ip));
345 transport1_.reset(new P2PTransportImpl(
346 new jingle_glue::FakeNetworkManager(ip),
347 new jingle_glue::FakeSocketFactory(socket_manager_, ip)));
348
349 ASSERT_TRUE(net::ParseIPLiteralToNumber(kTestAddress2, &ip));
350 transport2_.reset(new P2PTransportImpl(
351 new jingle_glue::FakeNetworkManager(ip),
352 new jingle_glue::FakeSocketFactory(socket_manager_, ip)));
353 }
354
355 virtual void TearDown() OVERRIDE {
356 DestroyTransport();
357 message_loop_.RunAllPending();
358 }
359
360 void Init(P2PTransport::Protocol protocol) {
361 P2PTransport::Config config;
362 ASSERT_TRUE(transport1_->Init(
363 NULL, kTransportName1, protocol, config, &event_handler1_));
364 ASSERT_TRUE(transport2_->Init(
365 NULL, kTransportName2, protocol, config, &event_handler2_));
366 }
367
368 MessageLoop message_loop_;
369
370 scoped_refptr<jingle_glue::FakeSocketManager> socket_manager_;
371 scoped_ptr<P2PTransportImpl> transport1_;
372 MockP2PEventHandler event_handler1_;
373 scoped_ptr<P2PTransportImpl> transport2_;
374 MockP2PEventHandler event_handler2_;
375 };
376
377 TEST_F(P2PTransportImplTest, Create) {
378 Init(P2PTransport::PROTOCOL_UDP);
379
380 EXPECT_CALL(event_handler1_, OnCandidateReady(_));
381 EXPECT_CALL(event_handler2_, OnCandidateReady(_));
382
383 message_loop_.RunAllPending();
384 }
385
386 ACTION_P(AddRemoteCandidate, transport) {
387 EXPECT_TRUE(transport->AddRemoteCandidate(arg0));
388 }
389
390 TEST_F(P2PTransportImplTest, ConnectUdp) {
391 Init(P2PTransport::PROTOCOL_UDP);
392
393 EXPECT_CALL(event_handler1_, OnCandidateReady(_)).WillRepeatedly(
394 AddRemoteCandidate(transport2_.get()));
395 EXPECT_CALL(event_handler2_, OnCandidateReady(_)).WillRepeatedly(
396 AddRemoteCandidate(transport1_.get()));
397
398 message_loop_.RunAllPending();
399 }
400
401 TEST_F(P2PTransportImplTest, ConnectTcp) {
402 Init(P2PTransport::PROTOCOL_TCP);
403
404 EXPECT_CALL(event_handler1_, OnCandidateReady(_)).WillRepeatedly(
405 AddRemoteCandidate(transport2_.get()));
406 EXPECT_CALL(event_handler2_, OnCandidateReady(_)).WillRepeatedly(
407 AddRemoteCandidate(transport1_.get()));
408
409 message_loop_.RunAllPending();
410 }
411
412 TEST_F(P2PTransportImplTest, SendDataUdp) {
413 Init(P2PTransport::PROTOCOL_UDP);
414
415 EXPECT_CALL(event_handler1_, OnCandidateReady(_)).WillRepeatedly(
416 AddRemoteCandidate(transport2_.get()));
417 EXPECT_CALL(event_handler2_, OnCandidateReady(_)).WillRepeatedly(
418 AddRemoteCandidate(transport1_.get()));
419
420 // Transport may first become ether readable or writable, but
421 // eventually it must be readable and writable.
422 EXPECT_CALL(event_handler1_, OnStateChange(P2PTransport::STATE_READABLE))
423 .Times(AtMost(1));
424 EXPECT_CALL(event_handler1_, OnStateChange(P2PTransport::STATE_WRITABLE))
425 .Times(AtMost(1));
426 EXPECT_CALL(event_handler1_, OnStateChange(
427 static_cast<P2PTransport::State>(P2PTransport::STATE_READABLE |
428 P2PTransport::STATE_WRITABLE)))
429 .Times(Exactly(1));
430
431 EXPECT_CALL(event_handler2_, OnStateChange(P2PTransport::STATE_READABLE))
432 .Times(AtMost(1));
433 EXPECT_CALL(event_handler2_, OnStateChange(P2PTransport::STATE_WRITABLE))
434 .Times(AtMost(1));
435 EXPECT_CALL(event_handler2_, OnStateChange(
436 static_cast<P2PTransport::State>(P2PTransport::STATE_READABLE |
437 P2PTransport::STATE_WRITABLE)))
438 .Times(Exactly(1));
439
440 scoped_refptr<UdpChannelTester> channel_tester = new UdpChannelTester(
441 &message_loop_, transport1_->GetChannel(), transport2_->GetChannel());
442
443 message_loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
444 TestTimeouts::action_max_timeout());
445
446 channel_tester->Start();
447 message_loop_.Run();
448 channel_tester->CheckResults();
449 }
450
451 TEST_F(P2PTransportImplTest, SendDataTcp) {
452 Init(P2PTransport::PROTOCOL_TCP);
453
454 EXPECT_CALL(event_handler1_, OnCandidateReady(_)).WillRepeatedly(
455 AddRemoteCandidate(transport2_.get()));
456 EXPECT_CALL(event_handler2_, OnCandidateReady(_)).WillRepeatedly(
457 AddRemoteCandidate(transport1_.get()));
458
459 scoped_refptr<TcpChannelTester> channel_tester = new TcpChannelTester(
460 &message_loop_, transport1_->GetChannel(), transport2_->GetChannel());
461
462 // Transport may first become ether readable or writable, but
463 // eventually it must be readable and writable.
464 EXPECT_CALL(event_handler1_, OnStateChange(P2PTransport::STATE_READABLE))
465 .Times(AtMost(1));
466 EXPECT_CALL(event_handler1_, OnStateChange(P2PTransport::STATE_WRITABLE))
467 .Times(AtMost(1));
468 EXPECT_CALL(event_handler1_, OnStateChange(
469 static_cast<P2PTransport::State>(P2PTransport::STATE_READABLE |
470 P2PTransport::STATE_WRITABLE)))
471 .Times(Exactly(1))
472 .WillOnce(InvokeWithoutArgs(channel_tester.get(),
473 &TcpChannelTester::StartWrite))
474 .RetiresOnSaturation();
475
476 EXPECT_CALL(event_handler2_, OnStateChange(P2PTransport::STATE_READABLE))
477 .Times(AtMost(1));
478 EXPECT_CALL(event_handler2_, OnStateChange(P2PTransport::STATE_WRITABLE))
479 .Times(AtMost(1));
480 EXPECT_CALL(event_handler2_, OnStateChange(
481 static_cast<P2PTransport::State>(P2PTransport::STATE_READABLE |
482 P2PTransport::STATE_WRITABLE)))
483 .Times(Exactly(1))
484 .WillOnce(InvokeWithoutArgs(channel_tester.get(),
485 &TcpChannelTester::StartRead))
486 .RetiresOnSaturation();
487
488 message_loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
489 TestTimeouts::action_max_timeout());
490
491 channel_tester->Init();
492 message_loop_.Run();
493 channel_tester->CheckResults();
494 }
495
496 TEST_F(P2PTransportImplTest, DeleteFromCallback) {
497 Init(P2PTransport::PROTOCOL_TCP);
498
499 EXPECT_CALL(event_handler1_, OnCandidateReady(_)).WillRepeatedly(
500 AddRemoteCandidate(transport2_.get()));
501 EXPECT_CALL(event_handler2_, OnCandidateReady(_)).WillRepeatedly(
502 AddRemoteCandidate(transport1_.get()));
503
504 // Transport may first become ether readable or writable, but
505 // eventually it must be readable and writable.
506 EXPECT_CALL(event_handler1_, OnStateChange(P2PTransport::STATE_READABLE))
507 .Times(AtMost(1));
508 EXPECT_CALL(event_handler1_, OnStateChange(P2PTransport::STATE_WRITABLE))
509 .Times(AtMost(1));
510 EXPECT_CALL(event_handler1_, OnStateChange(
511 static_cast<P2PTransport::State>(P2PTransport::STATE_READABLE |
512 P2PTransport::STATE_WRITABLE)))
513 .Times(AtMost(1));
514
515 EXPECT_CALL(event_handler2_, OnStateChange(P2PTransport::STATE_READABLE))
516 .Times(AtMost(1));
517 EXPECT_CALL(event_handler2_, OnStateChange(P2PTransport::STATE_WRITABLE))
518 .Times(AtMost(1));
519 EXPECT_CALL(event_handler2_, OnStateChange(
520 static_cast<P2PTransport::State>(P2PTransport::STATE_READABLE |
521 P2PTransport::STATE_WRITABLE)))
522 .Times(Exactly(1))
523 .WillOnce(DoAll(
524 InvokeWithoutArgs(this, &P2PTransportImplTest::DestroyTransport),
525 InvokeWithoutArgs(&message_loop_, &MessageLoop::Quit)));
526
527 message_loop_.Run();
528 }
529
530 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698