1 | 'use strict';
|
2 |
|
3 | var async = require('async');
|
4 | var fs = require('fs');
|
5 | var os = require('os');
|
6 | var path = require('path');
|
7 | var spawn = require('child_process').spawn;
|
8 | var downloader = require('./downloader');
|
9 | var tunnelLocation = void 0;
|
10 | var activeTunnel = void 0;
|
11 | var started = false;
|
12 |
|
13 | function logger(msg) {
|
14 | console.log.apply(console, arguments);
|
15 | }
|
16 |
|
17 | function download(options, callback) {
|
18 | tunnelLocation = path.normalize(path.join(__dirname, '../testingbot-tunnel.jar'));
|
19 |
|
20 | var url = 'https://testingbot.com/tunnel/testingbot-tunnel.jar';
|
21 |
|
22 | if (options.tunnelVersion) {
|
23 | tunnelLocation = path.normalize(path.join(__dirname, '../testingbot-tunnel-' + options.tunnelVersion + '.jar'));
|
24 | url = 'https://testingbot.com/tunnel/testingbot-tunnel-' + options.tunnelVersion + '.jar';
|
25 | }
|
26 |
|
27 | try {
|
28 | var tunnelFile = fs.statSync(tunnelLocation);
|
29 | if (tunnelFile['size'] > 1024) {
|
30 | return callback(null);
|
31 | }
|
32 | } catch (ignore) {}
|
33 |
|
34 | downloader.get(url, { fileName: 'testingbot-tunnel', destination: tunnelLocation }, function (err, destination) {
|
35 | if (err) {
|
36 | return callback(new Error('Could not download the tunnel from TestingBot - please check your connection. ' + err.message));
|
37 | }
|
38 |
|
39 | return callback(null);
|
40 | });
|
41 | }
|
42 |
|
43 | function run(options, callback) {
|
44 | if (!fs.existsSync(tunnelLocation)) {
|
45 | return callback(new Error('Tunnel jar file is not present in ' + tunnelLocation));
|
46 | }
|
47 |
|
48 | var checkJava = spawn('java');
|
49 | checkJava.on('error', function (err) {
|
50 | return callback(new Error('Java might not be installed, necessary to use testingbot-tunnel ' + err.message));
|
51 | });
|
52 |
|
53 | var onReady = function onReady() {
|
54 | started = true;
|
55 | logger('Tunnel is ready');
|
56 | callback(null, activeTunnel);
|
57 | };
|
58 |
|
59 | var args = [];
|
60 |
|
61 | args.push('-jar');
|
62 | args.push(tunnelLocation);
|
63 |
|
64 | if (options.apiKey) {
|
65 | args.push(options.apiKey);
|
66 | }
|
67 |
|
68 | if (options.apiSecret) {
|
69 | args.push(options.apiSecret);
|
70 | }
|
71 |
|
72 | for (var option in options) {
|
73 | if (option === 'apiKey' || option === 'apiSecret' || option === 'verbose' || option === 'tunnelVersion') {
|
74 | continue;
|
75 | }
|
76 |
|
77 | if (options[option]) {
|
78 | args.push('--' + option);
|
79 | args.push(options[option]);
|
80 | } else {
|
81 | args.push('--' + option);
|
82 | }
|
83 | }
|
84 |
|
85 | var readyFile = path.join(os.tmpdir(), 'testingbot.ready');
|
86 | try {
|
87 | if (fs.statSync(readyFile).isFile()) {
|
88 | logger('Tunnel Readyfile already exists, removing');
|
89 | fs.unlinkSync(readyFile);
|
90 | }
|
91 | } catch (ignore) {}
|
92 |
|
93 | args.push('-f');
|
94 | args.push(readyFile);
|
95 |
|
96 | var readyFileChecker = setInterval(function () {
|
97 | fs.stat(readyFile, function (error, stat) {
|
98 | if (!error) {
|
99 | clearInterval(readyFileChecker);
|
100 | onReady();
|
101 | }
|
102 | });
|
103 | }, 800);
|
104 |
|
105 | if (options.verbose) {
|
106 | logger('Starting tunnel with options', args);
|
107 | }
|
108 | activeTunnel = spawn('java', args, {});
|
109 |
|
110 | activeTunnel.stderr.on('data', function (data) {
|
111 | data = data.toString().trim();
|
112 | if (options.verbose && data !== '') {
|
113 | logger(data);
|
114 | }
|
115 | if (data.indexOf('is available for download') > -1) {
|
116 | logger(data);
|
117 | }
|
118 | if (data.indexOf('error code : 401') > -1) {
|
119 | activeTunnel.error = 'Invalid credentials. Please supply the correct key/secret obtained from TestingBot.com';
|
120 | activeTunnel.close();
|
121 | }
|
122 | });
|
123 |
|
124 | activeTunnel.stdout.on('data', function (data) {
|
125 | data = data.toString().trim();
|
126 | if (options.verbose && data !== '') {
|
127 | logger(data);
|
128 | }
|
129 | });
|
130 |
|
131 | activeTunnel.close = function (closeCallback) {
|
132 | if (closeCallback) {
|
133 | if (!activeTunnel) {
|
134 | closeCallback();
|
135 | } else {
|
136 | activeTunnel.on('close', function () {
|
137 | closeCallback();
|
138 | });
|
139 | }
|
140 | }
|
141 | activeTunnel.kill('SIGINT');
|
142 | };
|
143 |
|
144 | activeTunnel.on('exit', function (code, signal) {
|
145 | logger('Closing TestingBot Tunnel');
|
146 | if (!started) {
|
147 | callback(new Error(activeTunnel.error ? activeTunnel.error : 'Could not start TestingBot Tunnel. Exit code ' + code + ' signal: ' + signal));
|
148 | }
|
149 |
|
150 | started = false;
|
151 | activeTunnel = null;
|
152 | });
|
153 | }
|
154 |
|
155 | function killTunnel(callback) {
|
156 | if (!callback) {
|
157 | callback = function callback() {};
|
158 | }
|
159 |
|
160 | if (!activeTunnel) {
|
161 | return callback(new Error('no active tunnel'));
|
162 | }
|
163 |
|
164 | activeTunnel.kill('SIGINT');
|
165 | callback(null);
|
166 | }
|
167 |
|
168 | function downloadAndRun(options, callback) {
|
169 | if (!options) {
|
170 | options = {};
|
171 | }
|
172 |
|
173 | if (!callback) {
|
174 | callback = function callback() {};
|
175 | }
|
176 |
|
177 | async.waterfall([async.apply(download, options), async.apply(run, options)], callback);
|
178 | }
|
179 |
|
180 | module.exports = downloadAndRun;
|
181 | module.exports.kill = killTunnel; |
\ | No newline at end of file |