Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81154 views
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
436
437