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