Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use timeout option when timeout config option is set #101

Merged
merged 6 commits into from
Sep 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,13 @@ Below is the possible configuration
* Cross platform config representation
* @typedef {Object} PingConfig
* @property {boolean} numeric - Map IP address to hostname or not
* @property {number} timeout - Time duration, in seconds, for ping command to exit
* @property {number} timeout - Timeout in seconds for each ping request.
* Behaviour varies between platforms. Check platform ping documentation for more information.
* @property {number} deadline - Specify a timeout, in seconds, before ping exits regardless of
how many packets have been sent or received. In this case ping
does not stop after count packet are sent, it waits either for
deadline expire or until count probes are answered or for some
error notification from network. This option is only available on linux and mac.
* @property {number} min_reply - Exit after sending number of ECHO_REQUEST
* @property {boolean} v6 - Ping via ipv6 or not. Default is false
* @property {string} sourceAddr - source address for sending the ping
Expand Down Expand Up @@ -149,6 +155,8 @@ without corresponding arguments.

Try to install package `iputils`. For example, running `apk add iputils`

* For questions regarding to the implementation of `timeout`, and `deadline`, please checkout discussions in #101

# Contributing

Before opening a pull request please make sure your changes follow the
Expand Down
25 changes: 21 additions & 4 deletions lib/builder/linux.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ var builder = {};
* Cross platform config representation
* @typedef {Object} PingConfig
* @property {boolean} numeric - Map IP address to hostname or not
* @property {number} timeout - Time duration for ping command to exit
* @property {number} timeout - Time to wait for a response, in seconds.
* The option affects only timeout in absence of any responses,
* otherwise ping waits for two RTTs.
* @property {number} deadline - Specify a timeout, in seconds,
* before ping exits regardless of how many packets have been sent or received.
* In this case ping does not stop after count packet are sent,
* it waits either for deadline expire or until count probes are answered
* or for some error notification from network.
* This option is only available on linux and mac.
* @property {number} min_reply - Exit after sending number of ECHO_REQUEST
* @property {boolean} v6 - Use IPv4 (default) or IPv6
* @property {string} sourceAddr - source address for sending the ping
Expand All @@ -22,6 +30,7 @@ var builder = {};
var defaultConfig = {
numeric: true,
timeout: 2,
deadline: false,
min_reply: 1,
v6: false,
sourceAddr: '',
Expand All @@ -41,9 +50,10 @@ builder.getResult = function (target, config) {
var ret = [];

// Make every key in config has been setup properly
var keys = ['numeric', 'timeout', 'min_reply', 'v6', 'sourceAddr', 'extra'];
var keys = ['numeric', 'timeout', 'deadline', 'min_reply', 'v6',
'sourceAddr', 'extra'];
keys.forEach(function (k) {
// Falsy value will be overrided without below checking
// Falsy value will be overridden without below checking
if (typeof(_config[k]) !== 'boolean') {
_config[k] = _config[k] || defaultConfig[k];
}
Expand All @@ -55,11 +65,18 @@ builder.getResult = function (target, config) {

if (_config.timeout) {
ret = ret.concat([
'-w',
'-W',
util.format('%d', _config.timeout),
]);
}

if (_config.deadline) {
ret = ret.concat([
'-w',
util.format('%d', _config.deadline),
]);
}

if (_config.min_reply) {
ret = ret.concat([
'-c',
Expand Down
25 changes: 21 additions & 4 deletions lib/builder/mac.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ var builder = {};
* Cross platform config representation
* @typedef {Object} PingConfig
* @property {boolean} numeric - Map IP address to hostname or not
* @property {number} timeout - Time duration for ping command to exit
* @property {number} timeout - Time to wait for a response, in seconds.
* The option affects only timeout in absence of any responses,
* otherwise ping waits for two RTTs.
* @property {number} deadline - Specify a timeout, in seconds,
* before ping exits regardless of how many packets have been sent or received.
* In this case ping does not stop after count packet are sent,
* it waits either for deadline expire or until count probes are answered
* or for some error notification from network.
* This option is only available on linux and mac.
* @property {number} min_reply - Exit after sending number of ECHO_REQUEST
* @property {boolean} v6 - Use IPv4 (default) or IPv6
* @property {string} sourceAddr - source address for sending the ping
Expand All @@ -22,6 +30,7 @@ var builder = {};
var defaultConfig = {
numeric: true,
timeout: 2,
deadline: false,
min_reply: 1,
v6: false,
sourceAddr: '',
Expand All @@ -42,9 +51,10 @@ builder.getResult = function (target, config) {
var ret = [];

// Make every key in config has been setup properly
var keys = ['numeric', 'timeout', 'min_reply', 'v6', 'sourceAddr', 'extra'];
var keys = ['numeric', 'timeout', 'deadline', 'min_reply', 'v6',
'sourceAddr', 'extra'];
keys.forEach(function (k) {
// Falsy value will be overrided without below checking
// Falsy value will be overridden without below checking
if (typeof(_config[k]) !== 'boolean') {
_config[k] = _config[k] || defaultConfig[k];
}
Expand All @@ -60,9 +70,16 @@ builder.getResult = function (target, config) {
throw new Error('There is no timeout option on ping6');
}

ret = ret.concat([
'-W',
util.format('%d', _config.timeout * 1000),
]);
}

if (_config.deadline) {
ret = ret.concat([
'-t',
util.format('%d', _config.timeout),
util.format('%d', _config.deadline),
]);
}

Expand Down
6 changes: 5 additions & 1 deletion lib/builder/win.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var builder = {};
* Cross platform config representation
* @typedef {Object} PingConfig
* @property {boolean} numeric - Map IP address to hostname or not
* @property {number} timeout - Time duration for ping command to exit
* @property {number} timeout - Timeout in seconds for each individual ping request
* @property {number} min_reply - Exit after sending number of ECHO_REQUEST
* @property {boolean} v6 - Use IPv4 (default) or IPv6
* @property {string} sourceAddr - source address for sending the ping
Expand Down Expand Up @@ -65,6 +65,10 @@ builder.getResult = function (target, config) {
]);
}

if (_config.deadline) {
throw new Error('There is no deadline option on windows');
}

if (_config.min_reply) {
ret = ret.concat([
'-n',
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/load-fixture-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ module.exports = function (platform) {
'**',
'*.txt',
]);
targetDirectory = path.posix.join.apply(path.posix, targetDirectory);
targetDirectory = path.posix.join.apply(path.posix, targetDirectory);

return glob.sync(targetDirectory);
};
82 changes: 82 additions & 0 deletions test/test-ping.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
'use strict';

/* global describe it before after*/
/* eslint no-unused-expressions: 0 */

Expand All @@ -17,6 +18,7 @@ var ping = require('..');

// Some constants
var ANSWER = require('./fixture/answer');

var PLATFORMS = [
'window',
'darwin',
Expand Down Expand Up @@ -117,6 +119,86 @@ var createTestCase = function (platform, pingExecution) {
});
};

describe('ping timeout and deadline options', function () {
describe('on linux platform', function () {
beforeEach(function () {
this.platformStub = sinon.stub(os, 'platform',
function () { return 'linux'; });
const fixturePath = path.join(__dirname, 'fixture',
'linux', 'en', 'sample1.txt');
this.spawnStub = sinon.stub(cp, 'spawn', mockOutSpawn(fixturePath));
});

afterEach(function () {
this.platformStub.restore();
this.spawnStub.restore();
});

it('are forwarded to the ping binary', function () {
return ping.promise.probe('whatever', {
timeout: 47,
deadline: 83,
}).then(function () {
const spawnArgs = this.spawnStub.getCalls()[0].args;
const pingArgs = spawnArgs[1];
expect(pingArgs[pingArgs.indexOf('-W') + 1]).to.equal('47');
expect(pingArgs[pingArgs.indexOf('-w') + 1]).to.equal('83');
}.bind(this));
});
});

describe('on windows platform', function () {
beforeEach(function () {
this.platformStub = sinon.stub(os, 'platform',
function () { return 'window'; });
const fixturePath = path.join(__dirname, 'fixture',
'window', 'en', 'sample1.txt');
this.spawnStub = sinon.stub(cp, 'spawn', mockOutSpawn(fixturePath));
});

afterEach(function () {
this.platformStub.restore();
this.spawnStub.restore();
});

it('results in an error as deadline is not supported', function () {
return ping.promise.probe('whatever', {
timeout: 47,
deadline: 83,
}).then(function () {
throw new Error('deadline should result in an error');
}).catch(function () {});
});
});

describe('on mac platform', function () {
beforeEach(function () {
this.platformStub = sinon.stub(os, 'platform',
function () { return 'freebsd'; });
const fixturePath = path.join(__dirname, 'fixture',
'macos', 'en', 'sample1.txt');
this.spawnStub = sinon.stub(cp, 'spawn', mockOutSpawn(fixturePath));
});

afterEach(function () {
this.platformStub.restore();
this.spawnStub.restore();
});

it('are forwarded to the ping binary', function () {
return ping.promise.probe('whatever', {
timeout: 47,
deadline: 83,
}).then(function () {
const spawnArgs = this.spawnStub.getCalls()[0].args;
const pingArgs = spawnArgs[1];
expect(pingArgs[pingArgs.indexOf('-W') + 1]).to.equal('4700');
expect(pingArgs[pingArgs.indexOf('-t') + 1]).to.equal('83');
}.bind(this));
});
});
});

describe('Ping in callback mode', function () {
var pingExecution = function (fp, args) {
var deferred = q.defer();
Expand Down