'use strict'; /* global describe it before after*/ /* eslint no-unused-expressions: 0 */ var expect = require('chai').expect; var sinon = require('sinon'); var os = require('os'); var cp = require('child_process'); var q = require('q'); var fs = require('fs'); var path = require('path'); var util = require('util'); var events = require('events'); var loadFixturePath = require('./load-fixture-path'); var ping = require('..'); // Some constants var ANSWER = require('./fixture/answer'); var PLATFORMS = [ 'window', 'darwin', 'freebsd', // 'aix', 'android', 'linux', ]; var PLATFORM_TO_EXTRA_ARGUMENTS = { window: ['-n', '2'], darwin: ['-c', '2'], freebsd: ['-c', '2'], android: ['-c', '2'], linux: ['-c', '2'], }; var pathToAnswerKey = function (p) { var basename = path.posix.basename(p, '.txt'); var dirname = path.posix.basename(path.posix.dirname(p)); var osname = path.posix.basename( path.posix.dirname(path.posix.dirname(p)) ); return [osname, dirname, basename].join('_'); }; var mockOutSpawn = function (fp) { return function () { var e = new events.EventEmitter(); e.stdout = e; var s = fs.createReadStream(fp); s.on('data', function (line) { e.emit('data', line); }); s.on('close', function () { e.emit('close', 0); }); return e; }; }; var createTestCase = function (platform, pingExecution) { var stubs = []; describe(util.format('On %s platform', platform), function () { var fixturePaths = loadFixturePath(platform); before(function () { stubs.push( sinon.stub(os, 'platform').callsFake(function () { return platform; }) ); }); after(function () { stubs.forEach(function (stub) { stub.restore(); }); }); describe('runs with default config', function () { fixturePaths.forEach(function (fp) { it( util.format('Using |%s|', pathToAnswerKey(fp)), function () { return pingExecution(fp); } ); }); }); describe('runs with custom config', function () { fixturePaths.forEach(function (fp) { it( util.format('Using |%s|', pathToAnswerKey(fp)), function () { return pingExecution(fp, { timeout: 10, extra: PLATFORM_TO_EXTRA_ARGUMENTS[platform], }); } ); }); }); describe('runs with custom config with default gone', function () { fixturePaths.forEach(function (fp) { it( util.format('Using |%s|', pathToAnswerKey(fp)), function () { return pingExecution(fp, { timeout: false, extra: PLATFORM_TO_EXTRA_ARGUMENTS[platform], }); } ); }); }); }); }; describe('ping timeout and deadline options', function () { describe('on linux platform', function () { beforeEach(function () { this.platformStub = sinon.stub(os, 'platform').callsFake(function () { return 'linux'; }); const fixturePath = path.join(__dirname, 'fixture', 'linux', 'en', 'sample1.txt'); this.spawnStub = sinon.stub(cp, 'spawn').callsFake(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').callsFake(function () { return 'window'; }); const fixturePath = path.join(__dirname, 'fixture', 'window', 'en', 'sample1.txt'); this.spawnStub = sinon.stub(cp, 'spawn').callsFake(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').callsFake(function () { return 'freebsd'; }); const fixturePath = path.join(__dirname, 'fixture', 'macos', 'en', 'sample1.txt'); this.spawnStub = sinon.stub(cp, 'spawn').callsFake(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('47000'); 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(); var stub = sinon.stub(cp, 'spawn').callsFake(mockOutSpawn(fp)); var cb = function (isAlive, err) { if (err) { deferred.reject(err); } else { deferred.resolve(isAlive); } }; var _args = args; if (fp.includes('v6')) { _args = _args || {}; _args.v6 = true; } ping.sys.probe('whatever', cb, _args); stub.restore(); return deferred.promise.then(function (data) { var answerKey = pathToAnswerKey(fp); var actualIsAlive = data; var expectIsAlive = ANSWER[answerKey].alive; expect(actualIsAlive).to.equal(expectIsAlive); }); }; PLATFORMS.forEach(function (platform) { createTestCase(platform, pingExecution); }); }); describe('Ping in promise mode', function () { var pingExecution = function (fp, args) { var stub = sinon.stub(cp, 'spawn').callsFake(mockOutSpawn(fp)); var ret = null; var _args = args; if (fp.includes('v6')) { _args = _args || {}; _args.v6 = true; } ret = ping.promise.probe('whatever', _args); stub.restore(); return ret.then(function (data) { var answerKey = pathToAnswerKey(fp); var actualData = data; var expectData = ANSWER[answerKey]; expect(actualData).to.deep.equal(expectData); }); }; PLATFORMS.forEach(function (platform) { createTestCase(platform, pingExecution); }); }); describe('Ping ipv6 on MAC OS', function () { var platform = 'darwin'; var stubs = []; before(function () { stubs.push( sinon.stub(os, 'platform').callsFake(function () { return platform; }) ); }); after(function () { stubs.forEach(function (stub) { stub.restore(); }); }); describe('With timeout setting', function () { var fixturePaths = loadFixturePath(platform); fixturePaths.forEach(function (fp) { it('Should raise an error', function (done) { var stub = sinon.stub(cp, 'spawn').callsFake(mockOutSpawn(fp)); var ret = ping.promise.probe( 'whatever', {v6: true, timeout: 10} ); stub.restore(); ret.then(function () { done(new Error('It should not be success')); }).catch(function (err) { expect(err.message).to.be.a('string'); expect(err.message).to.include('no timeout option'); done(); }); }); }); }); }); describe('Ping in promise mode with unknown exception', function () { var pingExecution = function (fp, args) { var unknownException = new Error('Unknown error!'); var stub = sinon.stub(cp, 'spawn').throws(unknownException); var ret = null; var _args = args; if (fp.includes('v6')) { _args = _args || {}; _args.v6 = true; } ret = ping.promise.probe('whatever', _args); stub.restore(); return ret.catch(function (err) { expect(err.message).to.be.a('string'); expect(err.message).to.include('Unknown error!'); }); }; PLATFORMS.forEach(function (platform) { createTestCase(platform, pingExecution); }); });