1 // Copyright 2013 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 // Tests for multicast UDP chrome.sockets.udp.
6 function testMulticast() {
7 function randomHexString(count
) {
9 for (var i
= 0; i
< count
; i
++) {
10 result
+= (Math
.random() * 16 >> 0).toString(16);
15 var kMulticastAddress
= "237.132.100.133";
16 var kTestMessageLength
= 128;
17 var kTestMessage
= randomHexString(128);
20 function arrayBufferToString(arrayBuffer
) {
22 return String
.fromCharCode
.apply(String
, new Uint16Array(arrayBuffer
));
25 function stringToArrayBuffer(string
) {
27 var buf
= new ArrayBuffer(string
.length
* 2);
28 var bufView
= new Uint16Array(buf
);
29 for (var i
= 0, strLen
= string
.length
; i
< strLen
; i
++) {
30 bufView
[i
] = string
.charCodeAt(i
);
35 // Registers a listener on receiving data on |socketId|.
36 // Calls |callback| with a |cancelled| argument of "false" when receiving data
37 // of excactly |kTestMessageLength| characters.
38 // Calls |callback| with a |cancelled| argument of "true" when the caller
39 // decides to invoke the returned function.
40 // Returns a function that can be invoked to "cancel" the operation (i.e.
41 // call |callback| with a |cancelled| argument of "true").
42 function waitForMessage(socketId
, callback
) {
43 var cancelled
= false;
44 var relayCanceller
= null;
45 chrome
.sockets
.udp
.onReceive
.addListener(function(info
) {
46 console
.log("Data received: " +
47 "socketId=" + info
.socketId
+
48 ", bytes=" + info
.data
.byteLength
+
49 ", address=" + info
.remoteAddress
+
50 ", port=" + info
.remotePort
);
51 if (socketId
!= info
.socketId
)
57 if (info
.data
.byteLength
== kTestMessageLength
* 2 &&
58 kTestMessage
=== arrayBufferToString(info
.data
)) {
62 relayCanceller
= waitForMessage(socketId
, callback
);
65 return function canceller() {
69 cancelled
= true; // prevents callback from being called on receive.
75 function testMulticastSettings(nextTest
) {
76 console
.log("*************** testMulticastSettings");
77 chrome
.sockets
.udp
.create({}, function (socketInfo
) {
80 socketId
= socketInfo
.socketId
;
81 chrome
.sockets
.udp
.setMulticastTimeToLive(socketId
, 0,
83 chrome
.test
.assertEq(0, result
,
84 "Error setting multicast time to live.");
85 chrome
.sockets
.udp
.setMulticastTimeToLive(socketId
, -3,
87 chrome
.test
.assertEq(-4, result
,
88 "Error setting multicast time to live.");
89 chrome
.sockets
.udp
.setMulticastLoopbackMode(socketId
, false,
91 chrome
.test
.assertEq(0, result
,
92 "Error setting multicast loop back mode.");
93 chrome
.sockets
.udp
.setMulticastLoopbackMode(socketId
, true,
95 chrome
.test
.assertEq(0, result
,
96 "Error setting multicast loop back mode.");
97 chrome
.sockets
.udp
.close(socketId
, function() {});
104 chrome
.test
.fail("Cannot create server udp socket");
109 function testSendMessage(message
, address
) {
110 // Send the UDP message to the address with multicast ttl = 0.
111 chrome
.sockets
.udp
.create({}, function (socketInfo
) {
112 var clientSocketId
= socketInfo
.socketId
;
113 chrome
.test
.assertTrue(clientSocketId
> 0,
114 "Cannot create client udp socket.");
115 chrome
.sockets
.udp
.setMulticastTimeToLive(clientSocketId
, 0,
117 chrome
.test
.assertEq(0, result
,
118 "Cannot create client udp socket.");
119 chrome
.sockets
.udp
.bind(clientSocketId
, "0.0.0.0", 0,
121 chrome
.test
.assertEq(0, result
,
122 "Cannot bind to localhost.");
123 chrome
.sockets
.udp
.send(clientSocketId
,
124 stringToArrayBuffer(kTestMessage
),
125 address
, kPort
, function (result
) {
126 console
.log("Sent bytes to socket:" +
127 " socketId=" + clientSocketId
+
128 ", bytes=" + result
.bytesSent
+
129 ", address=" + address
+
131 chrome
.test
.assertTrue(result
.resultCode
>= 0,
132 "Send to failed. " + JSON
.stringify(result
));
133 chrome
.sockets
.udp
.close(clientSocketId
, function() {});
140 function testRecvBeforeAddMembership(serverSocketId
, nextTest
) {
141 console
.log("*************** testRecvBeforeAddMembership");
143 var canceller
= waitForMessage(serverSocketId
, function (cancelled
) {
144 clearTimeout(recvTimeout
);
148 chrome
.test
.fail("Received message before joining the group");
151 testSendMessage(kTestMessage
, kMulticastAddress
); // Meant to be lost.
152 recvTimeout
= setTimeout(function () {
153 // This is expected to execute.
158 function testRecvWithMembership(serverSocketId
, nextTest
) {
159 console
.log("*************** testRecvWithMembership");
160 chrome
.sockets
.udp
.joinGroup(serverSocketId
, kMulticastAddress
,
162 chrome
.test
.assertEq(0, result
, "Join group failed.");
164 var canceller
= waitForMessage(serverSocketId
, function (cancelled
) {
165 clearTimeout(recvTimeout
);
169 chrome
.test
.fail("Faild to receive message after joining the group");
172 testSendMessage(kTestMessage
, kMulticastAddress
);
173 recvTimeout
= setTimeout(function () {
175 chrome
.test
.fail("Cannot receive from multicast group.");
180 function testRecvWithoutMembership(serverSocketId
, nextTest
) {
181 console
.log("*************** testRecvWithoutMembership");
182 chrome
.sockets
.udp
.leaveGroup(serverSocketId
, kMulticastAddress
,
184 chrome
.test
.assertEq(0, result
, "leave group failed.");
186 var canceller
= waitForMessage(serverSocketId
, function (cancelled
) {
187 clearTimeout(recvTimeout
);
191 chrome
.test
.fail("Received message after leaving the group");
194 testSendMessage(request
, kMulticastAddress
);
195 recvTimeout
= setTimeout(function () {
196 // This is expected to execute.
202 function testMulticastRecv() {
203 console
.log("*************** testMulticastRecv");
204 chrome
.sockets
.udp
.create({}, function (socketInfo
) {
205 var serverSocketId
= socketInfo
.socketId
;
206 chrome
.sockets
.udp
.bind(serverSocketId
, "0.0.0.0", kPort
,
208 chrome
.test
.assertEq(0, result
, "Bind failed.");
210 testRecvBeforeAddMembership(serverSocketId
, function() {
212 testRecvWithMembership(serverSocketId
, function() {
214 testRecvWithoutMembership(serverSocketId
, function() {
216 chrome
.sockets
.udp
.close(serverSocketId
, function() {
217 console
.log("*************** SUCCESS! ");
218 chrome
.test
.succeed();
227 setTimeout(function() {
228 testMulticastSettings(function() {