Minor cleanups for EmbeddedSharedWorkerStub
[chromium-blink-merge.git] / net / udp / udp_socket_unittest.cc
blob3e31f9ec890db80443ef0279415711ba7d480a35
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.
5 #include "net/udp/udp_socket.h"
7 #include "net/udp/udp_client_socket.h"
8 #include "net/udp/udp_server_socket.h"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/location.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/metrics/histogram.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/stl_util.h"
18 #include "base/thread_task_runner_handle.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/ip_endpoint.h"
21 #include "net/base/net_errors.h"
22 #include "net/base/net_util.h"
23 #include "net/base/test_completion_callback.h"
24 #include "net/log/test_net_log.h"
25 #include "net/log/test_net_log_entry.h"
26 #include "net/log/test_net_log_util.h"
27 #include "net/test/net_test_suite.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
31 namespace net {
33 namespace {
35 class UDPSocketTest : public PlatformTest {
36 public:
37 UDPSocketTest() : buffer_(new IOBufferWithSize(kMaxRead)) {}
39 // Blocks until data is read from the socket.
40 std::string RecvFromSocket(UDPServerSocket* socket) {
41 TestCompletionCallback callback;
43 int rv = socket->RecvFrom(
44 buffer_.get(), kMaxRead, &recv_from_address_, callback.callback());
45 if (rv == ERR_IO_PENDING)
46 rv = callback.WaitForResult();
47 if (rv < 0)
48 return std::string(); // error!
49 return std::string(buffer_->data(), rv);
52 // Loop until |msg| has been written to the socket or until an
53 // error occurs.
54 // If |address| is specified, then it is used for the destination
55 // to send to. Otherwise, will send to the last socket this server
56 // received from.
57 int SendToSocket(UDPServerSocket* socket, std::string msg) {
58 return SendToSocket(socket, msg, recv_from_address_);
61 int SendToSocket(UDPServerSocket* socket,
62 std::string msg,
63 const IPEndPoint& address) {
64 TestCompletionCallback callback;
66 int length = msg.length();
67 scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg));
68 scoped_refptr<DrainableIOBuffer> buffer(
69 new DrainableIOBuffer(io_buffer.get(), length));
71 int bytes_sent = 0;
72 while (buffer->BytesRemaining()) {
73 int rv = socket->SendTo(
74 buffer.get(), buffer->BytesRemaining(), address, callback.callback());
75 if (rv == ERR_IO_PENDING)
76 rv = callback.WaitForResult();
77 if (rv <= 0)
78 return bytes_sent > 0 ? bytes_sent : rv;
79 bytes_sent += rv;
80 buffer->DidConsume(rv);
82 return bytes_sent;
85 std::string ReadSocket(UDPClientSocket* socket) {
86 TestCompletionCallback callback;
88 int rv = socket->Read(buffer_.get(), kMaxRead, callback.callback());
89 if (rv == ERR_IO_PENDING)
90 rv = callback.WaitForResult();
91 if (rv < 0)
92 return std::string(); // error!
93 return std::string(buffer_->data(), rv);
96 // Loop until |msg| has been written to the socket or until an
97 // error occurs.
98 int WriteSocket(UDPClientSocket* socket, std::string msg) {
99 TestCompletionCallback callback;
101 int length = msg.length();
102 scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg));
103 scoped_refptr<DrainableIOBuffer> buffer(
104 new DrainableIOBuffer(io_buffer.get(), length));
106 int bytes_sent = 0;
107 while (buffer->BytesRemaining()) {
108 int rv = socket->Write(
109 buffer.get(), buffer->BytesRemaining(), callback.callback());
110 if (rv == ERR_IO_PENDING)
111 rv = callback.WaitForResult();
112 if (rv <= 0)
113 return bytes_sent > 0 ? bytes_sent : rv;
114 bytes_sent += rv;
115 buffer->DidConsume(rv);
117 return bytes_sent;
120 void WriteSocketIgnoreResult(UDPClientSocket* socket, std::string msg) {
121 WriteSocket(socket, msg);
124 // Creates an address from ip address and port and writes it to |*address|.
125 void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) {
126 IPAddressNumber ip_number;
127 bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
128 if (!rv)
129 return;
130 *address = IPEndPoint(ip_number, port);
133 // Run unit test for a connection test.
134 // |use_nonblocking_io| is used to switch between overlapped and non-blocking
135 // IO on Windows. It has no effect in other ports.
136 void ConnectTest(bool use_nonblocking_io);
138 protected:
139 static const int kMaxRead = 1024;
140 scoped_refptr<IOBufferWithSize> buffer_;
141 IPEndPoint recv_from_address_;
144 void ReadCompleteCallback(int* result_out, base::Closure callback, int result) {
145 *result_out = result;
146 callback.Run();
149 void UDPSocketTest::ConnectTest(bool use_nonblocking_io) {
150 const uint16 kPort = 9999;
151 std::string simple_message("hello world!");
153 // Setup the server to listen.
154 IPEndPoint bind_address;
155 CreateUDPAddress("127.0.0.1", kPort, &bind_address);
156 TestNetLog server_log;
157 scoped_ptr<UDPServerSocket> server(
158 new UDPServerSocket(&server_log, NetLog::Source()));
159 #if defined(OS_WIN)
160 if (use_nonblocking_io)
161 server->UseNonBlockingIO();
162 #endif
163 server->AllowAddressReuse();
164 int rv = server->Listen(bind_address);
165 ASSERT_EQ(OK, rv);
167 // Setup the client.
168 IPEndPoint server_address;
169 CreateUDPAddress("127.0.0.1", kPort, &server_address);
170 TestNetLog client_log;
171 scoped_ptr<UDPClientSocket> client(
172 new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
173 &client_log, NetLog::Source()));
174 #if defined(OS_WIN)
175 if (use_nonblocking_io)
176 client->UseNonBlockingIO();
177 #endif
179 rv = client->Connect(server_address);
180 EXPECT_EQ(OK, rv);
182 // Client sends to the server.
183 rv = WriteSocket(client.get(), simple_message);
184 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
186 // Server waits for message.
187 std::string str = RecvFromSocket(server.get());
188 DCHECK(simple_message == str);
190 // Server echoes reply.
191 rv = SendToSocket(server.get(), simple_message);
192 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
194 // Client waits for response.
195 str = ReadSocket(client.get());
196 DCHECK(simple_message == str);
198 // Test asynchronous read. Server waits for message.
199 base::RunLoop run_loop;
200 int read_result = 0;
201 rv = server->RecvFrom(
202 buffer_.get(), kMaxRead, &recv_from_address_,
203 base::Bind(&ReadCompleteCallback, &read_result, run_loop.QuitClosure()));
204 EXPECT_EQ(ERR_IO_PENDING, rv);
206 // Client sends to the server.
207 base::ThreadTaskRunnerHandle::Get()->PostTask(
208 FROM_HERE,
209 base::Bind(&UDPSocketTest::WriteSocketIgnoreResult,
210 base::Unretained(this), client.get(), simple_message));
211 run_loop.Run();
212 EXPECT_EQ(simple_message.length(), static_cast<size_t>(read_result));
213 EXPECT_EQ(simple_message, std::string(buffer_->data(), read_result));
215 // Delete sockets so they log their final events.
216 server.reset();
217 client.reset();
219 // Check the server's log.
220 TestNetLogEntry::List server_entries;
221 server_log.GetEntries(&server_entries);
222 EXPECT_EQ(5u, server_entries.size());
223 EXPECT_TRUE(
224 LogContainsBeginEvent(server_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
225 EXPECT_TRUE(LogContainsEvent(
226 server_entries, 1, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
227 EXPECT_TRUE(LogContainsEvent(server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT,
228 NetLog::PHASE_NONE));
229 EXPECT_TRUE(LogContainsEvent(
230 server_entries, 3, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
231 EXPECT_TRUE(
232 LogContainsEndEvent(server_entries, 4, NetLog::TYPE_SOCKET_ALIVE));
234 // Check the client's log.
235 TestNetLogEntry::List client_entries;
236 client_log.GetEntries(&client_entries);
237 EXPECT_EQ(7u, client_entries.size());
238 EXPECT_TRUE(
239 LogContainsBeginEvent(client_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
240 EXPECT_TRUE(
241 LogContainsBeginEvent(client_entries, 1, NetLog::TYPE_UDP_CONNECT));
242 EXPECT_TRUE(LogContainsEndEvent(client_entries, 2, NetLog::TYPE_UDP_CONNECT));
243 EXPECT_TRUE(LogContainsEvent(client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT,
244 NetLog::PHASE_NONE));
245 EXPECT_TRUE(LogContainsEvent(
246 client_entries, 4, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
247 EXPECT_TRUE(LogContainsEvent(client_entries, 5, NetLog::TYPE_UDP_BYTES_SENT,
248 NetLog::PHASE_NONE));
249 EXPECT_TRUE(
250 LogContainsEndEvent(client_entries, 6, NetLog::TYPE_SOCKET_ALIVE));
253 TEST_F(UDPSocketTest, Connect) {
254 // The variable |use_nonblocking_io| has no effect in non-Windows ports.
255 ConnectTest(false);
258 #if defined(OS_WIN)
259 TEST_F(UDPSocketTest, ConnectNonBlocking) {
260 ConnectTest(true);
262 #endif
264 #if defined(OS_MACOSX)
265 // UDPSocketPrivate_Broadcast is disabled for OSX because it requires
266 // root permissions on OSX 10.7+.
267 TEST_F(UDPSocketTest, DISABLED_Broadcast) {
268 #elif defined(OS_ANDROID)
269 // It is also disabled for Android because it is extremely flaky.
270 // The first call to SendToSocket returns -109 (Address not reachable)
271 // in some unpredictable cases. crbug.com/139144.
272 TEST_F(UDPSocketTest, DISABLED_Broadcast) {
273 #else
274 TEST_F(UDPSocketTest, Broadcast) {
275 #endif
276 const uint16 kPort = 9999;
277 std::string first_message("first message"), second_message("second message");
279 IPEndPoint broadcast_address;
280 CreateUDPAddress("255.255.255.255", kPort, &broadcast_address);
281 IPEndPoint listen_address;
282 CreateUDPAddress("0.0.0.0", kPort, &listen_address);
284 TestNetLog server1_log, server2_log;
285 scoped_ptr<UDPServerSocket> server1(
286 new UDPServerSocket(&server1_log, NetLog::Source()));
287 scoped_ptr<UDPServerSocket> server2(
288 new UDPServerSocket(&server2_log, NetLog::Source()));
289 server1->AllowAddressReuse();
290 server1->AllowBroadcast();
291 server2->AllowAddressReuse();
292 server2->AllowBroadcast();
294 int rv = server1->Listen(listen_address);
295 EXPECT_EQ(OK, rv);
296 rv = server2->Listen(listen_address);
297 EXPECT_EQ(OK, rv);
299 rv = SendToSocket(server1.get(), first_message, broadcast_address);
300 ASSERT_EQ(static_cast<int>(first_message.size()), rv);
301 std::string str = RecvFromSocket(server1.get());
302 ASSERT_EQ(first_message, str);
303 str = RecvFromSocket(server2.get());
304 ASSERT_EQ(first_message, str);
306 rv = SendToSocket(server2.get(), second_message, broadcast_address);
307 ASSERT_EQ(static_cast<int>(second_message.size()), rv);
308 str = RecvFromSocket(server1.get());
309 ASSERT_EQ(second_message, str);
310 str = RecvFromSocket(server2.get());
311 ASSERT_EQ(second_message, str);
314 // In this test, we verify that random binding logic works, which attempts
315 // to bind to a random port and returns if succeeds, otherwise retries for
316 // |kBindRetries| number of times.
318 // To generate the scenario, we first create |kBindRetries| number of
319 // UDPClientSockets with default binding policy and connect to the same
320 // peer and save the used port numbers. Then we get rid of the last
321 // socket, making sure that the local port it was bound to is available.
322 // Finally, we create a socket with random binding policy, passing it a
323 // test PRNG that would serve used port numbers in the array, one after
324 // another. At the end, we make sure that the test socket was bound to the
325 // port that became available after deleting the last socket with default
326 // binding policy.
328 // We do not test the randomness of bound ports, but that we are using
329 // passed in PRNG correctly, thus, it's the duty of PRNG to produce strong
330 // random numbers.
331 static const int kBindRetries = 10;
333 class TestPrng {
334 public:
335 explicit TestPrng(const std::deque<int>& numbers) : numbers_(numbers) {}
336 int GetNext(int /* min */, int /* max */) {
337 DCHECK(!numbers_.empty());
338 int rv = numbers_.front();
339 numbers_.pop_front();
340 return rv;
342 private:
343 std::deque<int> numbers_;
345 DISALLOW_COPY_AND_ASSIGN(TestPrng);
348 #if defined(OS_ANDROID)
349 // Disabled on Android for lack of 192.168.1.13. crbug.com/161245
350 TEST_F(UDPSocketTest, DISABLED_ConnectRandomBind) {
351 #else
352 TEST_F(UDPSocketTest, ConnectRandomBind) {
353 #endif
354 std::vector<UDPClientSocket*> sockets;
355 IPEndPoint peer_address;
356 CreateUDPAddress("192.168.1.13", 53, &peer_address);
358 // Create and connect sockets and save port numbers.
359 std::deque<int> used_ports;
360 for (int i = 0; i < kBindRetries; ++i) {
361 UDPClientSocket* socket =
362 new UDPClientSocket(DatagramSocket::DEFAULT_BIND,
363 RandIntCallback(),
364 NULL,
365 NetLog::Source());
366 sockets.push_back(socket);
367 EXPECT_EQ(OK, socket->Connect(peer_address));
369 IPEndPoint client_address;
370 EXPECT_EQ(OK, socket->GetLocalAddress(&client_address));
371 used_ports.push_back(client_address.port());
374 // Free the last socket, its local port is still in |used_ports|.
375 delete sockets.back();
376 sockets.pop_back();
378 TestPrng test_prng(used_ports);
379 RandIntCallback rand_int_cb =
380 base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng));
382 // Create a socket with random binding policy and connect.
383 scoped_ptr<UDPClientSocket> test_socket(
384 new UDPClientSocket(DatagramSocket::RANDOM_BIND,
385 rand_int_cb,
386 NULL,
387 NetLog::Source()));
388 EXPECT_EQ(OK, test_socket->Connect(peer_address));
390 // Make sure that the last port number in the |used_ports| was used.
391 IPEndPoint client_address;
392 EXPECT_EQ(OK, test_socket->GetLocalAddress(&client_address));
393 EXPECT_EQ(used_ports.back(), client_address.port());
395 STLDeleteElements(&sockets);
398 // Return a privileged port (under 1024) so binding will fail.
399 int PrivilegedRand(int min, int max) {
400 // Chosen by fair dice roll. Guaranteed to be random.
401 return 4;
404 TEST_F(UDPSocketTest, ConnectFail) {
405 IPEndPoint peer_address;
406 CreateUDPAddress("0.0.0.0", 53, &peer_address);
408 scoped_ptr<UDPSocket> socket(
409 new UDPSocket(DatagramSocket::RANDOM_BIND,
410 base::Bind(&PrivilegedRand),
411 NULL,
412 NetLog::Source()));
413 int rv = socket->Open(peer_address.GetFamily());
414 EXPECT_EQ(OK, rv);
415 rv = socket->Connect(peer_address);
416 // Connect should have failed since we couldn't bind to that port,
417 EXPECT_NE(OK, rv);
418 // Make sure that UDPSocket actually closed the socket.
419 EXPECT_FALSE(socket->is_connected());
422 // In this test, we verify that connect() on a socket will have the effect
423 // of filtering reads on this socket only to data read from the destination
424 // we connected to.
426 // The purpose of this test is that some documentation indicates that connect
427 // binds the client's sends to send to a particular server endpoint, but does
428 // not bind the client's reads to only be from that endpoint, and that we need
429 // to always use recvfrom() to disambiguate.
430 TEST_F(UDPSocketTest, VerifyConnectBindsAddr) {
431 const uint16 kPort1 = 9999;
432 const uint16 kPort2 = 10000;
433 std::string simple_message("hello world!");
434 std::string foreign_message("BAD MESSAGE TO GET!!");
436 // Setup the first server to listen.
437 IPEndPoint bind_address;
438 CreateUDPAddress("127.0.0.1", kPort1, &bind_address);
439 UDPServerSocket server1(NULL, NetLog::Source());
440 server1.AllowAddressReuse();
441 int rv = server1.Listen(bind_address);
442 ASSERT_EQ(OK, rv);
444 // Setup the second server to listen.
445 CreateUDPAddress("127.0.0.1", kPort2, &bind_address);
446 UDPServerSocket server2(NULL, NetLog::Source());
447 server2.AllowAddressReuse();
448 rv = server2.Listen(bind_address);
449 ASSERT_EQ(OK, rv);
451 // Setup the client, connected to server 1.
452 IPEndPoint server_address;
453 CreateUDPAddress("127.0.0.1", kPort1, &server_address);
454 UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
455 RandIntCallback(),
456 NULL,
457 NetLog::Source());
458 rv = client.Connect(server_address);
459 EXPECT_EQ(OK, rv);
461 // Client sends to server1.
462 rv = WriteSocket(&client, simple_message);
463 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
465 // Server1 waits for message.
466 std::string str = RecvFromSocket(&server1);
467 DCHECK(simple_message == str);
469 // Get the client's address.
470 IPEndPoint client_address;
471 rv = client.GetLocalAddress(&client_address);
472 EXPECT_EQ(OK, rv);
474 // Server2 sends reply.
475 rv = SendToSocket(&server2, foreign_message,
476 client_address);
477 EXPECT_EQ(foreign_message.length(), static_cast<size_t>(rv));
479 // Server1 sends reply.
480 rv = SendToSocket(&server1, simple_message,
481 client_address);
482 EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
484 // Client waits for response.
485 str = ReadSocket(&client);
486 DCHECK(simple_message == str);
489 TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
490 struct TestData {
491 std::string remote_address;
492 std::string local_address;
493 bool may_fail;
494 } tests[] = {
495 { "127.0.00.1", "127.0.0.1", false },
496 { "::1", "::1", true },
497 #if !defined(OS_ANDROID)
498 // Addresses below are disabled on Android. See crbug.com/161248
499 { "192.168.1.1", "127.0.0.1", false },
500 { "2001:db8:0::42", "::1", true },
501 #endif
503 for (size_t i = 0; i < arraysize(tests); i++) {
504 SCOPED_TRACE(std::string("Connecting from ") + tests[i].local_address +
505 std::string(" to ") + tests[i].remote_address);
507 IPAddressNumber ip_number;
508 ParseIPLiteralToNumber(tests[i].remote_address, &ip_number);
509 IPEndPoint remote_address(ip_number, 80);
510 ParseIPLiteralToNumber(tests[i].local_address, &ip_number);
511 IPEndPoint local_address(ip_number, 80);
513 UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
514 RandIntCallback(),
515 NULL,
516 NetLog::Source());
517 int rv = client.Connect(remote_address);
518 if (tests[i].may_fail && rv == ERR_ADDRESS_UNREACHABLE) {
519 // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6
520 // addresses if IPv6 is not configured.
521 continue;
524 EXPECT_LE(ERR_IO_PENDING, rv);
526 IPEndPoint fetched_local_address;
527 rv = client.GetLocalAddress(&fetched_local_address);
528 EXPECT_EQ(OK, rv);
530 // TODO(mbelshe): figure out how to verify the IP and port.
531 // The port is dynamically generated by the udp stack.
532 // The IP is the real IP of the client, not necessarily
533 // loopback.
534 //EXPECT_EQ(local_address.address(), fetched_local_address.address());
536 IPEndPoint fetched_remote_address;
537 rv = client.GetPeerAddress(&fetched_remote_address);
538 EXPECT_EQ(OK, rv);
540 EXPECT_EQ(remote_address, fetched_remote_address);
544 TEST_F(UDPSocketTest, ServerGetLocalAddress) {
545 IPEndPoint bind_address;
546 CreateUDPAddress("127.0.0.1", 0, &bind_address);
547 UDPServerSocket server(NULL, NetLog::Source());
548 int rv = server.Listen(bind_address);
549 EXPECT_EQ(OK, rv);
551 IPEndPoint local_address;
552 rv = server.GetLocalAddress(&local_address);
553 EXPECT_EQ(rv, 0);
555 // Verify that port was allocated.
556 EXPECT_GT(local_address.port(), 0);
557 EXPECT_EQ(local_address.address(), bind_address.address());
560 TEST_F(UDPSocketTest, ServerGetPeerAddress) {
561 IPEndPoint bind_address;
562 CreateUDPAddress("127.0.0.1", 0, &bind_address);
563 UDPServerSocket server(NULL, NetLog::Source());
564 int rv = server.Listen(bind_address);
565 EXPECT_EQ(OK, rv);
567 IPEndPoint peer_address;
568 rv = server.GetPeerAddress(&peer_address);
569 EXPECT_EQ(rv, ERR_SOCKET_NOT_CONNECTED);
572 // Close the socket while read is pending.
573 TEST_F(UDPSocketTest, CloseWithPendingRead) {
574 IPEndPoint bind_address;
575 CreateUDPAddress("127.0.0.1", 0, &bind_address);
576 UDPServerSocket server(NULL, NetLog::Source());
577 int rv = server.Listen(bind_address);
578 EXPECT_EQ(OK, rv);
580 TestCompletionCallback callback;
581 IPEndPoint from;
582 rv = server.RecvFrom(buffer_.get(), kMaxRead, &from, callback.callback());
583 EXPECT_EQ(rv, ERR_IO_PENDING);
585 server.Close();
587 EXPECT_FALSE(callback.have_result());
590 #if defined(OS_ANDROID)
591 // Some Android devices do not support multicast socket.
592 // The ones supporting multicast need WifiManager.MulitcastLock to enable it.
593 // http://goo.gl/jjAk9
594 #define MAYBE_JoinMulticastGroup DISABLED_JoinMulticastGroup
595 #else
596 #define MAYBE_JoinMulticastGroup JoinMulticastGroup
597 #endif // defined(OS_ANDROID)
599 TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) {
600 const uint16 kPort = 9999;
601 const char kGroup[] = "237.132.100.17";
603 IPEndPoint bind_address;
604 CreateUDPAddress("0.0.0.0", kPort, &bind_address);
605 IPAddressNumber group_ip;
606 EXPECT_TRUE(ParseIPLiteralToNumber(kGroup, &group_ip));
608 UDPSocket socket(DatagramSocket::DEFAULT_BIND,
609 RandIntCallback(),
610 NULL,
611 NetLog::Source());
612 EXPECT_EQ(OK, socket.Open(bind_address.GetFamily()));
613 EXPECT_EQ(OK, socket.Bind(bind_address));
614 EXPECT_EQ(OK, socket.JoinGroup(group_ip));
615 // Joining group multiple times.
616 EXPECT_NE(OK, socket.JoinGroup(group_ip));
617 EXPECT_EQ(OK, socket.LeaveGroup(group_ip));
618 // Leaving group multiple times.
619 EXPECT_NE(OK, socket.LeaveGroup(group_ip));
621 socket.Close();
624 TEST_F(UDPSocketTest, MulticastOptions) {
625 const uint16 kPort = 9999;
626 IPEndPoint bind_address;
627 CreateUDPAddress("0.0.0.0", kPort, &bind_address);
629 UDPSocket socket(DatagramSocket::DEFAULT_BIND,
630 RandIntCallback(),
631 NULL,
632 NetLog::Source());
633 // Before binding.
634 EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(false));
635 EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(true));
636 EXPECT_EQ(OK, socket.SetMulticastTimeToLive(0));
637 EXPECT_EQ(OK, socket.SetMulticastTimeToLive(3));
638 EXPECT_NE(OK, socket.SetMulticastTimeToLive(-1));
639 EXPECT_EQ(OK, socket.SetMulticastInterface(0));
641 EXPECT_EQ(OK, socket.Open(bind_address.GetFamily()));
642 EXPECT_EQ(OK, socket.Bind(bind_address));
644 EXPECT_NE(OK, socket.SetMulticastLoopbackMode(false));
645 EXPECT_NE(OK, socket.SetMulticastTimeToLive(0));
646 EXPECT_NE(OK, socket.SetMulticastInterface(0));
648 socket.Close();
651 // Checking that DSCP bits are set correctly is difficult,
652 // but let's check that the code doesn't crash at least.
653 TEST_F(UDPSocketTest, SetDSCP) {
654 // Setup the server to listen.
655 IPEndPoint bind_address;
656 UDPSocket client(DatagramSocket::DEFAULT_BIND,
657 RandIntCallback(),
658 NULL,
659 NetLog::Source());
660 // We need a real IP, but we won't actually send anything to it.
661 CreateUDPAddress("8.8.8.8", 9999, &bind_address);
662 int rv = client.Open(bind_address.GetFamily());
663 EXPECT_EQ(OK, rv);
665 rv = client.Connect(bind_address);
666 if (rv != OK) {
667 // Let's try localhost then..
668 CreateUDPAddress("127.0.0.1", 9999, &bind_address);
669 rv = client.Connect(bind_address);
671 EXPECT_EQ(OK, rv);
673 client.SetDiffServCodePoint(DSCP_NO_CHANGE);
674 client.SetDiffServCodePoint(DSCP_AF41);
675 client.SetDiffServCodePoint(DSCP_DEFAULT);
676 client.SetDiffServCodePoint(DSCP_CS2);
677 client.SetDiffServCodePoint(DSCP_NO_CHANGE);
678 client.SetDiffServCodePoint(DSCP_DEFAULT);
679 client.Close();
682 } // namespace
684 #if defined(OS_WIN)
686 namespace {
688 const HANDLE kFakeHandle = (HANDLE)19;
689 const QOS_FLOWID kFakeFlowId = (QOS_FLOWID)27;
691 BOOL WINAPI FakeQOSCreateHandleFAIL(PQOS_VERSION version, PHANDLE handle) {
692 EXPECT_EQ(0, version->MinorVersion);
693 EXPECT_EQ(1, version->MajorVersion);
694 SetLastError(ERROR_OPEN_FAILED);
695 return false;
698 BOOL WINAPI FakeQOSCreateHandle(PQOS_VERSION version, PHANDLE handle) {
699 EXPECT_EQ(0, version->MinorVersion);
700 EXPECT_EQ(1, version->MajorVersion);
701 *handle = kFakeHandle;
702 return true;
705 BOOL WINAPI FakeQOSCloseHandle(HANDLE handle) {
706 EXPECT_EQ(kFakeHandle, handle);
707 return true;
710 QOS_TRAFFIC_TYPE g_expected_traffic_type;
712 BOOL WINAPI FakeQOSAddSocketToFlow(HANDLE handle,
713 SOCKET socket,
714 PSOCKADDR addr,
715 QOS_TRAFFIC_TYPE traffic_type,
716 DWORD flags,
717 PQOS_FLOWID flow_id) {
718 EXPECT_EQ(kFakeHandle, handle);
719 EXPECT_EQ(NULL, addr);
720 EXPECT_EQ(QOS_NON_ADAPTIVE_FLOW, flags);
721 EXPECT_EQ(0, *flow_id);
722 *flow_id = kFakeFlowId;
723 return true;
726 BOOL WINAPI FakeQOSRemoveSocketFromFlow(HANDLE handle,
727 SOCKET socket,
728 QOS_FLOWID flowid,
729 DWORD reserved) {
730 EXPECT_EQ(kFakeHandle, handle);
731 EXPECT_EQ(NULL, socket);
732 EXPECT_EQ(kFakeFlowId, flowid);
733 EXPECT_EQ(0, reserved);
734 return true;
737 DWORD g_expected_dscp;
739 BOOL WINAPI FakeQOSSetFlow(HANDLE handle,
740 QOS_FLOWID flow_id,
741 QOS_SET_FLOW op,
742 ULONG size,
743 PVOID data,
744 DWORD reserved,
745 LPOVERLAPPED overlapped) {
746 EXPECT_EQ(kFakeHandle, handle);
747 EXPECT_EQ(QOSSetOutgoingDSCPValue, op);
748 EXPECT_EQ(sizeof(DWORD), size);
749 EXPECT_EQ(g_expected_dscp, *reinterpret_cast<DWORD*>(data));
750 EXPECT_EQ(kFakeFlowId, flow_id);
751 EXPECT_EQ(0, reserved);
752 EXPECT_EQ(NULL, overlapped);
753 return true;
756 } // namespace
758 // Mock out the Qwave functions and make sure they are
759 // called correctly. Must be in net namespace for friendship
760 // reasons.
761 TEST_F(UDPSocketTest, SetDSCPFake) {
762 // Setup the server to listen.
763 IPEndPoint bind_address;
764 // We need a real IP, but we won't actually send anything to it.
765 CreateUDPAddress("8.8.8.8", 9999, &bind_address);
766 UDPSocket client(DatagramSocket::DEFAULT_BIND,
767 RandIntCallback(),
768 NULL,
769 NetLog::Source());
770 int rv = client.SetDiffServCodePoint(DSCP_AF41);
771 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, rv);
773 rv = client.Open(bind_address.GetFamily());
774 EXPECT_EQ(OK, rv);
776 rv = client.Connect(bind_address);
777 EXPECT_EQ(OK, rv);
779 QwaveAPI& qos(QwaveAPI::Get());
780 qos.create_handle_func_ = FakeQOSCreateHandleFAIL;
781 qos.close_handle_func_ = FakeQOSCloseHandle;
782 qos.add_socket_to_flow_func_ = FakeQOSAddSocketToFlow;
783 qos.remove_socket_from_flow_func_ = FakeQOSRemoveSocketFromFlow;
784 qos.set_flow_func_ = FakeQOSSetFlow;
785 qos.qwave_supported_ = true;
787 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_NO_CHANGE));
788 EXPECT_EQ(ERROR_NOT_SUPPORTED, client.SetDiffServCodePoint(DSCP_AF41));
789 qos.create_handle_func_ = FakeQOSCreateHandle;
790 g_expected_dscp = DSCP_AF41;
791 g_expected_traffic_type = QOSTrafficTypeAudioVideo;
792 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_AF41));
793 g_expected_dscp = DSCP_DEFAULT;
794 g_expected_traffic_type = QOSTrafficTypeBestEffort;
795 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_DEFAULT));
796 g_expected_dscp = DSCP_CS2;
797 g_expected_traffic_type = QOSTrafficTypeExcellentEffort;
798 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_CS2));
799 g_expected_dscp = DSCP_CS3;
800 g_expected_traffic_type = QOSTrafficTypeExcellentEffort;
801 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_NO_CHANGE));
802 g_expected_dscp = DSCP_DEFAULT;
803 g_expected_traffic_type = QOSTrafficTypeBestEffort;
804 EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_DEFAULT));
805 client.Close();
807 #endif
809 } // namespace net