Initial commit
[yaffs-website] / node_modules / sntp / test / index.js
1 // Load modules
2
3 var Dns = require('dns');
4 var Dgram = require('dgram');
5 var Lab = require('lab');
6 var Sntp = require('../lib');
7
8
9 // Declare internals
10
11 var internals = {};
12
13
14 // Test shortcuts
15
16 var lab = exports.lab = Lab.script();
17 var before = lab.before;
18 var after = lab.after;
19 var describe = lab.experiment;
20 var it = lab.test;
21 var expect = Lab.expect;
22
23
24 describe('SNTP', function () {
25
26     describe('#time', function () {
27
28         it('returns consistent result over multiple tries', function (done) {
29
30             Sntp.time(function (err, time) {
31
32                 expect(err).to.not.exist;
33                 expect(time).to.exist;
34                 var t1 = time.t;
35
36                 Sntp.time(function (err, time) {
37
38                     expect(err).to.not.exist;
39                     expect(time).to.exist;
40                     var t2 = time.t;
41                     expect(Math.abs(t1 - t2)).is.below(200);
42                     done();
43                 });
44             });
45         });
46
47         it('resolves reference IP', function (done) {
48
49             Sntp.time({ host: 'ntp.exnet.com', resolveReference: true }, function (err, time) {
50
51                 expect(err).to.not.exist;
52                 expect(time).to.exist;
53                 expect(time.referenceHost).to.exist;
54                 done();
55             });
56         });
57
58         it('times out on no response', function (done) {
59
60             Sntp.time({ port: 124, timeout: 100 }, function (err, time) {
61
62                 expect(err).to.exist;
63                 expect(time).to.not.exist;
64                 expect(err.message).to.equal('Timeout');
65                 done();
66             });
67         });
68
69         it('errors on error event', { parallel: false }, function (done) {
70
71             var orig = Dgram.createSocket;
72             Dgram.createSocket = function (type) {
73
74                 Dgram.createSocket = orig;
75                 var socket = Dgram.createSocket(type);
76                 setImmediate(function () { socket.emit('error', new Error('Fake')) });
77                 return socket;
78             };
79
80             Sntp.time(function (err, time) {
81
82                 expect(err).to.exist;
83                 expect(time).to.not.exist;
84                 expect(err.message).to.equal('Fake');
85                 done();
86             });
87         });
88
89         it('errors on incorrect sent size', { parallel: false }, function (done) {
90
91             var orig = Dgram.Socket.prototype.send;
92             Dgram.Socket.prototype.send = function (buf, offset, length, port, address, callback) {
93
94                 Dgram.Socket.prototype.send = orig;
95                 return callback(null, 40);
96             };
97
98             Sntp.time(function (err, time) {
99
100                 expect(err).to.exist;
101                 expect(time).to.not.exist;
102                 expect(err.message).to.equal('Could not send entire message');
103                 done();
104             });
105         });
106
107         it('times out on invalid host', function (done) {
108
109             Sntp.time({ host: 'error', timeout: 10000 }, function (err, time) {
110
111                 expect(err).to.exist;
112                 expect(time).to.not.exist;
113                 expect(err.message).to.contain('getaddrinfo');
114                 done();
115             });
116         });
117
118         it('fails on bad response buffer size', function (done) {
119
120             var server = Dgram.createSocket('udp4');
121             server.on('message', function (message, remote) {
122                 var message = new Buffer(10);
123                 server.send(message, 0, message.length, remote.port, remote.address, function (err, bytes) {
124
125                     server.close();
126                 });
127             });
128
129             server.bind(49123);
130
131             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
132
133                 expect(err).to.exist;
134                 expect(err.message).to.equal('Invalid server response');
135                 done();
136             });
137         });
138
139         var messup = function (bytes) {
140
141             var server = Dgram.createSocket('udp4');
142             server.on('message', function (message, remote) {
143
144                 var message = new Buffer([
145                     0x24, 0x01, 0x00, 0xe3,
146                     0x00, 0x00, 0x00, 0x00,
147                     0x00, 0x00, 0x00, 0x00,
148                     0x41, 0x43, 0x54, 0x53,
149                     0xd4, 0xa8, 0x2d, 0xc7,
150                     0x1c, 0x5d, 0x49, 0x1b,
151                     0xd4, 0xa8, 0x2d, 0xe6,
152                     0x67, 0xef, 0x9d, 0xb2,
153                     0xd4, 0xa8, 0x2d, 0xe6,
154                     0x71, 0xed, 0xb5, 0xfb,
155                     0xd4, 0xa8, 0x2d, 0xe6,
156                     0x71, 0xee, 0x6c, 0xc5
157                 ]);
158
159                 for (var i = 0, il = bytes.length; i < il; ++i) {
160                     message[bytes[i][0]] = bytes[i][1];
161                 }
162
163                 server.send(message, 0, message.length, remote.port, remote.address, function (err, bytes) {
164
165                     server.close();
166                 });
167             });
168
169             server.bind(49123);
170         };
171
172         it('fails on bad version', function (done) {
173
174             messup([[0, (0 << 6) + (3 << 3) + (4 << 0)]]);
175
176             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
177
178                 expect(err).to.exist;
179                 expect(time.version).to.equal(3);
180                 expect(err.message).to.equal('Invalid server response');
181                 done();
182             });
183         });
184
185         it('fails on bad originateTimestamp', function (done) {
186
187             messup([[24, 0x83], [25, 0xaa], [26, 0x7e], [27, 0x80], [28, 0], [29, 0], [30, 0], [31, 0]]);
188
189             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
190
191                 expect(err).to.exist;
192                 expect(err.message).to.equal('Invalid server response');
193                 done();
194             });
195         });
196
197         it('fails on bad receiveTimestamp', function (done) {
198
199             messup([[32, 0x83], [33, 0xaa], [34, 0x7e], [35, 0x80], [36, 0], [37, 0], [38, 0], [39, 0]]);
200
201             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
202
203                 expect(err).to.exist;
204                 expect(err.message).to.equal('Invalid server response');
205                 done();
206             });
207         });
208
209         it('fails on bad originate timestamp and alarm li', function (done) {
210
211             messup([[0, (3 << 6) + (4 << 3) + (4 << 0)]]);
212
213             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
214
215                 expect(err).to.exist;
216                 expect(err.message).to.equal('Wrong originate timestamp');
217                 expect(time.leapIndicator).to.equal('alarm');
218                 done();
219             });
220         });
221
222         it('returns time with death stratum and last61 li', function (done) {
223
224             messup([[0, (1 << 6) + (4 << 3) + (4 << 0)], [1, 0]]);
225
226             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
227
228                 expect(time.stratum).to.equal('death');
229                 expect(time.leapIndicator).to.equal('last-minute-61');
230                 done();
231             });
232         });
233
234         it('returns time with reserved stratum and last59 li', function (done) {
235
236             messup([[0, (2 << 6) + (4 << 3) + (4 << 0)], [1, 0x1f]]);
237
238             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
239
240                 expect(time.stratum).to.equal('reserved');
241                 expect(time.leapIndicator).to.equal('last-minute-59');
242                 done();
243             });
244         });
245
246         it('fails on bad mode (symmetric-active)', function (done) {
247
248             messup([[0, (0 << 6) + (4 << 3) + (1 << 0)]]);
249
250             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
251
252                 expect(err).to.exist;
253                 expect(time.mode).to.equal('symmetric-active');
254                 done();
255             });
256         });
257
258         it('fails on bad mode (symmetric-passive)', function (done) {
259
260             messup([[0, (0 << 6) + (4 << 3) + (2 << 0)]]);
261
262             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
263
264                 expect(err).to.exist;
265                 expect(time.mode).to.equal('symmetric-passive');
266                 done();
267             });
268         });
269
270         it('fails on bad mode (client)', function (done) {
271
272             messup([[0, (0 << 6) + (4 << 3) + (3 << 0)]]);
273
274             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
275
276                 expect(err).to.exist;
277                 expect(time.mode).to.equal('client');
278                 done();
279             });
280         });
281
282         it('fails on bad mode (broadcast)', function (done) {
283
284             messup([[0, (0 << 6) + (4 << 3) + (5 << 0)]]);
285
286             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
287
288                 expect(err).to.exist;
289                 expect(time.mode).to.equal('broadcast');
290                 done();
291             });
292         });
293
294         it('fails on bad mode (reserved)', function (done) {
295
296             messup([[0, (0 << 6) + (4 << 3) + (6 << 0)]]);
297
298             Sntp.time({ host: 'localhost', port: 49123 }, function (err, time) {
299
300                 expect(err).to.exist;
301                 expect(time.mode).to.equal('reserved');
302                 done();
303             });
304         });
305     });
306
307     describe('#offset', function () {
308
309         it('gets the current offset', function (done) {
310
311             Sntp.offset(function (err, offset) {
312
313                 expect(err).to.not.exist;
314                 expect(offset).to.not.equal(0);
315                 done();
316             });
317         });
318
319         it('gets the current offset from cache', function (done) {
320
321             Sntp.offset(function (err, offset) {
322
323                 expect(err).to.not.exist;
324                 expect(offset).to.not.equal(0);
325                 var offset1 = offset;
326                 Sntp.offset({}, function (err, offset) {
327
328                     expect(err).to.not.exist;
329                     expect(offset).to.equal(offset1);
330                     done();
331                 });
332             });
333         });
334
335         it('gets the new offset on different server', function (done) {
336
337             Sntp.offset(function (err, offset) {
338
339                 expect(err).to.not.exist;
340                 expect(offset).to.not.equal(0);
341                 var offset1 = offset;
342                 Sntp.offset({ host: 'nist1-sj.ustiming.org' }, function (err, offset) {
343
344                     expect(err).to.not.exist;
345                     expect(offset).to.not.equal(offset1);
346                     done();
347                 });
348             });
349         });
350
351         it('gets the new offset on different server', function (done) {
352
353             Sntp.offset(function (err, offset) {
354
355                 expect(err).to.not.exist;
356                 expect(offset).to.not.equal(0);
357                 var offset1 = offset;
358                 Sntp.offset({ port: 123 }, function (err, offset) {
359
360                     expect(err).to.not.exist;
361                     expect(offset).to.not.equal(offset1);
362                     done();
363                 });
364             });
365         });
366
367         it('fails getting the current offset on invalid server', function (done) {
368
369             Sntp.offset({ host: 'error' }, function (err, offset) {
370
371                 expect(err).to.exist;
372                 expect(offset).to.equal(0);
373                 done();
374             });
375         });
376     });
377
378     describe('#now', function () {
379
380         it('starts auto-sync, gets now, then stops', function (done) {
381
382             Sntp.stop();
383
384             var before = Sntp.now();
385             expect(before).to.equal(Date.now());
386
387             Sntp.start(function () {
388
389                 var now = Sntp.now();
390                 expect(now).to.not.equal(Date.now());
391                 Sntp.stop();
392
393                 done();
394             });
395         });
396
397         it('starts twice', function (done) {
398
399             Sntp.start(function () {
400
401                 Sntp.start(function () {
402
403                     var now = Sntp.now();
404                     expect(now).to.not.equal(Date.now());
405                     Sntp.stop();
406
407                     done();
408                 });
409             });
410         });
411
412         it('starts auto-sync, gets now, waits, gets again after timeout', function (done) {
413
414             Sntp.stop();
415
416             var before = Sntp.now();
417             expect(before).to.equal(Date.now());
418
419             Sntp.start({ clockSyncRefresh: 100 }, function () {
420
421                 var now = Sntp.now();
422                 expect(now).to.not.equal(Date.now());
423                 expect(now).to.equal(Sntp.now());
424
425                 setTimeout(function () {
426
427                     expect(Sntp.now()).to.not.equal(now);
428                     Sntp.stop();
429                     done();
430                 }, 110);
431             });
432         });
433     });
434 });
435