OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 <stddef.h> | |
6 #include <stdint.h> | |
7 | |
8 #include <utility> | |
9 | |
10 #include "base/macros.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/run_loop.h" | |
13 #include "mojo/public/cpp/bindings/callback.h" | |
14 #include "mojo/services/network/public/cpp/udp_socket_wrapper.h" | |
15 #include "mojo/services/network/public/interfaces/network_service.mojom.h" | |
16 #include "mojo/services/network/public/interfaces/udp_socket.mojom.h" | |
17 #include "mojo/shell/public/cpp/shell_test.h" | |
18 #include "net/base/net_errors.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace mojo { | |
22 namespace service { | |
23 namespace { | |
24 | |
25 NetAddressPtr GetLocalHostWithAnyPort() { | |
26 NetAddressPtr addr(NetAddress::New()); | |
27 addr->family = NetAddressFamily::IPV4; | |
28 addr->ipv4 = NetAddressIPv4::New(); | |
29 addr->ipv4->port = 0; | |
30 addr->ipv4->addr.resize(4); | |
31 addr->ipv4->addr[0] = 127; | |
32 addr->ipv4->addr[1] = 0; | |
33 addr->ipv4->addr[2] = 0; | |
34 addr->ipv4->addr[3] = 1; | |
35 | |
36 return addr; | |
37 } | |
38 | |
39 Array<uint8_t> CreateTestMessage(uint8_t initial, size_t size) { | |
40 Array<uint8_t> array(size); | |
41 for (size_t i = 0; i < size; ++i) | |
42 array[i] = static_cast<uint8_t>((i + initial) % 256); | |
43 return array; | |
44 } | |
45 | |
46 template <typename CallbackType> | |
47 class TestCallbackBase { | |
48 public: | |
49 TestCallbackBase() : state_(nullptr), run_loop_(nullptr), ran_(false) {} | |
50 | |
51 ~TestCallbackBase() { | |
52 state_->set_test_callback(nullptr); | |
53 } | |
54 | |
55 CallbackType callback() const { return callback_; } | |
56 | |
57 void WaitForResult() { | |
58 if (ran_) | |
59 return; | |
60 | |
61 base::RunLoop run_loop; | |
62 run_loop_ = &run_loop; | |
63 run_loop.Run(); | |
64 run_loop_ = nullptr; | |
65 } | |
66 | |
67 protected: | |
68 struct StateBase : public CallbackType::Runnable { | |
69 StateBase() : test_callback_(nullptr) {} | |
70 ~StateBase() override {} | |
71 | |
72 void set_test_callback(TestCallbackBase* test_callback) { | |
73 test_callback_ = test_callback; | |
74 } | |
75 | |
76 protected: | |
77 void NotifyRun() const { | |
78 if (test_callback_) { | |
79 test_callback_->ran_ = true; | |
80 if (test_callback_->run_loop_) | |
81 test_callback_->run_loop_->Quit(); | |
82 } | |
83 } | |
84 | |
85 TestCallbackBase* test_callback_; | |
86 | |
87 private: | |
88 DISALLOW_COPY_AND_ASSIGN(StateBase); | |
89 }; | |
90 | |
91 // Takes ownership of |state|, and guarantees that it lives at least as long | |
92 // as this object. | |
93 void Initialize(StateBase* state) { | |
94 state_ = state; | |
95 state_->set_test_callback(this); | |
96 callback_ = CallbackType( | |
97 static_cast<typename CallbackType::Runnable*>(state_)); | |
98 } | |
99 | |
100 private: | |
101 // The lifespan is managed by |callback_| (and its copies). | |
102 StateBase* state_; | |
103 CallbackType callback_; | |
104 base::RunLoop* run_loop_; | |
105 bool ran_; | |
106 | |
107 DISALLOW_COPY_AND_ASSIGN(TestCallbackBase); | |
108 }; | |
109 | |
110 class TestCallback : public TestCallbackBase<Callback<void(NetworkErrorPtr)>> { | |
111 public: | |
112 TestCallback() { | |
113 Initialize(new State()); | |
114 } | |
115 ~TestCallback() {} | |
116 | |
117 const NetworkErrorPtr& result() const { return result_; } | |
118 | |
119 private: | |
120 struct State: public StateBase { | |
121 ~State() override {} | |
122 | |
123 void Run(NetworkErrorPtr result) const override { | |
124 if (test_callback_) { | |
125 TestCallback* callback = static_cast<TestCallback*>(test_callback_); | |
126 callback->result_ = std::move(result); | |
127 } | |
128 NotifyRun(); | |
129 } | |
130 }; | |
131 | |
132 NetworkErrorPtr result_; | |
133 }; | |
134 | |
135 class TestCallbackWithAddressAndReceiver | |
136 : public TestCallbackBase< | |
137 Callback<void(NetworkErrorPtr, | |
138 NetAddressPtr, | |
139 InterfaceRequest<UDPSocketReceiver>)>> { | |
140 public: | |
141 TestCallbackWithAddressAndReceiver() { Initialize(new State()); } | |
142 ~TestCallbackWithAddressAndReceiver() {} | |
143 | |
144 const NetworkErrorPtr& result() const { return result_; } | |
145 const NetAddressPtr& net_address() const { return net_address_; } | |
146 InterfaceRequest<UDPSocketReceiver>& receiver() { return receiver_; } | |
147 | |
148 private: | |
149 struct State : public StateBase { | |
150 ~State() override {} | |
151 | |
152 void Run(NetworkErrorPtr result, | |
153 NetAddressPtr net_address, | |
154 InterfaceRequest<UDPSocketReceiver> receiver) const override { | |
155 if (test_callback_) { | |
156 TestCallbackWithAddressAndReceiver* callback = | |
157 static_cast<TestCallbackWithAddressAndReceiver*>(test_callback_); | |
158 callback->result_ = std::move(result); | |
159 callback->net_address_ = std::move(net_address); | |
160 callback->receiver_ = std::move(receiver); | |
161 } | |
162 NotifyRun(); | |
163 } | |
164 }; | |
165 | |
166 NetworkErrorPtr result_; | |
167 NetAddressPtr net_address_; | |
168 InterfaceRequest<UDPSocketReceiver> receiver_; | |
169 }; | |
170 | |
171 class TestCallbackWithAddress | |
172 : public TestCallbackBase<Callback<void(NetworkErrorPtr, NetAddressPtr)>> { | |
173 public: | |
174 TestCallbackWithAddress() { | |
175 Initialize(new State()); | |
176 } | |
177 ~TestCallbackWithAddress() {} | |
178 | |
179 const NetworkErrorPtr& result() const { return result_; } | |
180 const NetAddressPtr& net_address() const { return net_address_; } | |
181 | |
182 private: | |
183 struct State : public StateBase { | |
184 ~State() override {} | |
185 | |
186 void Run(NetworkErrorPtr result, NetAddressPtr net_address) const override { | |
187 if (test_callback_) { | |
188 TestCallbackWithAddress* callback = | |
189 static_cast<TestCallbackWithAddress*>(test_callback_); | |
190 callback->result_ = std::move(result); | |
191 callback->net_address_ = std::move(net_address); | |
192 } | |
193 NotifyRun(); | |
194 } | |
195 }; | |
196 | |
197 NetworkErrorPtr result_; | |
198 NetAddressPtr net_address_; | |
199 }; | |
200 | |
201 class TestCallbackWithUint32 | |
202 : public TestCallbackBase<Callback<void(uint32_t)>> { | |
203 public: | |
204 TestCallbackWithUint32() : result_(0) { | |
205 Initialize(new State()); | |
206 } | |
207 ~TestCallbackWithUint32() {} | |
208 | |
209 uint32_t result() const { return result_; } | |
210 | |
211 private: | |
212 struct State : public StateBase { | |
213 ~State() override {} | |
214 | |
215 void Run(uint32_t result) const override { | |
216 if (test_callback_) { | |
217 TestCallbackWithUint32* callback = | |
218 static_cast<TestCallbackWithUint32*>(test_callback_); | |
219 callback->result_ = result; | |
220 } | |
221 NotifyRun(); | |
222 } | |
223 }; | |
224 | |
225 uint32_t result_; | |
226 }; | |
227 | |
228 class TestReceiveCallback | |
229 : public TestCallbackBase< | |
230 Callback<void(NetworkErrorPtr, NetAddressPtr, Array<uint8_t>)>> { | |
231 public: | |
232 TestReceiveCallback() { | |
233 Initialize(new State()); | |
234 } | |
235 ~TestReceiveCallback() {} | |
236 | |
237 const NetworkErrorPtr& result() const { return result_; } | |
238 const NetAddressPtr& src_addr() const { return src_addr_; } | |
239 const Array<uint8_t>& data() const { return data_; } | |
240 | |
241 private: | |
242 struct State : public StateBase { | |
243 ~State() override {} | |
244 | |
245 void Run(NetworkErrorPtr result, | |
246 NetAddressPtr src_addr, | |
247 Array<uint8_t> data) const override { | |
248 if (test_callback_) { | |
249 TestReceiveCallback* callback = | |
250 static_cast<TestReceiveCallback*>(test_callback_); | |
251 callback->result_ = std::move(result); | |
252 callback->src_addr_ = std::move(src_addr); | |
253 callback->data_ = std::move(data); | |
254 } | |
255 NotifyRun(); | |
256 } | |
257 }; | |
258 | |
259 NetworkErrorPtr result_; | |
260 NetAddressPtr src_addr_; | |
261 Array<uint8_t> data_; | |
262 }; | |
263 | |
264 struct ReceiveResult { | |
265 NetworkErrorPtr result; | |
266 NetAddressPtr addr; | |
267 Array<uint8_t> data; | |
268 }; | |
269 | |
270 class UDPSocketReceiverImpl : public UDPSocketReceiver { | |
271 public: | |
272 UDPSocketReceiverImpl() : run_loop_(nullptr), expected_receive_count_(0) {} | |
273 | |
274 ~UDPSocketReceiverImpl() override { | |
275 while (!results_.empty()) { | |
276 delete results_.front(); | |
277 results_.pop(); | |
278 } | |
279 } | |
280 | |
281 std::queue<ReceiveResult*>* results() { | |
282 return &results_; | |
283 } | |
284 | |
285 void WaitForReceiveResults(size_t count) { | |
286 if (results_.size() == count) | |
287 return; | |
288 | |
289 expected_receive_count_ = count; | |
290 base::RunLoop run_loop; | |
291 run_loop_ = &run_loop; | |
292 run_loop.Run(); | |
293 run_loop_ = nullptr; | |
294 } | |
295 | |
296 private: | |
297 void OnReceived(NetworkErrorPtr result, | |
298 NetAddressPtr src_addr, | |
299 Array<uint8_t> data) override { | |
300 ReceiveResult* entry = new ReceiveResult(); | |
301 entry->result = std::move(result); | |
302 entry->addr = std::move(src_addr); | |
303 entry->data = std::move(data); | |
304 | |
305 results_.push(entry); | |
306 | |
307 if (results_.size() == expected_receive_count_ && run_loop_) { | |
308 expected_receive_count_ = 0; | |
309 run_loop_->Quit(); | |
310 } | |
311 } | |
312 | |
313 base::RunLoop* run_loop_; | |
314 std::queue<ReceiveResult*> results_; | |
315 size_t expected_receive_count_; | |
316 | |
317 DISALLOW_COPY_AND_ASSIGN(UDPSocketReceiverImpl); | |
318 }; | |
319 | |
320 class UDPSocketTest : public test::ShellTest { | |
321 public: | |
322 UDPSocketTest() : ShellTest("exe:network_service_unittests"), | |
323 receiver_binding_(&receiver_) {} | |
324 ~UDPSocketTest() override {} | |
325 | |
326 void SetUp() override { | |
327 ShellTest::SetUp(); | |
328 connector()->ConnectToInterface("mojo:network_service", &network_service_); | |
329 network_service_->CreateUDPSocket(GetProxy(&socket_)); | |
330 } | |
331 | |
332 protected: | |
333 NetworkServicePtr network_service_; | |
334 UDPSocketPtr socket_; | |
335 UDPSocketReceiverImpl receiver_; | |
336 Binding<UDPSocketReceiver> receiver_binding_; | |
337 | |
338 DISALLOW_COPY_AND_ASSIGN(UDPSocketTest); | |
339 }; | |
340 | |
341 } // namespace | |
342 | |
343 TEST_F(UDPSocketTest, Settings) { | |
344 TestCallback callback1; | |
345 socket_->AllowAddressReuse(callback1.callback()); | |
346 callback1.WaitForResult(); | |
347 EXPECT_EQ(net::OK, callback1.result()->code); | |
348 | |
349 // Should fail because the socket hasn't been bound. | |
350 TestCallback callback2; | |
351 socket_->SetSendBufferSize(1024, callback2.callback()); | |
352 callback2.WaitForResult(); | |
353 EXPECT_NE(net::OK, callback2.result()->code); | |
354 | |
355 // Should fail because the socket hasn't been bound. | |
356 TestCallback callback3; | |
357 socket_->SetReceiveBufferSize(2048, callback3.callback()); | |
358 callback3.WaitForResult(); | |
359 EXPECT_NE(net::OK, callback3.result()->code); | |
360 | |
361 TestCallbackWithAddressAndReceiver callback4; | |
362 socket_->Bind(GetLocalHostWithAnyPort(), callback4.callback()); | |
363 callback4.WaitForResult(); | |
364 EXPECT_EQ(net::OK, callback4.result()->code); | |
365 EXPECT_NE(0u, callback4.net_address()->ipv4->port); | |
366 | |
367 // Should fail because the socket has been bound. | |
368 TestCallback callback5; | |
369 socket_->AllowAddressReuse(callback5.callback()); | |
370 callback5.WaitForResult(); | |
371 EXPECT_NE(net::OK, callback5.result()->code); | |
372 | |
373 TestCallback callback6; | |
374 socket_->SetSendBufferSize(1024, callback6.callback()); | |
375 callback6.WaitForResult(); | |
376 EXPECT_EQ(net::OK, callback6.result()->code); | |
377 | |
378 TestCallback callback7; | |
379 socket_->SetReceiveBufferSize(2048, callback7.callback()); | |
380 callback7.WaitForResult(); | |
381 EXPECT_EQ(net::OK, callback7.result()->code); | |
382 | |
383 TestCallbackWithUint32 callback8; | |
384 socket_->NegotiateMaxPendingSendRequests(0, callback8.callback()); | |
385 callback8.WaitForResult(); | |
386 EXPECT_GT(callback8.result(), 0u); | |
387 | |
388 TestCallbackWithUint32 callback9; | |
389 socket_->NegotiateMaxPendingSendRequests(16, callback9.callback()); | |
390 callback9.WaitForResult(); | |
391 EXPECT_GT(callback9.result(), 0u); | |
392 } | |
393 | |
394 TEST_F(UDPSocketTest, TestReadWrite) { | |
395 TestCallbackWithAddressAndReceiver callback1; | |
396 socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback()); | |
397 callback1.WaitForResult(); | |
398 ASSERT_EQ(net::OK, callback1.result()->code); | |
399 ASSERT_NE(0u, callback1.net_address()->ipv4->port); | |
400 | |
401 receiver_binding_.Bind(std::move(callback1.receiver())); | |
402 | |
403 NetAddressPtr server_addr = callback1.net_address().Clone(); | |
404 | |
405 UDPSocketPtr client_socket; | |
406 network_service_->CreateUDPSocket(GetProxy(&client_socket)); | |
407 | |
408 TestCallbackWithAddressAndReceiver callback2; | |
409 client_socket->Bind(GetLocalHostWithAnyPort(), callback2.callback()); | |
410 callback2.WaitForResult(); | |
411 ASSERT_EQ(net::OK, callback2.result()->code); | |
412 ASSERT_NE(0u, callback2.net_address()->ipv4->port); | |
413 | |
414 NetAddressPtr client_addr = callback2.net_address().Clone(); | |
415 | |
416 const size_t kDatagramCount = 6; | |
417 const size_t kDatagramSize = 255; | |
418 socket_->ReceiveMore(kDatagramCount); | |
419 | |
420 for (size_t i = 0; i < kDatagramCount; ++i) { | |
421 TestCallback callback; | |
422 client_socket->SendTo( | |
423 server_addr.Clone(), | |
424 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize), | |
425 callback.callback()); | |
426 callback.WaitForResult(); | |
427 EXPECT_EQ(255, callback.result()->code); | |
428 } | |
429 | |
430 receiver_.WaitForReceiveResults(kDatagramCount); | |
431 for (size_t i = 0; i < kDatagramCount; ++i) { | |
432 scoped_ptr<ReceiveResult> result(receiver_.results()->front()); | |
433 receiver_.results()->pop(); | |
434 | |
435 EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code); | |
436 EXPECT_TRUE(result->addr.Equals(client_addr)); | |
437 EXPECT_TRUE(result->data.Equals( | |
438 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize))); | |
439 } | |
440 } | |
441 | |
442 TEST_F(UDPSocketTest, TestConnectedReadWrite) { | |
443 TestCallbackWithAddressAndReceiver callback1; | |
444 socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback()); | |
445 callback1.WaitForResult(); | |
446 ASSERT_EQ(net::OK, callback1.result()->code); | |
447 ASSERT_NE(0u, callback1.net_address()->ipv4->port); | |
448 | |
449 receiver_binding_.Bind(std::move(callback1.receiver())); | |
450 | |
451 NetAddressPtr server_addr = callback1.net_address().Clone(); | |
452 | |
453 UDPSocketPtr client_socket; | |
454 network_service_->CreateUDPSocket(GetProxy(&client_socket)); | |
455 | |
456 TestCallbackWithAddressAndReceiver callback2; | |
457 client_socket->Connect(server_addr.Clone(), callback2.callback()); | |
458 callback2.WaitForResult(); | |
459 ASSERT_EQ(net::OK, callback2.result()->code); | |
460 ASSERT_NE(0u, callback2.net_address()->ipv4->port); | |
461 | |
462 UDPSocketReceiverImpl client_socket_receiver; | |
463 Binding<UDPSocketReceiver> client_receiver_binding( | |
464 &client_socket_receiver, std::move(callback2.receiver())); | |
465 | |
466 NetAddressPtr client_addr = callback2.net_address().Clone(); | |
467 | |
468 const size_t kDatagramCount = 6; | |
469 const size_t kDatagramSize = 255; | |
470 | |
471 // Test send using a connected socket. | |
472 socket_->ReceiveMore(kDatagramCount); | |
473 | |
474 for (size_t i = 0; i < kDatagramCount; ++i) { | |
475 TestCallback callback; | |
476 client_socket->SendTo( | |
477 nullptr, | |
478 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize), | |
479 callback.callback()); | |
480 callback.WaitForResult(); | |
481 EXPECT_EQ(255, callback.result()->code); | |
482 } | |
483 | |
484 receiver_.WaitForReceiveResults(kDatagramCount); | |
485 for (size_t i = 0; i < kDatagramCount; ++i) { | |
486 scoped_ptr<ReceiveResult> result(receiver_.results()->front()); | |
487 receiver_.results()->pop(); | |
488 | |
489 EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code); | |
490 EXPECT_TRUE(result->addr.Equals(client_addr)); | |
491 EXPECT_TRUE(result->data.Equals( | |
492 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize))); | |
493 } | |
494 | |
495 // Test receive using a connected socket. | |
496 client_socket->ReceiveMore(kDatagramCount); | |
497 | |
498 for (size_t i = 0; i < kDatagramCount; ++i) { | |
499 TestCallback callback; | |
500 socket_->SendTo( | |
501 client_addr.Clone(), | |
502 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize), | |
503 callback.callback()); | |
504 callback.WaitForResult(); | |
505 EXPECT_EQ(255, callback.result()->code); | |
506 } | |
507 | |
508 client_socket_receiver.WaitForReceiveResults(kDatagramCount); | |
509 for (size_t i = 0; i < kDatagramCount; ++i) { | |
510 scoped_ptr<ReceiveResult> result(client_socket_receiver.results()->front()); | |
511 client_socket_receiver.results()->pop(); | |
512 | |
513 EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code); | |
514 EXPECT_FALSE(result->addr); | |
515 EXPECT_TRUE(result->data.Equals( | |
516 CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize))); | |
517 } | |
518 } | |
519 | |
520 TEST_F(UDPSocketTest, TestWrapperReadWrite) { | |
521 UDPSocketWrapper socket(std::move(socket_), 4, 4); | |
522 | |
523 TestCallbackWithAddress callback1; | |
524 socket.Bind(GetLocalHostWithAnyPort(), callback1.callback()); | |
525 callback1.WaitForResult(); | |
526 ASSERT_EQ(net::OK, callback1.result()->code); | |
527 ASSERT_NE(0u, callback1.net_address()->ipv4->port); | |
528 | |
529 NetAddressPtr server_addr = callback1.net_address().Clone(); | |
530 | |
531 UDPSocketPtr raw_client_socket; | |
532 network_service_->CreateUDPSocket(GetProxy(&raw_client_socket)); | |
533 UDPSocketWrapper client_socket(std::move(raw_client_socket), 4, 4); | |
534 | |
535 TestCallbackWithAddress callback2; | |
536 client_socket.Bind(GetLocalHostWithAnyPort(), callback2.callback()); | |
537 callback2.WaitForResult(); | |
538 ASSERT_EQ(net::OK, callback2.result()->code); | |
539 ASSERT_NE(0u, callback2.net_address()->ipv4->port); | |
540 | |
541 NetAddressPtr client_addr = callback2.net_address().Clone(); | |
542 | |
543 const size_t kDatagramCount = 16; | |
544 const size_t kDatagramSize = 255; | |
545 | |
546 for (size_t i = 1; i < kDatagramCount; ++i) { | |
547 scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]); | |
548 scoped_ptr<TestReceiveCallback[]> receive_callbacks( | |
549 new TestReceiveCallback[i]); | |
550 | |
551 for (size_t j = 0; j < i; ++j) { | |
552 client_socket.SendTo( | |
553 server_addr.Clone(), | |
554 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize), | |
555 send_callbacks[j].callback()); | |
556 | |
557 socket.ReceiveFrom(receive_callbacks[j].callback()); | |
558 } | |
559 | |
560 receive_callbacks[i - 1].WaitForResult(); | |
561 | |
562 for (size_t j = 0; j < i; ++j) { | |
563 EXPECT_EQ(static_cast<int>(kDatagramSize), | |
564 receive_callbacks[j].result()->code); | |
565 EXPECT_TRUE(receive_callbacks[j].src_addr().Equals(client_addr)); | |
566 EXPECT_TRUE(receive_callbacks[j].data().Equals( | |
567 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize))); | |
568 } | |
569 } | |
570 } | |
571 | |
572 TEST_F(UDPSocketTest, TestWrapperConnectedReadWrite) { | |
573 UDPSocketWrapper socket(std::move(socket_), 4, 4); | |
574 | |
575 TestCallbackWithAddress callback1; | |
576 socket.Bind(GetLocalHostWithAnyPort(), callback1.callback()); | |
577 callback1.WaitForResult(); | |
578 ASSERT_EQ(net::OK, callback1.result()->code); | |
579 ASSERT_NE(0u, callback1.net_address()->ipv4->port); | |
580 | |
581 NetAddressPtr server_addr = callback1.net_address().Clone(); | |
582 | |
583 UDPSocketPtr raw_client_socket; | |
584 network_service_->CreateUDPSocket(GetProxy(&raw_client_socket)); | |
585 UDPSocketWrapper client_socket(std::move(raw_client_socket), 4, 4); | |
586 | |
587 TestCallbackWithAddress callback2; | |
588 client_socket.Connect(std::move(server_addr), callback2.callback()); | |
589 callback2.WaitForResult(); | |
590 ASSERT_EQ(net::OK, callback2.result()->code); | |
591 ASSERT_NE(0u, callback2.net_address()->ipv4->port); | |
592 | |
593 NetAddressPtr client_addr = callback2.net_address().Clone(); | |
594 | |
595 const size_t kDatagramCount = 16; | |
596 const size_t kDatagramSize = 255; | |
597 | |
598 // Test send using a connected socket. | |
599 for (size_t i = 1; i < kDatagramCount; ++i) { | |
600 scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]); | |
601 scoped_ptr<TestReceiveCallback[]> receive_callbacks( | |
602 new TestReceiveCallback[i]); | |
603 | |
604 for (size_t j = 0; j < i; ++j) { | |
605 client_socket.SendTo( | |
606 nullptr, | |
607 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize), | |
608 send_callbacks[j].callback()); | |
609 | |
610 socket.ReceiveFrom(receive_callbacks[j].callback()); | |
611 } | |
612 | |
613 receive_callbacks[i - 1].WaitForResult(); | |
614 | |
615 for (size_t j = 0; j < i; ++j) { | |
616 EXPECT_EQ(static_cast<int>(kDatagramSize), | |
617 receive_callbacks[j].result()->code); | |
618 EXPECT_TRUE(receive_callbacks[j].src_addr().Equals(client_addr)); | |
619 EXPECT_TRUE(receive_callbacks[j].data().Equals( | |
620 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize))); | |
621 } | |
622 } | |
623 | |
624 // Test receive using a connected socket. | |
625 for (size_t i = 1; i < kDatagramCount; ++i) { | |
626 scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]); | |
627 scoped_ptr<TestReceiveCallback[]> receive_callbacks( | |
628 new TestReceiveCallback[i]); | |
629 | |
630 for (size_t j = 0; j < i; ++j) { | |
631 socket.SendTo( | |
632 client_addr.Clone(), | |
633 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize), | |
634 send_callbacks[j].callback()); | |
635 | |
636 client_socket.ReceiveFrom(receive_callbacks[j].callback()); | |
637 } | |
638 | |
639 receive_callbacks[i - 1].WaitForResult(); | |
640 | |
641 for (size_t j = 0; j < i; ++j) { | |
642 EXPECT_EQ(static_cast<int>(kDatagramSize), | |
643 receive_callbacks[j].result()->code); | |
644 EXPECT_FALSE(receive_callbacks[j].src_addr()); | |
645 EXPECT_TRUE(receive_callbacks[j].data().Equals( | |
646 CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize))); | |
647 } | |
648 } | |
649 } | |
650 | |
651 } // namespace service | |
652 } // namespace mojo | |
OLD | NEW |