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() {