From 4c148e28329be3ee768173ddd9d2a9230ab59955 Mon Sep 17 00:00:00 2001 From: Zachary Boyd Date: Thu, 9 Aug 2018 16:13:48 -0400 Subject: [PATCH] completes mocha test for TorProcess --- bin/tor-router | 20 +-- src/TorProcess.js | 5 + test/test.js | 336 +++++++++------------------------------------- 3 files changed, 69 insertions(+), 292 deletions(-) diff --git a/bin/tor-router b/bin/tor-router index 8112329..47b80fa 100755 --- a/bin/tor-router +++ b/bin/tor-router @@ -75,27 +75,9 @@ let argv_config = require('yargs') } }); -let env_whitelist = [ "CONTROL_PORT", "TOR_PATH", "INSTANCES", "SOCKS_PORT", "DNS_PORT", "HTTP_PORT", "LOG_LEVEL", 'PARENT_DATA_DIRECTORIES', 'LOAD_BALANCE_METHOD', "controlPort", "torPath", "instances", "socksPort", "dnsPort", "httpPort", "logLevel", 'parentDataDirectories', 'loadBalanceMethod']; +nconf = require(`${__dirname}/../src/nconf_load_env.js`)(nconf); nconf - .env({ - whitelist: env_whitelist, - parseValues: true, - transform: (obj) => { - if (env_whitelist.includes(obj.key)) { - if (obj.key.indexOf('_') !== -1) { - let a = obj.key.toLowerCase().split('_'); - i = 1; - while (i < a.length) { - a[i] = a[i][0].toUpperCase() + a[i].substr(1); - i++; - } - obj.key = a.join(''); - } - } - return obj; - } - }) .argv(argv_config); let nconf_config = nconf.get('config'); diff --git a/src/TorProcess.js b/src/TorProcess.js index 9ba0d27..a779502 100644 --- a/src/TorProcess.js +++ b/src/TorProcess.js @@ -157,6 +157,7 @@ class TorProcess extends EventEmitter { this.emit('error', err); } else { this.logger.debug(`[tor-${this.instance_name}]: authenticated with tor instance via the control port`); + this.control_port_connected = true; this.emit('controller_ready'); } }); @@ -167,18 +168,22 @@ class TorProcess extends EventEmitter { let text = Buffer.from(data).toString('utf8'); let msg = text.split('] ').pop(); if (text.indexOf('Bootstrapped 100%: Done') !== -1){ + this.bootstrapped = true; this.emit('ready'); } if (text.indexOf('Opening Control listener on') !== -1) { + this.control_port_listening = true; this.emit('control_listen'); } if (text.indexOf('Opening Socks listener on') !== -1) { + this.socks_port_listening = true; this.emit('socks_listen'); } if (text.indexOf('Opening DNS listener on') !== -1) { + this.dns_port_listening = true; this.emit('dns_listen'); } diff --git a/test/test.js b/test/test.js index bd8b137..a1deca6 100644 --- a/test/test.js +++ b/test/test.js @@ -6,304 +6,94 @@ temp.track(); const TorRouter = require('../'); const getPort = require('get-port'); const dns = require('native-dns'); -const io = require('socket.io-client'); const _ = require('lodash'); +const winston = require('winston'); -const get_ip = function (callback) { - request({ - url: 'http://monip.org', - agentClass: SocksAgent, - agentOptions: { - socksHost: '127.0.0.1', - socksPort: this.socks_port - } - }, (error, res, body) => { - var ip; - if (body) - ip = body.split('IP : ').pop().split('<').shift(); +var colors = require('mocha/lib/reporters/base').colors; +colors['diff added'] = 32; +colors['diff removed'] = 31; - callback(error || (!body && new Error("Couldn't grab IP")), ip) - }); -}; - - -// describe('ControlServer', function () { -// let ports = {}; -// var controlServer; -// var client; - -// before((done) => { -// async.autoInject({ -// dnsPort: (cb) => { getPort().then((port) => { cb(null, port); }) }, -// socksPort: (cb) => { getPort().then((port) => { cb(null, port); }) }, -// controlPort: (cb) => { getPort().then((port) => { cb(null, port); }) } -// }, (error, context) => { -// _.extend(ports, context); - -// done(error); -// }); -// }); - -// controlServer = new TorRouter.ControlServer(); - -// describe('#listen(port, callback)', () => { -// it('should listen on the control port', (done) => { controlServer.listen(ports.controlPort, done); }) -// it('should connect to control server', (done) => { -// client = io.connect(`ws://127.0.0.1:${ports.controlPort}`); - -// client.once('connect_error', (err) => { -// console.log(err) -// done(err); -// }); - -// client.once('connected', () => { -// done(); -// }) -// }); -// }); - -// describe('#createTorPool(options)', function () { -// it('should create a tor pool', () => { -// client.emit('createTorPool', {}); -// }); -// }); - -// describe('#createSOCKSServer(port)', function () { -// it('should create a socks server', () => { -// client.emit('createSOCKSServer', ports.socksPort); -// }); -// }); - -// describe('#createInstances(instances, callback)', function () { -// this.timeout(Infinity); -// it('should create 1 instance', function (done) { -// client.emit('createInstances', 1, (err) => { -// if (err) return done(error); - -// done(((controlServer.torPool.instances.length !== 1) && new Error(`It doesn't have 1 instance`))); -// }); -// }) -// }) - -// describe('#newIps()', function (done) { -// var oldip; -// this.timeout(Infinity); -// it('should grab the current ip', (done) => { -// get_ip.call({ socks_port: ports.socksPort })((error, ip) => { -// oldip = ip; -// done(error); -// }); -// }); - -// it('should change the ip', (done) => { -// client.emit('newIps'); -// setTimeout(() => { -// done(); -// }, 1000); -// }); - -// it('should have a diffrent ip', (done) => { -// get_ip.call({ socks_port: ports.socksPort })((error, ip) => { -// done(((oldip === ip) && new Error("ip hasn't changed"))); -// }); -// }); -// }); - -// after(() => { -// controlServer.torPool.exit(); -// client.close(); -// controlServer.close(); -// }); -// }); +var nconf = require('nconf') +nconf = require(`${__dirname}/../src/nconf_load_env.js`)(nconf); +nconf.defaults(require(`${__dirname}/../src/default_config.js`)); +var logger = winston.createLogger({ + level: 'info', + format: winston.format.simple(), + transports: [new (require('winston-null-transport'))() ] +}); describe('TorProcess', function () { - const TOR_DATA_DIR = temp.mkdirSync(); - const TorProcess = TorRouter.TorProcess; - + const torDataDir = temp.mkdirSync(); + + var tor = new (TorRouter.TorProcess)(nconf.get('torPath'), { DataDirectory: torDataDir, ProtocolWarnings: 0 }, null, logger); describe('#create()', function () { - var tor = new TorProcess('tor', { DataDirectory: TOR_DATA_DIR }); + this.timeout(60000); - this.timeout(Infinity); - - it('should create the process without an error', function (done) { + it('should create the child process', function (done) { tor.create(done); }); - it('should signal ready when bootstrapped', function (done) { + it('should signal when it is listening on the control port', function (done) { + if (tor.control_port_listening) + return done(); + tor.once('control_listen', done); + }); + + it('should signal when connected to the control port', function (done) { + if (tor.control_port_connected) + return done(); + tor.once('controller_ready', done); + }); + + it('should signal when it is listening on the socks port', function (done) { + if (tor.socks_port_listening) + return done(); + tor.once('socks_listen', done); + }); + + it('should signal when it is listening on the dns port', function (done) { + if (tor.dns_port_listening) + return done(); + tor.once('dns_listen', done); + }); + + it('should signal when bootstrapped', function (done) { tor.once('error', done); + if (tor.bootstrapped) + return done(); tor.once('ready', done); }); + }); - after('shutdown tor', function () { - tor.exit(); + describe('#set_config(keyword, value)', function () { + it('should set sample configuration option via the control protocol', function (done) { + tor.set_config('ProtocolWarnings', 1, done); }); }); - describe('#new_ip()', function () { - var tor = new TorProcess('tor', { DataDirectory: TOR_DATA_DIR }); - var old_ip = null; - this.timeout(Infinity); - - - before('create a tor instance', function (done) { - tor.once('error', done); - tor.once('ready', done); - tor.create(); - }); - - it('should have an ip address', function (done) { - get_ip.call({ socks_port: tor.socks_port }, (err, ip) => { - if (err) return done(err); - - old_ip = ip; - done(err); + describe('#get_config(keyword, value)', function () { + it('should retrieve sample configuration option via the control protocol', function (done) { + tor.get_config('ProtocolWarnings', function (error, value) { + done(error, (value == 1)); }); }); - - it('should have a new ip address after sending HUP', function (done) { - tor.new_ip(); - setTimeout(() => { - get_ip.call({ socks_port: tor.socks_port }, (err, ip) => { - if (err) return done(err); - - if (ip === old_ip) - done(new Error(`IP hasn't changed ${old_ip} === ${ip}`)); - else - done(); - }); - }, (10*1000)); - }); - - after('shutdown tor', function () { - tor.exit(); - }); }); -}); -describe('TorPool', function () { - var TorPool = TorRouter.TorPool; - var pool = new TorPool('tor'); - this.timeout(Infinity); - describe('#create', function () { - it('should create two instances without any problems', function (done) { - pool.create(2, function (error) { - if (error) return done(error); - done((pool.instances.length !== 2) && new Error('pool does not have two instances')); - }); - }); - - }); - - describe('#remove', function () { - it('should remove 2 instances from the pool', function (done) { - pool.remove(2, function (error) { - if (error) return done(error); - done((pool.instances.length) && new Error('pool has two instances')); - }) - }); - }) - - after(function () { - pool.exit(); - }); -}) - -describe('DNSServer', function () { - var TorPool = TorRouter.TorPool; - var DNSServer = TorRouter.DNSServer; - var port; - var pool = new TorPool('tor'); - var dns_server = new DNSServer(pool); - describe('#on("request")', function () { - this.timeout(Infinity); - - - before((done) => { - getPort().then(($port) => { - port = $port; - dns_server.serve(port); - done() - }); - }) - - it('should startup tor', (done) => { - - pool.create(2, done); - }) - - it('should be able to resolve "google.com" ', function (done) { - - - let req = dns.Request({ - question: dns.Question({ name: 'google.com', type: 'A' }), - server: { address: '127.0.0.1', port: port, type: 'udp' }, - timeout: 5000 - }); - - req.on('timeout', () => { - done && done(new Error("Request timed out")); - done = null; - }); - - req.on('message', (e, m) => { - done && done(((!m) || (!m.answer.length)) && new Error('Unable to resolve host')); - done = null; - }); - - req.send(); - }); - - after(function () { - pool.exit(); - dns_server.close(); + describe('#new_identity()', function () { + it('should use a new identity', function (done) { + tor.new_identity(done); }); }); -}); -describe('SOCKSServer', function () { - var TorPool = TorRouter.TorPool; - var SOCKSServer = TorRouter.SOCKSServer; - - var pool = new TorPool('tor'); - var socks = new SOCKSServer(pool); - - this.timeout(Infinity); - - var port; - - before((done) => { - getPort().then(($port) => { - port = $port; - socks.listen(port, (done)); - }); - }) - - describe('#on("connection")', function () { - var ip; - - it('should startup tor ', (done) => { - pool.create(2, done); - }) - - it('should get an ip address', function (done) { - get_ip.call({ socks_port: port }, (err, _ip) => { - ip = _ip; - done(err || (!ip && new Error('could not get an ip'))) - }); - }); - - it('should have a different ip', function (done) { - get_ip.call({ socks_port: port }, (err, _ip) => { - - done(err || (!ip && new Error('could not get an ip')) || ((_ip === ip) && new Error('IP has not changed'))); - }); - }); - - after(() => { - pool.exit(); - socks.close(); + describe('#signal()', function () { + it('should send a signal via the control protocol', function (done) { + tor.signal('DEBUG', done); }); }); -}); + after('shutdown tor', function () { + tor.exit(); + require('fs').unlinkSync(torDataDir); + }); +}); \ No newline at end of file