Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / extensions / test / data / sockets_udp / api / multicast.js
blob7b591cf36d9c7584ee012673341857fd2ee21954
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) {
8     var result = '';
9     for (var i = 0; i < count; i++) {
10       result += (Math.random() * 16 >> 0).toString(16);
11     }
12     return result;
13   }
15   var kMulticastAddress = "237.132.100.133";
16   var kTestMessageLength = 128;
17   var kTestMessage = randomHexString(128);
18   var kPort = 11103;
20   function arrayBufferToString(arrayBuffer) {
21     // UTF-16LE
22     return String.fromCharCode.apply(String, new Uint16Array(arrayBuffer));
23   }
25   function stringToArrayBuffer(string) {
26     // UTF-16LE
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);
31     }
32     return buf;
33   }
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)
52         return;
54       if (cancelled)
55         return;
57       if (info.data.byteLength == kTestMessageLength * 2 &&
58           kTestMessage === arrayBufferToString(info.data)) {
59         callback(false);
60       } else {
61         // Restart waiting.
62         relayCanceller = waitForMessage(socketId, callback);
63       }
64     });
65     return function canceller() {
66       if (relayCanceller) {
67         relayCanceller();
68       } else {
69         cancelled = true;  // prevents callback from being called on receive.
70         callback(true);
71       }
72     };
73   }
75   function testMulticastSettings(nextTest) {
76     console.log("*************** testMulticastSettings");
77     chrome.sockets.udp.create({}, function (socketInfo) {
78       var socketId;
79       if (socketInfo) {
80         socketId = socketInfo.socketId;
81         chrome.sockets.udp.setMulticastTimeToLive(socketId, 0,
82             function (result) {
83           chrome.test.assertEq(0, result,
84               "Error setting multicast time to live.");
85           chrome.sockets.udp.setMulticastTimeToLive(socketId, -3,
86               function (result) {
87             chrome.test.assertEq(-4, result,
88                 "Error setting multicast time to live.");
89             chrome.sockets.udp.setMulticastLoopbackMode(socketId, false,
90                 function (result) {
91               chrome.test.assertEq(0, result,
92                   "Error setting multicast loop back mode.");
93               chrome.sockets.udp.setMulticastLoopbackMode(socketId, true,
94                   function (result) {
95                 chrome.test.assertEq(0, result,
96                     "Error setting multicast loop back mode.");
97                 chrome.sockets.udp.close(socketId, function() {});
98                 nextTest();
99               });
100             });
101           });
102         });
103       } else {
104         chrome.test.fail("Cannot create server udp socket");
105       }
106     });
107   }
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,
116           function (result) {
117         chrome.test.assertEq(0, result,
118             "Cannot create client udp socket.");
119         chrome.sockets.udp.bind(clientSocketId, "0.0.0.0", 0,
120             function (result) {
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 +
130                ", port=" + kPort);
131             chrome.test.assertTrue(result.resultCode >= 0,
132                 "Send to failed. " + JSON.stringify(result));
133             chrome.sockets.udp.close(clientSocketId, function() {});
134           });
135         });
136       });
137     });
138   }
140   function testRecvBeforeAddMembership(serverSocketId, nextTest) {
141     console.log("*************** testRecvBeforeAddMembership");
142     var recvTimeout;
143     var canceller = waitForMessage(serverSocketId, function (cancelled) {
144       clearTimeout(recvTimeout);
145       if (cancelled) {
146         nextTest();
147       } else {
148         chrome.test.fail("Received message before joining the group");
149       }
150     });
151     testSendMessage(kTestMessage, kMulticastAddress); // Meant to be lost.
152     recvTimeout = setTimeout(function () {
153       // This is expected to execute.
154       canceller();
155     }, 2000);
156   }
158   function testRecvWithMembership(serverSocketId, nextTest) {
159     console.log("*************** testRecvWithMembership");
160     chrome.sockets.udp.joinGroup(serverSocketId, kMulticastAddress,
161         function (result) {
162       chrome.test.assertEq(0, result, "Join group failed.");
163       var recvTimeout;
164       var canceller = waitForMessage(serverSocketId, function (cancelled) {
165         clearTimeout(recvTimeout);
166         if (!cancelled) {
167           nextTest();
168         } else {
169           chrome.test.fail("Faild to receive message after joining the group");
170         }
171       });
172       testSendMessage(kTestMessage, kMulticastAddress);
173       recvTimeout = setTimeout(function () {
174         canceller();
175         chrome.test.fail("Cannot receive from multicast group.");
176       }, 2000);
177     });
178   }
180   function testRecvWithoutMembership(serverSocketId, nextTest) {
181     console.log("*************** testRecvWithoutMembership");
182     chrome.sockets.udp.leaveGroup(serverSocketId, kMulticastAddress,
183         function (result) {
184       chrome.test.assertEq(0, result, "leave group failed.");
185       var recvTimeout;
186       var canceller = waitForMessage(serverSocketId, function (cancelled) {
187         clearTimeout(recvTimeout);
188         if (cancelled) {
189           nextTest();
190         } else {
191           chrome.test.fail("Received message after leaving the group");
192         }
193       });
194       testSendMessage(request, kMulticastAddress);
195       recvTimeout = setTimeout(function () {
196         // This is expected to execute.
197         canceller();
198       }, 2000);
199     });
200   }
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,
207           function (result) {
208         chrome.test.assertEq(0, result, "Bind failed.");
209         // Test 1
210         testRecvBeforeAddMembership(serverSocketId, function() {
211           // Test 2
212           testRecvWithMembership(serverSocketId, function() {
213             // Test 3
214             testRecvWithoutMembership(serverSocketId, function() {
215               // Success!
216               chrome.sockets.udp.close(serverSocketId, function() {
217                 console.log("*************** SUCCESS! ");
218                 chrome.test.succeed();
219               });
220             });
221           });
222         });
223       });
224     });
225   }
227   setTimeout(function() {
228     testMulticastSettings(function() {
229       testMulticastRecv();
230     })
231   }, 100);