Breaks the mocha test into individual files so tests can be run independently. Uses Promises in the mocha test. Adds a listen method to all servers
This commit is contained in:
parent
1c29679024
commit
b65fa27ba8
|
@ -5,4 +5,5 @@ npm-debug.log
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
.env
|
.env
|
||||||
README.md
|
README.md
|
||||||
Jenkinsfile
|
.vscode
|
||||||
|
.DS_Store
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
.env
|
.env
|
||||||
|
.vscode
|
||||||
|
.DS_Store
|
|
@ -1,4 +1,5 @@
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
.env
|
.env
|
||||||
Jenkinsfile
|
.vscode
|
||||||
|
.DS_Store
|
|
@ -2,10 +2,14 @@
|
||||||
|
|
||||||
## [4.0.0] - 2018-09-09
|
## [4.0.0] - 2018-09-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- All servers (DNS, HTTP, SOCKS and Control) all have a `listen` method which returns a Promise that will resolve when the server is listening.
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
- All methods now return promises instead of accepting callbacks. Methods now take advantage of async/await to increase readability.
|
- All methods now return promises instead of accepting callbacks. Methods now take advantage of async/await to increase readability.
|
||||||
- The `logger` argument to the constructor's of all classes is now optional
|
- The `logger` argument to the constructor's of all classes is now optional
|
||||||
- The mocha test has been split into individual files
|
- The `Config` property of instance definitions will now inherit from `TorPool.default_tor_config`.
|
||||||
|
- The mocha test has been split into individual files all under `test/`
|
||||||
|
|
||||||
### Removes
|
### Removes
|
||||||
- The `new_ips` and `new_ip_at` TorPool and `new_ip` TorProcess have been removed. Use `new_identites`, `new_identity_at` and `new_identity` instead.
|
- The `new_ips` and `new_ip_at` TorPool and `new_ip` TorProcess have been removed. Use `new_identites`, `new_identity_at` and `new_identity` instead.
|
||||||
|
|
|
@ -41,7 +41,7 @@ For example: `tor-router -j 3 -s 9050` would start the proxy with 3 tor instance
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Tests are written in mocha and can be found under `test/test.js` and can be run with `npm test`
|
Tests are written in mocha and can be found under `test/` and can be run with `npm test`
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "bin/tor-router -s -d -j 1",
|
"start": "bin/tor-router -s -d -j 1",
|
||||||
"test": "mocha --exit test/index.js",
|
"test": "mocha --exit test",
|
||||||
"debug": "node --inspect-brk bin/tor-router"
|
"debug": "node --inspect-brk bin/tor-router"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -6,7 +6,7 @@ const rpc = require('jrpc2');
|
||||||
|
|
||||||
class ControlServer {
|
class ControlServer {
|
||||||
constructor(logger, nconf) {
|
constructor(logger, nconf) {
|
||||||
this.torPool = new TorPool(nconf.get('torPath'), null, nconf.get('parentDataDirectory'), nconf.get('loadBalanceMethod'), nconf.get('granaxOptions'),logger);
|
this.torPool = new TorPool(nconf.get('torPath'), (() => nconf.get('torConfig')), nconf.get('parentDataDirectory'), nconf.get('loadBalanceMethod'), nconf.get('granaxOptions'), logger);
|
||||||
this.logger = logger || require('./winston-silent-logger');
|
this.logger = logger || require('./winston-silent-logger');
|
||||||
this.nconf = nconf;
|
this.nconf = nconf;
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ class ControlServer {
|
||||||
|
|
||||||
server.expose('queryInstances', (async () => {
|
server.expose('queryInstances', (async () => {
|
||||||
if (!this.torPool)
|
if (!this.torPool)
|
||||||
throw new Error('No instances created');
|
throw new Error('No Tor Pool created');
|
||||||
|
|
||||||
this.torPool.instances.map(instance_info);
|
return this.torPool.instances.map(instance_info);
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
|
|
||||||
server.expose('queryInstanceByName', (async (instance_name) => {
|
server.expose('queryInstanceByName', (async (instance_name) => {
|
||||||
|
@ -36,7 +36,7 @@ class ControlServer {
|
||||||
if (!instance)
|
if (!instance)
|
||||||
throw new Error(`Instance "${instance_name}"" does not exist`);
|
throw new Error(`Instance "${instance_name}"" does not exist`);
|
||||||
|
|
||||||
return instance_info(i)
|
return instance_info(instance);
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
|
|
||||||
server.expose('queryInstanceAt', (async (index) => {
|
server.expose('queryInstanceAt', (async (index) => {
|
||||||
|
@ -51,9 +51,17 @@ class ControlServer {
|
||||||
return instance_info(this.torPool.instance_at(index));
|
return instance_info(this.torPool.instance_at(index));
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
|
|
||||||
server.expose('createInstances', this.torPool.create.bind(this.torPool));
|
server.expose('createInstances', (async (num) => {
|
||||||
|
let instances = await this.torPool.create(num);
|
||||||
|
|
||||||
server.expose('addInstances', this.torPool.add.bind(this.torPool));
|
return instances.map(instance_info);
|
||||||
|
}).bind(this));
|
||||||
|
|
||||||
|
server.expose('addInstances', (async (defs) => {
|
||||||
|
let instances = await this.torPool.create(defs);
|
||||||
|
|
||||||
|
return instances.map(instance_info);
|
||||||
|
}).bind(this));
|
||||||
|
|
||||||
server.expose('removeInstances', this.torPool.remove.bind(this.torPool));
|
server.expose('removeInstances', this.torPool.remove.bind(this.torPool));
|
||||||
|
|
||||||
|
@ -67,7 +75,7 @@ class ControlServer {
|
||||||
|
|
||||||
server.expose('newIdentityByName', this.torPool.new_identity_by_name.bind(this.torPool));
|
server.expose('newIdentityByName', this.torPool.new_identity_by_name.bind(this.torPool));
|
||||||
|
|
||||||
server.expose('nextInstance', (async () => this.torPool.next()).bind(this));
|
server.expose('nextInstance', (async () => instance_info( await this.torPool.next() )).bind(this));
|
||||||
|
|
||||||
server.expose('closeInstances', (async () => this.torPool.exit()).bind(this));
|
server.expose('closeInstances', (async () => this.torPool.exit()).bind(this));
|
||||||
|
|
||||||
|
@ -81,7 +89,7 @@ class ControlServer {
|
||||||
|
|
||||||
server.expose('setTorConfig', (async (config) => {
|
server.expose('setTorConfig', (async (config) => {
|
||||||
await Promise.all(Object.keys(config).map((key) => {
|
await Promise.all(Object.keys(config).map((key) => {
|
||||||
var value = config[key];
|
let value = config[key];
|
||||||
|
|
||||||
return this.torPool.set_config_all(key, value);
|
return this.torPool.set_config_all(key, value);
|
||||||
}));
|
}));
|
||||||
|
@ -124,23 +132,23 @@ class ControlServer {
|
||||||
return this.torPool;
|
return this.torPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
createSOCKSServer(port) {
|
async createSOCKSServer(port) {
|
||||||
this.socksServer = new SOCKSServer(this.torPool, this.logger);
|
this.socksServer = new SOCKSServer(this.torPool, this.logger);
|
||||||
this.socksServer.listen(port || 9050);
|
await this.socksServer.listen(port || 9050);
|
||||||
this.logger.info(`[socks]: Listening on ${port}`);
|
this.logger.info(`[socks]: Listening on ${port}`);
|
||||||
this.socksServer;
|
this.socksServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
createHTTPServer(port) {
|
async createHTTPServer(port) {
|
||||||
this.httpServer = new HTTPServer(this.torPool, this.logger);
|
this.httpServer = new HTTPServer(this.torPool, this.logger);
|
||||||
this.httpServer.listen(port || 9080);
|
await this.httpServer.listen(port || 9080);
|
||||||
this.logger.info(`[http]: Listening on ${port}`);
|
this.logger.info(`[http]: Listening on ${port}`);
|
||||||
this.httpServer;
|
this.httpServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
createDNSServer(port) {
|
async createDNSServer(port) {
|
||||||
this.dnsServer = new DNSServer(this.torPool, this.nconf.get('dns:options'), this.nconf.get('dns:timeout'), this.logger);
|
this.dnsServer = new DNSServer(this.torPool, this.nconf.get('dns:options'), this.nconf.get('dns:timeout'), this.logger);
|
||||||
this.dnsServer.serve(port || 9053);
|
await this.dnsServer.serve(port || 9053);
|
||||||
this.logger.info(`[dns]: Listening on ${port}`);
|
this.logger.info(`[dns]: Listening on ${port}`);
|
||||||
this.dnsServer;
|
this.dnsServer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,29 @@
|
||||||
const dns = require('native-dns');
|
const dns = require('native-dns');
|
||||||
const { UDPServer } = require('native-dns');
|
const { UDPServer } = require('native-dns');
|
||||||
|
const Promise = require('bluebird');
|
||||||
|
|
||||||
class DNSServer extends UDPServer {
|
class DNSServer extends UDPServer {
|
||||||
|
async listen() {
|
||||||
|
let args = Array.from(arguments);
|
||||||
|
let inner_func = super.serve;
|
||||||
|
|
||||||
|
if (!args[1])
|
||||||
|
args[1] = null;
|
||||||
|
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
args.push(() => {
|
||||||
|
let args = Array.from(arguments);
|
||||||
|
resolve.apply(args);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
inner_func.apply(this, args);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor(tor_pool, dns_options, dns_timeout, logger) {
|
constructor(tor_pool, dns_options, dns_timeout, logger) {
|
||||||
super(dns_options);
|
super(dns_options);
|
||||||
this.logger = logger || require('./winston-silent-logger');
|
this.logger = logger || require('./winston-silent-logger');
|
||||||
|
|
|
@ -2,12 +2,25 @@ const http = require('http');
|
||||||
const URL = require('url');
|
const URL = require('url');
|
||||||
const { Server } = http;
|
const { Server } = http;
|
||||||
|
|
||||||
|
const Promise = require('bluebird');
|
||||||
const socks = require('socksv5');
|
const socks = require('socksv5');
|
||||||
const SocksProxyAgent = require('socks-proxy-agent');
|
const SocksProxyAgent = require('socks-proxy-agent');
|
||||||
|
|
||||||
const TOR_ROUTER_PROXY_AGENT = 'tor-router';
|
const TOR_ROUTER_PROXY_AGENT = 'tor-router';
|
||||||
|
|
||||||
class HTTPServer extends Server {
|
class HTTPServer extends Server {
|
||||||
|
async listen() {
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
let args = Array.from(arguments);
|
||||||
|
let inner_func = super.listen;
|
||||||
|
args.push(() => {
|
||||||
|
let args = Array.from(arguments);
|
||||||
|
resolve.apply(args);
|
||||||
|
});
|
||||||
|
inner_func.apply(this, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor(tor_pool, logger) {
|
constructor(tor_pool, logger) {
|
||||||
let handle_http_connections = (req, res) => {
|
let handle_http_connections = (req, res) => {
|
||||||
let url = URL.parse(req.url);
|
let url = URL.parse(req.url);
|
||||||
|
@ -26,12 +39,12 @@ class HTTPServer extends Server {
|
||||||
req.on('data', onIncomingData);
|
req.on('data', onIncomingData);
|
||||||
req.on('end', preConnectClosed);
|
req.on('end', preConnectClosed);
|
||||||
req.on('error', function (err) {
|
req.on('error', function (err) {
|
||||||
logger.error("[http-proxy]: an error occured: "+err.message);
|
this.logger.error("[http-proxy]: an error occured: "+err.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
let connect = (tor_instance) => {
|
let connect = (tor_instance) => {
|
||||||
let socks_port = tor_instance.socks_port;
|
let socks_port = tor_instance.socks_port;
|
||||||
logger.verbose(`[http-proxy]: ${req.connection.remoteAddress}:${req.connection.remotePort} → 127.0.0.1:${socks_port} → ${url.hostname}:${url.port}`);
|
this.logger.verbose(`[http-proxy]: ${req.connection.remoteAddress}:${req.connection.remotePort} → 127.0.0.1:${socks_port} → ${url.hostname}:${url.port}`);
|
||||||
|
|
||||||
let proxy_req = http.request({
|
let proxy_req = http.request({
|
||||||
method: req.method,
|
method: req.method,
|
||||||
|
@ -74,7 +87,7 @@ class HTTPServer extends Server {
|
||||||
if (tor_pool.instances.length) {
|
if (tor_pool.instances.length) {
|
||||||
connect(tor_pool.next());
|
connect(tor_pool.next());
|
||||||
} else {
|
} else {
|
||||||
logger.debug(`[http-proxy]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
|
this.logger.debug(`[http-proxy]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
|
||||||
tor_pool.once('instance_created', connect);
|
tor_pool.once('instance_created', connect);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -85,7 +98,7 @@ class HTTPServer extends Server {
|
||||||
|
|
||||||
let connect = (tor_instance) => {
|
let connect = (tor_instance) => {
|
||||||
let socks_port = tor_instance.socks_port;
|
let socks_port = tor_instance.socks_port;
|
||||||
logger && logger.verbose(`[http-connect]: ${req.connection.remoteAddress}:${req.connection.remotePort} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${hostname}:${port}`)
|
this.logger && this.logger.verbose(`[http-connect]: ${req.connection.remoteAddress}:${req.connection.remotePort} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${hostname}:${port}`)
|
||||||
var outbound_socket;
|
var outbound_socket;
|
||||||
|
|
||||||
let onClose = (error) => {
|
let onClose = (error) => {
|
||||||
|
@ -125,7 +138,7 @@ class HTTPServer extends Server {
|
||||||
if (tor_pool.instances.length) {
|
if (tor_pool.instances.length) {
|
||||||
connect(tor_pool.next());
|
connect(tor_pool.next());
|
||||||
} else {
|
} else {
|
||||||
logger.debug(`[http-connect]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
|
this.logger.debug(`[http-connect]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
|
||||||
tor_pool.once('instance_created', connect);
|
tor_pool.once('instance_created', connect);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
const socks = require('socksv5');
|
const socks = require('socksv5');
|
||||||
|
const Promise = require('bluebird');
|
||||||
const { Server } = socks;
|
const { Server } = socks;
|
||||||
|
|
||||||
class SOCKSServer extends Server{
|
class SOCKSServer extends Server{
|
||||||
|
async listen() {
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
let args = Array.from(arguments);
|
||||||
|
let inner_func = super.listen;
|
||||||
|
args.push(() => {
|
||||||
|
let args = Array.from(arguments);
|
||||||
|
resolve.apply(args);
|
||||||
|
});
|
||||||
|
inner_func.apply(this, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor(tor_pool, logger) {
|
constructor(tor_pool, logger) {
|
||||||
let handleConnection = (info, accept, deny) => {
|
let handleConnection = (info, accept, deny) => {
|
||||||
let inbound_socket = accept(true);
|
let inbound_socket = accept(true);
|
||||||
|
@ -28,7 +41,7 @@ class SOCKSServer extends Server{
|
||||||
|
|
||||||
let connect = (tor_instance) => {
|
let connect = (tor_instance) => {
|
||||||
let socks_port = tor_instance.socks_port;
|
let socks_port = tor_instance.socks_port;
|
||||||
logger.verbose(`[socks]: ${info.srcAddr}:${info.srcPort} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${info.dstAddr}:${info.dstPort}`)
|
this.logger.verbose(`[socks]: ${info.srcAddr}:${info.srcPort} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${info.dstAddr}:${info.dstPort}`)
|
||||||
|
|
||||||
socks.connect({
|
socks.connect({
|
||||||
host: info.dstAddr,
|
host: info.dstAddr,
|
||||||
|
@ -60,7 +73,7 @@ class SOCKSServer extends Server{
|
||||||
if (tor_pool.instances.length) {
|
if (tor_pool.instances.length) {
|
||||||
connect(tor_pool.next());
|
connect(tor_pool.next());
|
||||||
} else {
|
} else {
|
||||||
logger.debug(`[socks]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
|
this.logger.debug(`[socks]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
|
||||||
tor_pool.once('instance_created', connect);
|
tor_pool.once('instance_created', connect);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,20 +29,33 @@ const WeightedList = require('js-weighted-list');
|
||||||
|
|
||||||
const TorProcess = require('./TorProcess');
|
const TorProcess = require('./TorProcess');
|
||||||
|
|
||||||
|
Promise.promisifyAll(fs);
|
||||||
|
|
||||||
class TorPool extends EventEmitter {
|
class TorPool extends EventEmitter {
|
||||||
constructor(tor_path, default_config, data_directory, load_balance_method, granax_options, logger) {
|
constructor(tor_path, default_config, data_directory, load_balance_method, granax_options, logger) {
|
||||||
|
if (!data_directory)
|
||||||
|
throw new Error('Invalid "data_directory"');
|
||||||
super();
|
super();
|
||||||
this._instances = [];
|
this._instances = [];
|
||||||
default_config = _.extend({}, (default_config || {}));
|
this._default_tor_config = default_config;
|
||||||
this.default_tor_config = default_config;
|
|
||||||
this.data_directory = data_directory;
|
this.data_directory = data_directory;
|
||||||
this.load_balance_method = load_balance_method;
|
this.load_balance_method = load_balance_method;
|
||||||
!fs.existsSync(this.data_directory) && fs.mkdirSync(this.data_directory);
|
|
||||||
this.tor_path = tor_path;
|
this.tor_path = tor_path;
|
||||||
this.logger = logger || require('./winston-silent-logger');
|
this.logger = logger || require('./winston-silent-logger');
|
||||||
this.granax_options = granax_options;
|
this.granax_options = granax_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get default_tor_config() {
|
||||||
|
if (typeof(this._default_tor_config) === 'function')
|
||||||
|
return this._default_tor_config();
|
||||||
|
else if (this._default_tor_config)
|
||||||
|
return _.cloneDeep(this._default_tor_config);
|
||||||
|
else
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
set default_tor_config(value) { this._default_tor_config = value; }
|
||||||
|
|
||||||
static get load_balance_methods() {
|
static get load_balance_methods() {
|
||||||
return {
|
return {
|
||||||
round_robin: function (instances) {
|
round_robin: function (instances) {
|
||||||
|
@ -68,9 +81,11 @@ class TorPool extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async create_instance(instance_definition) {
|
async create_instance(instance_definition) {
|
||||||
|
if (!(fs.existsSync(this.data_directory)))
|
||||||
|
await fs.mkdirAsync(this.data_directory);
|
||||||
|
|
||||||
this._instances._weighted_list = void(0);
|
this._instances._weighted_list = void(0);
|
||||||
if (!instance_definition.Config)
|
instance_definition.Config = _.extend(_.cloneDeep(this.default_tor_config), (instance_definition.Config || {}));
|
||||||
instance_definition.Config = _.extend({}, this.default_tor_config);
|
|
||||||
let instance_id = nanoid();
|
let instance_id = nanoid();
|
||||||
instance_definition.Config.DataDirectory = instance_definition.Config.DataDirectory || path.join(this.data_directory, (instance_definition.Name || instance_id));
|
instance_definition.Config.DataDirectory = instance_definition.Config.DataDirectory || path.join(this.data_directory, (instance_definition.Name || instance_id));
|
||||||
|
|
||||||
|
@ -138,7 +153,7 @@ class TorPool extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
this._instances = load_balance_methods[this.load_balance_method](this._instances);
|
this._instances = TorPool.load_balance_methods[this.load_balance_method](this._instances);
|
||||||
return this.instances[0];
|
return this.instances[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +163,7 @@ class TorPool extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async new_identites() {
|
async new_identites() {
|
||||||
await Promise.all(this.instances.map((instance) => instance.new_identity(next)));
|
await Promise.all(this.instances.map((instance) => instance.new_identity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
async new_identity_at(index) {
|
async new_identity_at(index) {
|
||||||
|
@ -201,7 +216,7 @@ class TorPool extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async signal_all(signal) {
|
async signal_all(signal) {
|
||||||
await Promise.all(this.instances.map((instance) => instance.signal(signal, next)));
|
await Promise.all(this.instances.map((instance) => instance.signal(signal)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async signal_by_name(name, signal) {
|
async signal_by_name(name, signal) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ class TorProcess extends EventEmitter {
|
||||||
|
|
||||||
let configFile = await temp.openAsync('tor-router');
|
let configFile = await temp.openAsync('tor-router');
|
||||||
let configPath = configFile.path;
|
let configPath = configFile.path;
|
||||||
fs.writeFileAsync(configPath, text);
|
await fs.writeFileAsync(configPath, text);
|
||||||
|
|
||||||
let tor = spawn(this.tor_path, ['-f', configPath], {
|
let tor = spawn(this.tor_path, ['-f', configPath], {
|
||||||
stdio: ['ignore', 'pipe', 'pipe'],
|
stdio: ['ignore', 'pipe', 'pipe'],
|
||||||
|
|
|
@ -24,6 +24,7 @@ async function main(nconf, logger) {
|
||||||
let control = new ControlServer(logger, nconf);
|
let control = new ControlServer(logger, nconf);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await control.listen(control_port);
|
||||||
|
|
||||||
if (socks_port) {
|
if (socks_port) {
|
||||||
if (typeof(socks_port) === 'boolean') {
|
if (typeof(socks_port) === 'boolean') {
|
||||||
|
@ -50,13 +51,11 @@ async function main(nconf, logger) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instances) {
|
if (instances) {
|
||||||
logger.info(`[tor]: starting ${Array.isArray(instances) ? instances.length : instances} tor instances...`)
|
logger.info(`[tor]: starting ${Array.isArray(instances) ? instances.length : instances} tor instance(s)...`)
|
||||||
await control.torPool.create(instances);
|
await control.torPool.create(instances);
|
||||||
|
|
||||||
logger.info('[tor]: tor started');
|
logger.info('[tor]: tor started');
|
||||||
}
|
}
|
||||||
|
|
||||||
await control.listen(control_port);
|
|
||||||
logger.info(`[control]: control Server listening on ${control_port}`);
|
logger.info(`[control]: control Server listening on ${control_port}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[global]: error starting application: ${error.stack}`);
|
logger.error(`[global]: error starting application: ${error.stack}`);
|
||||||
|
@ -160,6 +159,8 @@ nconf
|
||||||
let nconf_config = nconf.get('config');
|
let nconf_config = nconf.get('config');
|
||||||
if (nconf_config) {
|
if (nconf_config) {
|
||||||
nconf.file(nconf_config);
|
nconf.file(nconf_config);
|
||||||
|
} else {
|
||||||
|
nconf.use('memory');
|
||||||
}
|
}
|
||||||
|
|
||||||
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const assert = require('chai').assert;
|
const assert = require('chai').assert;
|
||||||
const rpc = require('jrpc2');
|
|
||||||
const Promise = require('bluebird');
|
|
||||||
const nconf = require('nconf');
|
const nconf = require('nconf');
|
||||||
|
const getPort = require('get-port');
|
||||||
|
|
||||||
const logger = require('../src/winston-silent-logger');
|
nconf.use('memory');
|
||||||
|
|
||||||
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
||||||
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
const { ControlServer } = require('../');
|
const { ControlServer, TorPool, HTTPServer, SOCKSServer, DNSServer } = require('../');
|
||||||
|
|
||||||
let controlServer = new ControlServer(logger, nconf);
|
let controlServer = new ControlServer(null, nconf);
|
||||||
let controlPort;
|
let controlPort;
|
||||||
|
|
||||||
describe('ControlServer', function () {
|
describe('ControlServer', function () {
|
||||||
describe('#listen(port)', function () {
|
describe('#listen(port)', function () {
|
||||||
it('should bind to a given port', async function () {
|
it('should bind to a given port', async function () {
|
||||||
|
@ -24,7 +23,7 @@ describe('ControlServer', function () {
|
||||||
it('should create a TorPool with a given configuration', function () {
|
it('should create a TorPool with a given configuration', function () {
|
||||||
let torPool = controlServer.createTorPool({ ProtocolWarnings: 1 });
|
let torPool = controlServer.createTorPool({ ProtocolWarnings: 1 });
|
||||||
|
|
||||||
assert.ok((controlServer.torPool instanceof (TorRouter.TorPool)));
|
assert.instanceOf(controlServer.torPool, TorPool);
|
||||||
assert.equal(1, torPool.default_tor_config.ProtocolWarnings);
|
assert.equal(1, torPool.default_tor_config.ProtocolWarnings);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -60,5 +59,3 @@ describe('ControlServer', function () {
|
||||||
await controlServer.torPool.exit();
|
await controlServer.torPool.exit();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
require('./RPCServer');
|
|
|
@ -3,15 +3,18 @@ const nconf = require('nconf');
|
||||||
const getPort = require('get-port');
|
const getPort = require('get-port');
|
||||||
const dns = require('native-dns');
|
const dns = require('native-dns');
|
||||||
|
|
||||||
const logger = require('../src/winston-silent-logger');
|
|
||||||
const { TorPool, DNSServer } = require('../');
|
const { TorPool, DNSServer } = require('../');
|
||||||
const { WAIT_FOR_CREATE } = require('./constants');
|
const { WAIT_FOR_CREATE } = require('./constants');
|
||||||
|
|
||||||
|
nconf.use('memory');
|
||||||
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
||||||
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
|
|
||||||
let dnsServerTorPool;
|
let dnsServerTorPool;
|
||||||
let dnsServer;
|
let dnsServer;
|
||||||
describe('DNSServer', function () {
|
describe('DNSServer', function () {
|
||||||
dnsServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null, logger);
|
dnsServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null);
|
||||||
dnsServer = new DNSServer(dnsServerTorPool, {}, 10000, logger);
|
dnsServer = new DNSServer(dnsServerTorPool, {}, 10000);
|
||||||
let dnsPort;
|
let dnsPort;
|
||||||
before('start up server', async function (){
|
before('start up server', async function (){
|
||||||
this.timeout(WAIT_FOR_CREATE);
|
this.timeout(WAIT_FOR_CREATE);
|
||||||
|
@ -19,7 +22,7 @@ describe('DNSServer', function () {
|
||||||
await dnsServerTorPool.create(1);
|
await dnsServerTorPool.create(1);
|
||||||
dnsPort = await getPort();
|
dnsPort = await getPort();
|
||||||
|
|
||||||
dnsServer.serve(dnsPort);
|
await dnsServer.listen(dnsPort);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#handle_dns_request(req, res)', function () {
|
describe('#handle_dns_request(req, res)', function () {
|
||||||
|
@ -32,7 +35,7 @@ describe('DNSServer', function () {
|
||||||
type: 'A'
|
type: 'A'
|
||||||
}),
|
}),
|
||||||
server: { address: '127.0.0.1', port: dnsPort, type: 'udp' },
|
server: { address: '127.0.0.1', port: dnsPort, type: 'udp' },
|
||||||
timeout: 1000,
|
timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on('timeout', function () {
|
req.on('timeout', function () {
|
||||||
|
|
|
@ -3,18 +3,18 @@ const request = require('request-promise');
|
||||||
const getPort = require('get-port');
|
const getPort = require('get-port');
|
||||||
const ProxyAgent = require('proxy-agent');
|
const ProxyAgent = require('proxy-agent');
|
||||||
|
|
||||||
const logger = require('../src/winston-silent-logger');
|
|
||||||
const { TorPool, HTTPServer } = require('../');
|
const { TorPool, HTTPServer } = require('../');
|
||||||
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME } = require('./constants');
|
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME } = require('./constants');
|
||||||
|
|
||||||
|
nconf.use('memory');
|
||||||
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
||||||
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
|
|
||||||
let httpServerTorPool;
|
let httpServerTorPool;
|
||||||
let httpServer;
|
let httpServer;
|
||||||
describe('HTTPServer', function () {
|
describe('HTTPServer', function () {
|
||||||
httpServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null, logger);
|
httpServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null);
|
||||||
httpServer = new HTTPServer(httpServerTorPool, logger);
|
httpServer = new HTTPServer(httpServerTorPool);
|
||||||
let httpPort;
|
let httpPort;
|
||||||
before('start up server', async function (){
|
before('start up server', async function (){
|
||||||
this.timeout(WAIT_FOR_CREATE);
|
this.timeout(WAIT_FOR_CREATE);
|
||||||
|
@ -22,7 +22,7 @@ describe('HTTPServer', function () {
|
||||||
await httpServerTorPool.create(1);
|
await httpServerTorPool.create(1);
|
||||||
httpPort = await getPort();
|
httpPort = await getPort();
|
||||||
|
|
||||||
httpServer.listen(httpPort);
|
await httpServer.listen(httpPort);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#handle_http_connections(req, res)', function () {
|
describe('#handle_http_connections(req, res)', function () {
|
||||||
|
@ -31,7 +31,7 @@ describe('HTTPServer', function () {
|
||||||
|
|
||||||
await request({
|
await request({
|
||||||
url: 'http://example.com',
|
url: 'http://example.com',
|
||||||
agent: new ProxyAgent(`http://localhost:${httpPort}`)
|
agent: new ProxyAgent(`http://127.0.0.1:${httpPort}`)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -42,7 +42,7 @@ describe('HTTPServer', function () {
|
||||||
|
|
||||||
await request({
|
await request({
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
agent: new ProxyAgent(`http://localhost:${httpPort}`)
|
agent: new ProxyAgent(`http://127.0.0.1:${httpPort}`)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const assert = require('chai').assert;
|
const assert = require('chai').assert;
|
||||||
const rpc = require('jrpc2');
|
|
||||||
const Promise = require('bluebird');
|
const Promise = require('bluebird');
|
||||||
const nconf = require('nconf');
|
const nconf = require('nconf');
|
||||||
const rpc = require('jrpc2');
|
const rpc = require('jrpc2');
|
||||||
|
const getPort = require('get-port');
|
||||||
|
|
||||||
const logger = require('../src/winston-silent-logger');
|
nconf.use('memory');
|
||||||
|
|
||||||
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
||||||
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
const { ControlServer } = require('../');
|
const { ControlServer } = require('../');
|
||||||
|
const { WAIT_FOR_CREATE } = require('./constants');
|
||||||
|
|
||||||
let rpcControlServer = new ControlServer(logger, nconf);
|
let rpcControlServer = new ControlServer(null, nconf);
|
||||||
let rpcControlPort;
|
let rpcControlPort;
|
||||||
let rpcClient;
|
let rpcClient;
|
||||||
describe('ControlServer - RPC', function () {
|
describe('ControlServer - RPC Interface', function () {
|
||||||
before('setup control server', async function () {
|
before('setup control server', async function () {
|
||||||
rpcControlPort = await getPort();
|
rpcControlPort = await getPort();
|
||||||
await rpcControlServer.listen(rpcControlPort);
|
await rpcControlServer.listen(rpcControlPort);
|
||||||
|
@ -35,11 +35,11 @@ describe('ControlServer - RPC', function () {
|
||||||
it('should return a list of instances', async function () {
|
it('should return a list of instances', async function () {
|
||||||
let raw = await rpcClient.invokeAsync('queryInstances', []);
|
let raw = await rpcClient.invokeAsync('queryInstances', []);
|
||||||
|
|
||||||
var instances = JSON.parse(raw).result;
|
let instances = JSON.parse(raw).result;
|
||||||
|
|
||||||
assert.isArray(instances, 'Did not return an array');
|
assert.isArray(instances, 'Did not return an array');
|
||||||
assert.isNotEmpty(instances);
|
assert.isNotEmpty(instances, 'Returned an empty array');
|
||||||
assert.isTrue(instances.every((instance) => ( typeof(instance.name) !== 'undefined' ) && ( instance.name !== null )));
|
assert.isTrue(instances.every((instance) => ( typeof(instance.name) !== 'undefined' ) && ( instance.name !== null )), 'Objects were not valid');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ describe('ControlServer - RPC', function () {
|
||||||
it('should return a single instance by name', async function () {
|
it('should return a single instance by name', async function () {
|
||||||
let raw = await rpcClient.invokeAsync('queryInstanceByName', ['instance-1']);
|
let raw = await rpcClient.invokeAsync('queryInstanceByName', ['instance-1']);
|
||||||
|
|
||||||
var instance = JSON.parse(raw).result;
|
let instance = JSON.parse(raw).result;
|
||||||
|
|
||||||
assert.isOk(instance);
|
assert.isOk(instance);
|
||||||
});
|
});
|
||||||
|
@ -73,7 +73,7 @@ describe('ControlServer - RPC', function () {
|
||||||
it('should return a single instance by index', async function () {
|
it('should return a single instance by index', async function () {
|
||||||
let raw = await rpcClient.invokeAsync('queryInstanceAt', [0]);
|
let raw = await rpcClient.invokeAsync('queryInstanceAt', [0]);
|
||||||
|
|
||||||
var instance = JSON.parse(raw).result;
|
let instance = JSON.parse(raw).result;
|
||||||
|
|
||||||
assert.isOk(instance);
|
assert.isOk(instance);
|
||||||
});
|
});
|
||||||
|
@ -132,9 +132,10 @@ describe('ControlServer - RPC', function () {
|
||||||
this.timeout(WAIT_FOR_CREATE);
|
this.timeout(WAIT_FOR_CREATE);
|
||||||
|
|
||||||
await rpcControlServer.torPool.create_instance({ Name: 'config-test' });
|
await rpcControlServer.torPool.create_instance({ Name: 'config-test' });
|
||||||
let value = await rpcControlServer.torPool.instance_by_name('config-test').get_config('TestSocks');
|
let values = await rpcControlServer.torPool.instance_by_name('config-test').get_config('TestSocks');
|
||||||
|
|
||||||
assert.equal(value, 1);
|
assert.isNotEmpty(values);
|
||||||
|
assert.equal(values[0], "1");
|
||||||
});
|
});
|
||||||
|
|
||||||
after('remove instance', async function () {
|
after('remove instance', async function () {
|
||||||
|
@ -150,8 +151,8 @@ describe('ControlServer - RPC', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a tor config with a modified property', async function () {
|
it('should return a tor config with a modified property', async function () {
|
||||||
this.timeout(3000);
|
this.timeout(6000);
|
||||||
let raw = await rpcClient.invokeAsync('getDefaultTorConfig', [ { } ]);
|
let raw = await rpcClient.invokeAsync('getDefaultTorConfig', [ ]);
|
||||||
let config = JSON.parse(raw).result;
|
let config = JSON.parse(raw).result;
|
||||||
|
|
||||||
assert.equal(config.TestSocks, 1);
|
assert.equal(config.TestSocks, 1);
|
||||||
|
@ -198,11 +199,12 @@ describe('ControlServer - RPC', function () {
|
||||||
await rpcControlServer.torPool.instance_by_name('instance-1').set_config('TestSocks', 1);
|
await rpcControlServer.torPool.instance_by_name('instance-1').set_config('TestSocks', 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retrieve the property from the tor instance', async function (done) {
|
it('should retrieve the property from the tor instance', async function () {
|
||||||
let raw = await rpcClient.invokeAsync('getInstanceConfigByName', ['instance-1']);
|
let raw = await rpcClient.invokeAsync('getInstanceConfigByName', ['instance-1', "TestSocks"]);
|
||||||
let value = JSON.parse(raw).result;
|
let values = JSON.parse(raw).result;
|
||||||
|
|
||||||
assert.equal(value, 1);
|
assert.isNotEmpty(values);
|
||||||
|
assert.equal(values[0], "1");
|
||||||
});
|
});
|
||||||
|
|
||||||
after('unset config property', async function () {
|
after('unset config property', async function () {
|
||||||
|
@ -218,10 +220,11 @@ describe('ControlServer - RPC', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retrieve the property from the tor instance', async function () {
|
it('should retrieve the property from the tor instance', async function () {
|
||||||
let raw = await rpcClient.invokeAsync('getInstanceConfigByName', [0]);
|
let raw = await rpcClient.invokeAsync('getInstanceConfigAt', [0, "TestSocks"]);
|
||||||
let value = JSON.parse(raw).result;
|
let values = JSON.parse(raw).result;
|
||||||
|
|
||||||
assert.equal(value, 1);
|
assert.isNotEmpty(values);
|
||||||
|
assert.equal(values[0], "1");
|
||||||
});
|
});
|
||||||
|
|
||||||
after('unset config property', async function () {
|
after('unset config property', async function () {
|
|
@ -3,18 +3,18 @@ const request = require('request-promise');
|
||||||
const getPort = require('get-port');
|
const getPort = require('get-port');
|
||||||
const ProxyAgent = require('proxy-agent');
|
const ProxyAgent = require('proxy-agent');
|
||||||
|
|
||||||
const logger = require('../src/winston-silent-logger');
|
|
||||||
const { TorPool, SOCKSServer } = require('../');
|
const { TorPool, SOCKSServer } = require('../');
|
||||||
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME } = require('./constants');
|
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME } = require('./constants');
|
||||||
|
|
||||||
|
nconf.use('memory');
|
||||||
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
||||||
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
|
|
||||||
let socksServerTorPool;
|
let socksServerTorPool;
|
||||||
let socksServer;
|
let socksServer;
|
||||||
describe('SOCKSServer', function () {
|
describe('SOCKSServer', function () {
|
||||||
socksServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null, logger);
|
socksServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null);
|
||||||
socksServer = new SOCKSServer(socksServerTorPool, logger);
|
socksServer = new SOCKSServer(socksServerTorPool);
|
||||||
let socksPort;
|
let socksPort;
|
||||||
before('start up server', async function (){
|
before('start up server', async function (){
|
||||||
this.timeout(WAIT_FOR_CREATE);
|
this.timeout(WAIT_FOR_CREATE);
|
||||||
|
@ -22,7 +22,7 @@ describe('SOCKSServer', function () {
|
||||||
await socksServerTorPool.create(1);
|
await socksServerTorPool.create(1);
|
||||||
socksPort = await getPort();
|
socksPort = await getPort();
|
||||||
|
|
||||||
socksServer.listen(socksPort);
|
await socksServer.listen(socksPort);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#handleConnection(socket)', function () {
|
describe('#handleConnection(socket)', function () {
|
||||||
|
@ -31,7 +31,7 @@ describe('SOCKSServer', function () {
|
||||||
|
|
||||||
await request({
|
await request({
|
||||||
url: 'http://example.com',
|
url: 'http://example.com',
|
||||||
agent: new ProxyAgent(`socks://localhost:${socksPort}`)
|
agent: new ProxyAgent(`socks://127.0.0.1:${socksPort}`)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,14 +5,13 @@ const _ = require('lodash');
|
||||||
|
|
||||||
const { TorPool } = require('../');
|
const { TorPool } = require('../');
|
||||||
const { WAIT_FOR_CREATE } = require('./constants');
|
const { WAIT_FOR_CREATE } = require('./constants');
|
||||||
const logger = require('../src/winston-silent-logger');
|
|
||||||
|
|
||||||
|
nconf.use('memory');
|
||||||
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
||||||
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
|
|
||||||
let torPool;
|
|
||||||
describe('TorPool', function () {
|
describe('TorPool', function () {
|
||||||
torPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null, logger);
|
const torPoolFactory = () => new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null);
|
||||||
|
|
||||||
describe('#create_instance(instance_defintion)', function () {
|
describe('#create_instance(instance_defintion)', function () {
|
||||||
let instance_defintion = {
|
let instance_defintion = {
|
||||||
|
@ -22,6 +21,9 @@ describe('TorPool', function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let torPool;
|
||||||
|
before('create tor pool', () => { torPool = torPoolFactory(); })
|
||||||
|
|
||||||
it('should create one tor instance based on the provided definition', async function () {
|
it('should create one tor instance based on the provided definition', async function () {
|
||||||
this.timeout(WAIT_FOR_CREATE);
|
this.timeout(WAIT_FOR_CREATE);
|
||||||
await torPool.create_instance(instance_defintion);
|
await torPool.create_instance(instance_defintion);
|
||||||
|
@ -51,9 +53,12 @@ describe('TorPool', function () {
|
||||||
{ Name: 'instance-2', Config: { ProtocolWarnings: 1 } }
|
{ Name: 'instance-2', Config: { ProtocolWarnings: 1 } }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let torPool;
|
||||||
|
before('create tor pool', () => { torPool = torPoolFactory(); })
|
||||||
|
|
||||||
it('should create instances from several instance definitions', async function () {
|
it('should create instances from several instance definitions', async function () {
|
||||||
this.timeout(WAIT_FOR_CREATE*2);
|
this.timeout(WAIT_FOR_CREATE*2);
|
||||||
await torPool.add(instance_defintions)
|
await torPool.add(_.cloneDeep(instance_defintions))
|
||||||
});
|
});
|
||||||
|
|
||||||
it('2 instances should exist in the pool', function () {
|
it('2 instances should exist in the pool', function () {
|
||||||
|
@ -61,19 +66,21 @@ describe('TorPool', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('the created instances should have the same defintion properties as the input definitions', function () {
|
it('the created instances should have the same defintion properties as the input definitions', function () {
|
||||||
assert.deepEqual(instance_defintions, torPool.instances.map((instance) => {
|
let live_instance_definitions = torPool.instances.map((instance) => {
|
||||||
let def_clone = _.cloneDeep(instance.definition);
|
let def_clone = _.cloneDeep(instance.definition);
|
||||||
delete def_clone.Config.DataDirectory;
|
delete def_clone.Config.DataDirectory;
|
||||||
return def_clone;
|
return def_clone;
|
||||||
}).sort(function(a,b) {return (a.Name > b.Name) ? 1 : ((b.Name > a.Name) ? -1 : 0);}));
|
}).sort((a,b) => (a.Name > b.Name) ? 1 : ((b.Name > a.Name) ? -1 : 0));
|
||||||
|
|
||||||
|
assert.deepEqual(instance_defintions, live_instance_definitions);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('the created instances should have the same config properties specified in the definiton', async function (done) {
|
it('the created instances should have the same config properties specified in the definiton', async function () {
|
||||||
this.timeout(10000);
|
this.timeout(10000);
|
||||||
|
|
||||||
let values = await Promise.all(torPool.instances.map((instance) => instance.get_config('ProtocolWarnings')));
|
let values = await Promise.all(torPool.instances.map((instance) => instance.get_config('ProtocolWarnings')));
|
||||||
|
values = _.flatten(values);
|
||||||
assert.isTrue( values.every((value) => value === 1) );
|
assert.isTrue( values.every((value) => value === "1") );
|
||||||
});
|
});
|
||||||
|
|
||||||
after('shutdown tor pool', async function () {
|
after('shutdown tor pool', async function () {
|
||||||
|
@ -82,7 +89,13 @@ describe('TorPool', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#create(number_of_instances)', function () {
|
describe('#create(number_of_instances)', function () {
|
||||||
|
let torPool;
|
||||||
|
|
||||||
|
before('create tor pool', () => {
|
||||||
|
torPool = torPoolFactory();
|
||||||
torPool.default_tor_config = { TestSocks: 1 };
|
torPool.default_tor_config = { TestSocks: 1 };
|
||||||
|
})
|
||||||
|
|
||||||
it('should create 2 instances with the default config', async function () {
|
it('should create 2 instances with the default config', async function () {
|
||||||
this.timeout(WAIT_FOR_CREATE*2);
|
this.timeout(WAIT_FOR_CREATE*2);
|
||||||
await torPool.create(2);
|
await torPool.create(2);
|
||||||
|
@ -95,19 +108,21 @@ describe('TorPool', function () {
|
||||||
it('the created instances should have the same config properties specified in the default config', async function () {
|
it('the created instances should have the same config properties specified in the default config', async function () {
|
||||||
this.timeout(10000);
|
this.timeout(10000);
|
||||||
|
|
||||||
let values = await Promise.all(torPool.instances.map((instance) => instance.get_config('ProtocolWarnings')));
|
let values = await Promise.all(torPool.instances.map((instance) => instance.get_config('TestSocks')));
|
||||||
|
values = _.flatten(values);
|
||||||
assert.isTrue( values.every((value) => value === 1) );
|
assert.isTrue( values.every((value) => value === "1") );
|
||||||
});
|
});
|
||||||
|
|
||||||
after('shutdown tor pool', async function () {
|
after('shutdown tor pool', async function () {
|
||||||
torPool.default_tor_config = {};
|
torPool.default_tor_config = {};
|
||||||
await torPool.exit(done);
|
await torPool.exit();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let torPool;
|
||||||
describe('#next()', function () {
|
describe('#next()', function () {
|
||||||
|
before('create tor pool', () => { torPool = torPoolFactory(); })
|
||||||
|
|
||||||
before('create tor instances', async function () {
|
before('create tor instances', async function () {
|
||||||
this.timeout(WAIT_FOR_CREATE * 3);
|
this.timeout(WAIT_FOR_CREATE * 3);
|
||||||
await torPool.add([
|
await torPool.add([
|
||||||
|
@ -127,8 +142,8 @@ describe('TorPool', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('result of next should be different if run twice', function () {
|
it('result of next should be different if run twice', function () {
|
||||||
var t1 = torPool.next().instance_name;
|
let t1 = torPool.next().instance_name;
|
||||||
var t2 = torPool.next().instance_name;
|
let t2 = torPool.next().instance_name;
|
||||||
assert.notEqual(t1, t2);
|
assert.notEqual(t1, t2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -192,8 +207,8 @@ describe('TorPool', function () {
|
||||||
this.timeout(5000);
|
this.timeout(5000);
|
||||||
|
|
||||||
let values = await Promise.all(torPool.instances.map((instance) => instance.get_config('TestSocks')));
|
let values = await Promise.all(torPool.instances.map((instance) => instance.get_config('TestSocks')));
|
||||||
|
values = _.flatten(values);
|
||||||
assert.isTrue( values.every((value) => value === 1) );
|
assert.isTrue( values.every((value) => value === "1") );
|
||||||
});
|
});
|
||||||
|
|
||||||
after('unset config options', async function () {
|
after('unset config options', async function () {
|
||||||
|
|
|
@ -3,13 +3,13 @@ const assert = require('chai').assert;
|
||||||
|
|
||||||
const { TorProcess } = require('../');
|
const { TorProcess } = require('../');
|
||||||
const { WAIT_FOR_CREATE } = require('./constants');
|
const { WAIT_FOR_CREATE } = require('./constants');
|
||||||
const logger = require('../src/winston-silent-logger');
|
|
||||||
|
|
||||||
|
nconf.use('memory');
|
||||||
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
||||||
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
||||||
|
|
||||||
describe('TorProcess', function () {
|
describe('TorProcess', function () {
|
||||||
let tor = new TorProcess(nconf.get('torPath'), { DataDirectory: nconf.get('parentDataDirectory'), ProtocolWarnings: 0 }, null, logger);
|
let tor = new TorProcess(nconf.get('torPath'), { DataDirectory: nconf.get('parentDataDirectory'), ProtocolWarnings: 0 }, null);
|
||||||
describe('#create()', function () {
|
describe('#create()', function () {
|
||||||
this.timeout(WAIT_FOR_CREATE);
|
this.timeout(WAIT_FOR_CREATE);
|
||||||
|
|
||||||
|
|
|
@ -5,4 +5,5 @@ describe("TorRouter", function () {
|
||||||
require('./HTTPServer');
|
require('./HTTPServer');
|
||||||
require('./DNSServer');
|
require('./DNSServer');
|
||||||
require('./ControlServer');
|
require('./ControlServer');
|
||||||
|
require('./RPCInterface');
|
||||||
});
|
});
|
Loading…
Reference in a new issue