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.
5 #include "base/macros.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/run_loop.h"
8 #include "mojo/application/public/cpp/application_connection.h"
9 #include "mojo/application/public/cpp/application_impl.h"
10 #include "mojo/application/public/cpp/application_test_base.h"
11 #include "mojo/public/cpp/bindings/callback.h"
12 #include "mojo/services/network/public/cpp/udp_socket_wrapper.h"
13 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
14 #include "mojo/services/network/public/interfaces/udp_socket.mojom.h"
15 #include "net/base/net_errors.h"
16 #include "testing/gtest/include/gtest/gtest.h"
22 NetAddressPtr
GetLocalHostWithAnyPort() {
23 NetAddressPtr
addr(NetAddress::New());
24 addr
->family
= NET_ADDRESS_FAMILY_IPV4
;
25 addr
->ipv4
= NetAddressIPv4::New();
27 addr
->ipv4
->addr
.resize(4);
28 addr
->ipv4
->addr
[0] = 127;
29 addr
->ipv4
->addr
[1] = 0;
30 addr
->ipv4
->addr
[2] = 0;
31 addr
->ipv4
->addr
[3] = 1;
36 Array
<uint8_t> CreateTestMessage(uint8_t initial
, size_t size
) {
37 Array
<uint8_t> array(size
);
38 for (size_t i
= 0; i
< size
; ++i
)
39 array
[i
] = static_cast<uint8_t>((i
+ initial
) % 256);
43 template <typename CallbackType
>
44 class TestCallbackBase
{
46 TestCallbackBase() : state_(nullptr), run_loop_(nullptr), ran_(false) {}
49 state_
->set_test_callback(nullptr);
52 CallbackType
callback() const { return callback_
; }
54 void WaitForResult() {
58 base::RunLoop run_loop
;
59 run_loop_
= &run_loop
;
65 struct StateBase
: public CallbackType::Runnable
{
66 StateBase() : test_callback_(nullptr) {}
67 ~StateBase() override
{}
69 void set_test_callback(TestCallbackBase
* test_callback
) {
70 test_callback_
= test_callback
;
74 void NotifyRun() const {
76 test_callback_
->ran_
= true;
77 if (test_callback_
->run_loop_
)
78 test_callback_
->run_loop_
->Quit();
82 TestCallbackBase
* test_callback_
;
85 DISALLOW_COPY_AND_ASSIGN(StateBase
);
88 // Takes ownership of |state|, and guarantees that it lives at least as long
90 void Initialize(StateBase
* state
) {
92 state_
->set_test_callback(this);
93 callback_
= CallbackType(
94 static_cast<typename
CallbackType::Runnable
*>(state_
));
98 // The lifespan is managed by |callback_| (and its copies).
100 CallbackType callback_
;
101 base::RunLoop
* run_loop_
;
104 DISALLOW_COPY_AND_ASSIGN(TestCallbackBase
);
107 class TestCallback
: public TestCallbackBase
<Callback
<void(NetworkErrorPtr
)>> {
110 Initialize(new State());
114 const NetworkErrorPtr
& result() const { return result_
; }
117 struct State
: public StateBase
{
120 void Run(NetworkErrorPtr result
) const override
{
121 if (test_callback_
) {
122 TestCallback
* callback
= static_cast<TestCallback
*>(test_callback_
);
123 callback
->result_
= result
.Pass();
129 NetworkErrorPtr result_
;
132 class TestCallbackWithAddressAndReceiver
133 : public TestCallbackBase
<
134 Callback
<void(NetworkErrorPtr
,
136 InterfaceRequest
<UDPSocketReceiver
>)>> {
138 TestCallbackWithAddressAndReceiver() { Initialize(new State()); }
139 ~TestCallbackWithAddressAndReceiver() {}
141 const NetworkErrorPtr
& result() const { return result_
; }
142 const NetAddressPtr
& net_address() const { return net_address_
; }
143 InterfaceRequest
<UDPSocketReceiver
>& receiver() { return receiver_
; }
146 struct State
: public StateBase
{
149 void Run(NetworkErrorPtr result
,
150 NetAddressPtr net_address
,
151 InterfaceRequest
<UDPSocketReceiver
> receiver
) const override
{
152 if (test_callback_
) {
153 TestCallbackWithAddressAndReceiver
* callback
=
154 static_cast<TestCallbackWithAddressAndReceiver
*>(test_callback_
);
155 callback
->result_
= result
.Pass();
156 callback
->net_address_
= net_address
.Pass();
157 callback
->receiver_
= receiver
.Pass();
163 NetworkErrorPtr result_
;
164 NetAddressPtr net_address_
;
165 InterfaceRequest
<UDPSocketReceiver
> receiver_
;
168 class TestCallbackWithAddress
169 : public TestCallbackBase
<Callback
<void(NetworkErrorPtr
, NetAddressPtr
)>> {
171 TestCallbackWithAddress() {
172 Initialize(new State());
174 ~TestCallbackWithAddress() {}
176 const NetworkErrorPtr
& result() const { return result_
; }
177 const NetAddressPtr
& net_address() const { return net_address_
; }
180 struct State
: public StateBase
{
183 void Run(NetworkErrorPtr result
, NetAddressPtr net_address
) const override
{
184 if (test_callback_
) {
185 TestCallbackWithAddress
* callback
=
186 static_cast<TestCallbackWithAddress
*>(test_callback_
);
187 callback
->result_
= result
.Pass();
188 callback
->net_address_
= net_address
.Pass();
194 NetworkErrorPtr result_
;
195 NetAddressPtr net_address_
;
198 class TestCallbackWithUint32
199 : public TestCallbackBase
<Callback
<void(uint32_t)>> {
201 TestCallbackWithUint32() : result_(0) {
202 Initialize(new State());
204 ~TestCallbackWithUint32() {}
206 uint32_t result() const { return result_
; }
209 struct State
: public StateBase
{
212 void Run(uint32_t result
) const override
{
213 if (test_callback_
) {
214 TestCallbackWithUint32
* callback
=
215 static_cast<TestCallbackWithUint32
*>(test_callback_
);
216 callback
->result_
= result
;
225 class TestReceiveCallback
226 : public TestCallbackBase
<
227 Callback
<void(NetworkErrorPtr
, NetAddressPtr
, Array
<uint8_t>)>> {
229 TestReceiveCallback() {
230 Initialize(new State());
232 ~TestReceiveCallback() {}
234 const NetworkErrorPtr
& result() const { return result_
; }
235 const NetAddressPtr
& src_addr() const { return src_addr_
; }
236 const Array
<uint8_t>& data() const { return data_
; }
239 struct State
: public StateBase
{
242 void Run(NetworkErrorPtr result
,
243 NetAddressPtr src_addr
,
244 Array
<uint8_t> data
) const override
{
245 if (test_callback_
) {
246 TestReceiveCallback
* callback
=
247 static_cast<TestReceiveCallback
*>(test_callback_
);
248 callback
->result_
= result
.Pass();
249 callback
->src_addr_
= src_addr
.Pass();
250 callback
->data_
= data
.Pass();
256 NetworkErrorPtr result_
;
257 NetAddressPtr src_addr_
;
258 Array
<uint8_t> data_
;
261 struct ReceiveResult
{
262 NetworkErrorPtr result
;
267 class UDPSocketReceiverImpl
: public UDPSocketReceiver
{
269 UDPSocketReceiverImpl() : run_loop_(nullptr), expected_receive_count_(0) {}
271 ~UDPSocketReceiverImpl() override
{
272 while (!results_
.empty()) {
273 delete results_
.front();
278 std::queue
<ReceiveResult
*>* results() {
282 void WaitForReceiveResults(size_t count
) {
283 if (results_
.size() == count
)
286 expected_receive_count_
= count
;
287 base::RunLoop run_loop
;
288 run_loop_
= &run_loop
;
294 void OnReceived(NetworkErrorPtr result
,
295 NetAddressPtr src_addr
,
296 Array
<uint8_t> data
) override
{
297 ReceiveResult
* entry
= new ReceiveResult();
298 entry
->result
= result
.Pass();
299 entry
->addr
= src_addr
.Pass();
300 entry
->data
= data
.Pass();
302 results_
.push(entry
);
304 if (results_
.size() == expected_receive_count_
&& run_loop_
) {
305 expected_receive_count_
= 0;
310 base::RunLoop
* run_loop_
;
311 std::queue
<ReceiveResult
*> results_
;
312 size_t expected_receive_count_
;
314 DISALLOW_COPY_AND_ASSIGN(UDPSocketReceiverImpl
);
317 class UDPSocketAppTest
: public test::ApplicationTestBase
{
319 UDPSocketAppTest() : receiver_binding_(&receiver_
) {}
320 ~UDPSocketAppTest() override
{}
322 void SetUp() override
{
323 ApplicationTestBase::SetUp();
325 mojo::URLRequestPtr
request(mojo::URLRequest::New());
326 request
->url
= mojo::String::From("mojo:network_service");
327 scoped_ptr
<ApplicationConnection
> connection
=
328 application_impl()->ConnectToApplication(request
.Pass());
329 connection
->ConnectToService(&network_service_
);
331 network_service_
->CreateUDPSocket(GetProxy(&socket_
));
335 NetworkServicePtr network_service_
;
336 UDPSocketPtr socket_
;
337 UDPSocketReceiverImpl receiver_
;
338 Binding
<UDPSocketReceiver
> receiver_binding_
;
340 DISALLOW_COPY_AND_ASSIGN(UDPSocketAppTest
);
345 TEST_F(UDPSocketAppTest
, Settings
) {
346 TestCallback callback1
;
347 socket_
->AllowAddressReuse(callback1
.callback());
348 callback1
.WaitForResult();
349 EXPECT_EQ(net::OK
, callback1
.result()->code
);
351 // Should fail because the socket hasn't been bound.
352 TestCallback callback2
;
353 socket_
->SetSendBufferSize(1024, callback2
.callback());
354 callback2
.WaitForResult();
355 EXPECT_NE(net::OK
, callback2
.result()->code
);
357 // Should fail because the socket hasn't been bound.
358 TestCallback callback3
;
359 socket_
->SetReceiveBufferSize(2048, callback3
.callback());
360 callback3
.WaitForResult();
361 EXPECT_NE(net::OK
, callback3
.result()->code
);
363 TestCallbackWithAddressAndReceiver callback4
;
364 socket_
->Bind(GetLocalHostWithAnyPort(), callback4
.callback());
365 callback4
.WaitForResult();
366 EXPECT_EQ(net::OK
, callback4
.result()->code
);
367 EXPECT_NE(0u, callback4
.net_address()->ipv4
->port
);
369 // Should fail because the socket has been bound.
370 TestCallback callback5
;
371 socket_
->AllowAddressReuse(callback5
.callback());
372 callback5
.WaitForResult();
373 EXPECT_NE(net::OK
, callback5
.result()->code
);
375 TestCallback callback6
;
376 socket_
->SetSendBufferSize(1024, callback6
.callback());
377 callback6
.WaitForResult();
378 EXPECT_EQ(net::OK
, callback6
.result()->code
);
380 TestCallback callback7
;
381 socket_
->SetReceiveBufferSize(2048, callback7
.callback());
382 callback7
.WaitForResult();
383 EXPECT_EQ(net::OK
, callback7
.result()->code
);
385 TestCallbackWithUint32 callback8
;
386 socket_
->NegotiateMaxPendingSendRequests(0, callback8
.callback());
387 callback8
.WaitForResult();
388 EXPECT_GT(callback8
.result(), 0u);
390 TestCallbackWithUint32 callback9
;
391 socket_
->NegotiateMaxPendingSendRequests(16, callback9
.callback());
392 callback9
.WaitForResult();
393 EXPECT_GT(callback9
.result(), 0u);
396 TEST_F(UDPSocketAppTest
, TestReadWrite
) {
397 TestCallbackWithAddressAndReceiver callback1
;
398 socket_
->Bind(GetLocalHostWithAnyPort(), callback1
.callback());
399 callback1
.WaitForResult();
400 ASSERT_EQ(net::OK
, callback1
.result()->code
);
401 ASSERT_NE(0u, callback1
.net_address()->ipv4
->port
);
403 receiver_binding_
.Bind(callback1
.receiver().Pass());
405 NetAddressPtr server_addr
= callback1
.net_address().Clone();
407 UDPSocketPtr client_socket
;
408 network_service_
->CreateUDPSocket(GetProxy(&client_socket
));
410 TestCallbackWithAddressAndReceiver callback2
;
411 client_socket
->Bind(GetLocalHostWithAnyPort(), callback2
.callback());
412 callback2
.WaitForResult();
413 ASSERT_EQ(net::OK
, callback2
.result()->code
);
414 ASSERT_NE(0u, callback2
.net_address()->ipv4
->port
);
416 NetAddressPtr client_addr
= callback2
.net_address().Clone();
418 const size_t kDatagramCount
= 6;
419 const size_t kDatagramSize
= 255;
420 socket_
->ReceiveMore(kDatagramCount
);
422 for (size_t i
= 0; i
< kDatagramCount
; ++i
) {
423 TestCallback callback
;
424 client_socket
->SendTo(
426 CreateTestMessage(static_cast<uint8_t>(i
), kDatagramSize
),
427 callback
.callback());
428 callback
.WaitForResult();
429 EXPECT_EQ(255, callback
.result()->code
);
432 receiver_
.WaitForReceiveResults(kDatagramCount
);
433 for (size_t i
= 0; i
< kDatagramCount
; ++i
) {
434 scoped_ptr
<ReceiveResult
> result(receiver_
.results()->front());
435 receiver_
.results()->pop();
437 EXPECT_EQ(static_cast<int>(kDatagramSize
), result
->result
->code
);
438 EXPECT_TRUE(result
->addr
.Equals(client_addr
));
439 EXPECT_TRUE(result
->data
.Equals(
440 CreateTestMessage(static_cast<uint8_t>(i
), kDatagramSize
)));
444 TEST_F(UDPSocketAppTest
, TestConnectedReadWrite
) {
445 TestCallbackWithAddressAndReceiver callback1
;
446 socket_
->Bind(GetLocalHostWithAnyPort(), callback1
.callback());
447 callback1
.WaitForResult();
448 ASSERT_EQ(net::OK
, callback1
.result()->code
);
449 ASSERT_NE(0u, callback1
.net_address()->ipv4
->port
);
451 receiver_binding_
.Bind(callback1
.receiver().Pass());
453 NetAddressPtr server_addr
= callback1
.net_address().Clone();
455 UDPSocketPtr client_socket
;
456 network_service_
->CreateUDPSocket(GetProxy(&client_socket
));
458 TestCallbackWithAddressAndReceiver callback2
;
459 client_socket
->Connect(server_addr
.Clone(), callback2
.callback());
460 callback2
.WaitForResult();
461 ASSERT_EQ(net::OK
, callback2
.result()->code
);
462 ASSERT_NE(0u, callback2
.net_address()->ipv4
->port
);
464 UDPSocketReceiverImpl client_socket_receiver
;
465 Binding
<UDPSocketReceiver
> client_receiver_binding(
466 &client_socket_receiver
, callback2
.receiver().Pass());
468 NetAddressPtr client_addr
= callback2
.net_address().Clone();
470 const size_t kDatagramCount
= 6;
471 const size_t kDatagramSize
= 255;
473 // Test send using a connected socket.
474 socket_
->ReceiveMore(kDatagramCount
);
476 for (size_t i
= 0; i
< kDatagramCount
; ++i
) {
477 TestCallback callback
;
478 client_socket
->SendTo(
480 CreateTestMessage(static_cast<uint8_t>(i
), kDatagramSize
),
481 callback
.callback());
482 callback
.WaitForResult();
483 EXPECT_EQ(255, callback
.result()->code
);
486 receiver_
.WaitForReceiveResults(kDatagramCount
);
487 for (size_t i
= 0; i
< kDatagramCount
; ++i
) {
488 scoped_ptr
<ReceiveResult
> result(receiver_
.results()->front());
489 receiver_
.results()->pop();
491 EXPECT_EQ(static_cast<int>(kDatagramSize
), result
->result
->code
);
492 EXPECT_TRUE(result
->addr
.Equals(client_addr
));
493 EXPECT_TRUE(result
->data
.Equals(
494 CreateTestMessage(static_cast<uint8_t>(i
), kDatagramSize
)));
497 // Test receive using a connected socket.
498 client_socket
->ReceiveMore(kDatagramCount
);
500 for (size_t i
= 0; i
< kDatagramCount
; ++i
) {
501 TestCallback callback
;
504 CreateTestMessage(static_cast<uint8_t>(i
), kDatagramSize
),
505 callback
.callback());
506 callback
.WaitForResult();
507 EXPECT_EQ(255, callback
.result()->code
);
510 client_socket_receiver
.WaitForReceiveResults(kDatagramCount
);
511 for (size_t i
= 0; i
< kDatagramCount
; ++i
) {
512 scoped_ptr
<ReceiveResult
> result(client_socket_receiver
.results()->front());
513 client_socket_receiver
.results()->pop();
515 EXPECT_EQ(static_cast<int>(kDatagramSize
), result
->result
->code
);
516 EXPECT_FALSE(result
->addr
);
517 EXPECT_TRUE(result
->data
.Equals(
518 CreateTestMessage(static_cast<uint8_t>(i
), kDatagramSize
)));
522 TEST_F(UDPSocketAppTest
, TestWrapperReadWrite
) {
523 UDPSocketWrapper
socket(socket_
.Pass(), 4, 4);
525 TestCallbackWithAddress callback1
;
526 socket
.Bind(GetLocalHostWithAnyPort(), callback1
.callback());
527 callback1
.WaitForResult();
528 ASSERT_EQ(net::OK
, callback1
.result()->code
);
529 ASSERT_NE(0u, callback1
.net_address()->ipv4
->port
);
531 NetAddressPtr server_addr
= callback1
.net_address().Clone();
533 UDPSocketPtr raw_client_socket
;
534 network_service_
->CreateUDPSocket(GetProxy(&raw_client_socket
));
535 UDPSocketWrapper
client_socket(raw_client_socket
.Pass(), 4, 4);
537 TestCallbackWithAddress callback2
;
538 client_socket
.Bind(GetLocalHostWithAnyPort(), callback2
.callback());
539 callback2
.WaitForResult();
540 ASSERT_EQ(net::OK
, callback2
.result()->code
);
541 ASSERT_NE(0u, callback2
.net_address()->ipv4
->port
);
543 NetAddressPtr client_addr
= callback2
.net_address().Clone();
545 const size_t kDatagramCount
= 16;
546 const size_t kDatagramSize
= 255;
548 for (size_t i
= 1; i
< kDatagramCount
; ++i
) {
549 scoped_ptr
<TestCallback
[]> send_callbacks(new TestCallback
[i
]);
550 scoped_ptr
<TestReceiveCallback
[]> receive_callbacks(
551 new TestReceiveCallback
[i
]);
553 for (size_t j
= 0; j
< i
; ++j
) {
554 client_socket
.SendTo(
556 CreateTestMessage(static_cast<uint8_t>(j
), kDatagramSize
),
557 send_callbacks
[j
].callback());
559 socket
.ReceiveFrom(receive_callbacks
[j
].callback());
562 receive_callbacks
[i
- 1].WaitForResult();
564 for (size_t j
= 0; j
< i
; ++j
) {
565 EXPECT_EQ(static_cast<int>(kDatagramSize
),
566 receive_callbacks
[j
].result()->code
);
567 EXPECT_TRUE(receive_callbacks
[j
].src_addr().Equals(client_addr
));
568 EXPECT_TRUE(receive_callbacks
[j
].data().Equals(
569 CreateTestMessage(static_cast<uint8_t>(j
), kDatagramSize
)));
574 TEST_F(UDPSocketAppTest
, TestWrapperConnectedReadWrite
) {
575 UDPSocketWrapper
socket(socket_
.Pass(), 4, 4);
577 TestCallbackWithAddress callback1
;
578 socket
.Bind(GetLocalHostWithAnyPort(), callback1
.callback());
579 callback1
.WaitForResult();
580 ASSERT_EQ(net::OK
, callback1
.result()->code
);
581 ASSERT_NE(0u, callback1
.net_address()->ipv4
->port
);
583 NetAddressPtr server_addr
= callback1
.net_address().Clone();
585 UDPSocketPtr raw_client_socket
;
586 network_service_
->CreateUDPSocket(GetProxy(&raw_client_socket
));
587 UDPSocketWrapper
client_socket(raw_client_socket
.Pass(), 4, 4);
589 TestCallbackWithAddress callback2
;
590 client_socket
.Connect(server_addr
.Pass(), callback2
.callback());
591 callback2
.WaitForResult();
592 ASSERT_EQ(net::OK
, callback2
.result()->code
);
593 ASSERT_NE(0u, callback2
.net_address()->ipv4
->port
);
595 NetAddressPtr client_addr
= callback2
.net_address().Clone();
597 const size_t kDatagramCount
= 16;
598 const size_t kDatagramSize
= 255;
600 // Test send using a connected socket.
601 for (size_t i
= 1; i
< kDatagramCount
; ++i
) {
602 scoped_ptr
<TestCallback
[]> send_callbacks(new TestCallback
[i
]);
603 scoped_ptr
<TestReceiveCallback
[]> receive_callbacks(
604 new TestReceiveCallback
[i
]);
606 for (size_t j
= 0; j
< i
; ++j
) {
607 client_socket
.SendTo(
609 CreateTestMessage(static_cast<uint8_t>(j
), kDatagramSize
),
610 send_callbacks
[j
].callback());
612 socket
.ReceiveFrom(receive_callbacks
[j
].callback());
615 receive_callbacks
[i
- 1].WaitForResult();
617 for (size_t j
= 0; j
< i
; ++j
) {
618 EXPECT_EQ(static_cast<int>(kDatagramSize
),
619 receive_callbacks
[j
].result()->code
);
620 EXPECT_TRUE(receive_callbacks
[j
].src_addr().Equals(client_addr
));
621 EXPECT_TRUE(receive_callbacks
[j
].data().Equals(
622 CreateTestMessage(static_cast<uint8_t>(j
), kDatagramSize
)));
626 // Test receive using a connected socket.
627 for (size_t i
= 1; i
< kDatagramCount
; ++i
) {
628 scoped_ptr
<TestCallback
[]> send_callbacks(new TestCallback
[i
]);
629 scoped_ptr
<TestReceiveCallback
[]> receive_callbacks(
630 new TestReceiveCallback
[i
]);
632 for (size_t j
= 0; j
< i
; ++j
) {
635 CreateTestMessage(static_cast<uint8_t>(j
), kDatagramSize
),
636 send_callbacks
[j
].callback());
638 client_socket
.ReceiveFrom(receive_callbacks
[j
].callback());
641 receive_callbacks
[i
- 1].WaitForResult();
643 for (size_t j
= 0; j
< i
; ++j
) {
644 EXPECT_EQ(static_cast<int>(kDatagramSize
),
645 receive_callbacks
[j
].result()->code
);
646 EXPECT_FALSE(receive_callbacks
[j
].src_addr());
647 EXPECT_TRUE(receive_callbacks
[j
].data().Equals(
648 CreateTestMessage(static_cast<uint8_t>(j
), kDatagramSize
)));
653 } // namespace service