UNPKG

testingbot-tunnel-launcher

Version:
236 lines (190 loc) 6.83 kB
'use strict'; var async = require('async'); var _require = require('child_process'), exec = _require.exec; var fs = require('fs'); var os = require('os'); var path = require('path'); var spawn = require('child_process').spawn; var downloader = require('./downloader'); var tunnelLocation = void 0; var activeTunnel = void 0; var started = false; function logger(msg) { console.log.apply(console, arguments); } function download(options, callback) { tunnelLocation = path.normalize(path.join(__dirname, '../testingbot-tunnel.jar')); var url = 'https://testingbot.com/tunnel/testingbot-tunnel.jar'; if (options.tunnelVersion) { tunnelLocation = path.normalize(path.join(__dirname, '../testingbot-tunnel-' + options.tunnelVersion + '.jar')); url = 'https://testingbot.com/tunnel/testingbot-tunnel-' + options.tunnelVersion + '.jar'; } try { var exists = fs.existsSync(tunnelLocation); if (exists) { return exec('java -jar ' + tunnelLocation + ' -h', function (error, stdout, stderr) { if (error || stderr) { logger('Found a cached testingbot-tunnel.jar file, but it might be corrupt. Redownloading.'); downloadTunnel(url, tunnelLocation, callback); } else { callback(null); } }); } } catch (ignore) {} return downloadTunnel(url, tunnelLocation, callback); } function downloadTunnel(url, tunnelLocation, callback) { downloader.get(url, { fileName: 'testingbot-tunnel', destination: tunnelLocation }, function (err) { if (err) { return callback(new Error('Could not download the tunnel from TestingBot - please check your connection. ' + err.message)); } return callback(null); }); } function createArgs(options) { var args = []; args.push('-jar'); args.push(tunnelLocation); var optionMapping = { 'tunnelIdentifier': 'tunnel-identifier', 'noBump': 'nobump', 'noCache': 'nocache' }; if (options.apiKey) { args.push(options.apiKey); } if (options.apiSecret) { args.push(options.apiSecret); } for (var option in options) { if (option === 'apiKey' || option === 'apiSecret' || option === 'verbose' || option === 'tunnelVersion') { continue; } var optionName = optionMapping[option] || option; if (options[option] && typeof options[option] === 'string') { args.push('--' + optionName); args.push(options[option]); } else if (options[option]) { args.push('--' + optionName); } } return args; } function run(options, callback) { if (!fs.existsSync(tunnelLocation)) { return callback(new Error('Tunnel jar file is not present in ' + tunnelLocation)); } var checkJava = spawn('java'); checkJava.on('error', function (err) { return callback(new Error('Java might not be installed, necessary to use testingbot-tunnel ' + err.message)); }); var onReady = function onReady() { started = true; logger('Tunnel is ready'); callback(null, activeTunnel); }; var onError = function onError(waitCounter) { var errorMessage = 'Tunnel failed to launch in ' + waitCounter + ' seconds.'; logger(errorMessage); callback(new Error(errorMessage), null); }; var readyFile = path.join(os.tmpdir(), 'testingbot.ready'); function checkReadyFile() { var waitCounter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; fs.access(readyFile, fs.constants.F_OK, function (error) { if (!error) { clearInterval(readyFileChecker); return onReady(); } if (waitCounter > 90) { clearInterval(readyFileChecker); return onError(waitCounter); } waitCounter += 1; }); } var readyFileChecker = setInterval(function () { return checkReadyFile(); }, 1000); var args = createArgs(options); try { if (fs.statSync(readyFile).isFile()) { logger('Tunnel Readyfile already exists, removing'); fs.unlinkSync(readyFile); } } catch (ignore) {} args.push('-f'); args.push(readyFile); if (options.verbose) { logger('Starting tunnel with options', args); } activeTunnel = spawn('java', args, {}); activeTunnel.stderr.on('data', function (data) { data = data.toString().trim(); if (options.verbose && data !== '') { logger(data); } if (data.indexOf('is available for download') > -1) { logger(data); } if (data.indexOf('401 Unauthorized') > -1) { activeTunnel.error = 'Invalid credentials. Please supply the correct key/secret obtained from TestingBot.com'; activeTunnel.close(); } else if (data.indexOf('minutes left') > -1) { activeTunnel.error = 'You do not have any minutes left. Please upgrade your account at TestingBot.com'; activeTunnel.close(); } }); activeTunnel.stdout.on('data', function (data) { data = data.toString().trim(); if (options.verbose && data !== '') { logger(data); } }); activeTunnel.close = function (closeCallback) { if (closeCallback) { if (!activeTunnel) { closeCallback(); } else { activeTunnel.on('close', function () { closeCallback(); }); } } activeTunnel.kill('SIGINT'); }; activeTunnel.on('exit', function (code, signal) { if (options.verbose) { logger('Closing TestingBot Tunnel'); } if (!started) { callback(new Error(activeTunnel.error ? activeTunnel.error : 'Could not start TestingBot Tunnel. Exit code ' + code + ' signal: ' + signal)); } started = false; activeTunnel = null; }); } function killTunnel(callback) { if (!callback) { callback = function callback() {}; } if (!activeTunnel) { return callback(new Error('no active tunnel')); } activeTunnel.kill('SIGINT'); callback(null); } function downloadAndRun(options, callback) { if (!options) { options = {}; } if (!callback) { callback = function callback() {}; } async.waterfall([async.apply(download, options), async.apply(run, options)], callback); } module.exports = downloadAndRun; module.exports.kill = killTunnel; module.exports.createArgs = createArgs;