tor-router/test/RPCInterface.js

352 lines
12 KiB
JavaScript

const _ = require('lodash');
const assert = require('chai').assert;
const Promise = require('bluebird');
const nconf = require('nconf');
const rpc = require('jrpc2');
const getPort = require('get-port');
nconf.use('memory');
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
const { ControlServer } = require('../');
const { WAIT_FOR_CREATE } = require('./constants');
let rpcControlServer = new ControlServer(null, nconf);
let rpcControlPort;
let rpcClient;
describe('ControlServer - RPC Interface', function () {
before('setup control server', async function () {
rpcControlPort = await getPort();
await rpcControlServer.listen(rpcControlPort);
rpcClient = new rpc.Client(new rpc.tcpTransport({ port: rpcControlPort, hostname: 'localhost' }));
Promise.promisifyAll(rpcClient);
});
describe('#createInstances(number_of_instances)', function () {
this.timeout(WAIT_FOR_CREATE*2);
it('should create an instance', async function () {
await rpcClient.invokeAsync('createInstances', [2]);
});
});
describe('#queryInstances()', function () {
this.timeout(3000);
it('should return a list of instances', async function () {
let raw = await rpcClient.invokeAsync('queryInstances', []);
let instances = JSON.parse(raw).result;
assert.isArray(instances, 'Did not return an array');
assert.isNotEmpty(instances, 'Returned an empty array');
assert.isTrue(instances.every((instance) => ( typeof(instance.name) !== 'undefined' ) && ( instance.name !== null )), 'Objects were not valid');
});
});
describe('#addInstances(definitions)', function () {
this.timeout(WAIT_FOR_CREATE);
it("should add an instance based on a defintion", async function () {
var def = {
Name: 'instance-1'
};
await rpcClient.invokeAsync('addInstances', [ [ def ] ]);
});
it("tor pool should now contain and instance that has the same name as the name specified in the defintion", function () {
assert.ok(rpcControlServer.torPool.instance_by_name('instance-1'));
});
});
describe('#queryInstanceByName(instance_name)', function () {
this.timeout(3000);
it('should return a single instance by name', async function () {
let raw = await rpcClient.invokeAsync('queryInstanceByName', ['instance-1']);
let instance = JSON.parse(raw).result;
assert.isOk(instance);
});
});
describe('#queryInstanceAt(index)', function () {
this.timeout(3000);
it('should return a single instance by index', async function () {
let raw = await rpcClient.invokeAsync('queryInstanceAt', [0]);
let instance = JSON.parse(raw).result;
assert.isOk(instance);
});
});
describe('#newIdentites()', function () {
this.timeout(3000);
it('should request new identities for all instances', async function () {
await rpcClient.invokeAsync('newIdentites', []);
});
});
describe('#newIdentityByName(instance_name)', function () {
this.timeout(3000);
it('should request new identities for all instances', async function () {
await rpcClient.invokeAsync('newIdentityByName', ['instance-1']);
});
});
describe('#newIdentityAt(index)', function () {
this.timeout(3000);
it('should request new identities for all instances', async function () {
await rpcClient.invokeAsync('newIdentityAt', [0]);
});
});
describe("#setTorConfig(config_object)", function () {
this.timeout(3000);
it('should set several config variables on all instances', async function () {
await rpcClient.invokeAsync('setTorConfig', [ { TestSocks: 1, ProtocolWarnings: 1 } ]);
});
it('all instances should have the modified variables', async function() {
await Promise.all(rpcControlServer.torPool.instances.map(async (instance) => {
let var1 = await instance.get_config('TestSocks');
let var2 = await instance.get_config('ProtocolWarnings');
assert.equal(var1, 1);
assert.equal(var2, 1);
}));
});
after('unset config variables', async function () {
await rpcControlServer.torPool.set_config_all('TestSocks', 0);
await rpcControlServer.torPool.set_config_all('ProtocolWarnings', 0);
});
});
describe('#setDefaultTorConfig(object)', function () {
it('should set the default config of new instances', async function () {
this.timeout(3000);
await rpcClient.invokeAsync('setDefaultTorConfig', [ { TestSocks: 1 } ]);
});
it('a new instance should be created with the modified property', async function () {
this.timeout(WAIT_FOR_CREATE);
await rpcControlServer.torPool.create_instance({ Name: 'config-test' });
let values = await rpcControlServer.torPool.instance_by_name('config-test').get_config('TestSocks');
assert.isNotEmpty(values);
assert.equal(values[0], "1");
});
after('remove instance', async function () {
this.timeout(10000);
nconf.set('torConfig', {});
await rpcControlServer.torPool.remove_by_name('config-test');
});
});
describe('#getDefaultTorConfig()', function () {
before('set tor config', function () {
nconf.set('torConfig', { TestSocks: 1 });
});
it('should return a tor config with a modified property', async function () {
this.timeout(6000);
let raw = await rpcClient.invokeAsync('getDefaultTorConfig', [ ]);
let config = JSON.parse(raw).result;
assert.equal(config.TestSocks, 1);
});
after('unset property', function () {
nconf.set('torConfig', {});
});
});
describe('#getLoadBalanceMethod()', function () {
this.timeout(3000);
before(function () {
rpcControlServer.torPool.load_balance_method = 'round_robin';
});
it('should return the current load balance method', async function () {
let raw = await rpcClient.invokeAsync('getLoadBalanceMethod', []);
let lb_method = JSON.parse(raw).result;
assert.equal(lb_method, 'round_robin');
});
});
describe('#setLoadBalanceMethod(load_balance_method)', function () {
this.timeout(3000);
it('should set the load balance method', async function () {
await rpcClient.invokeAsync('setLoadBalanceMethod', ['weighted']);
});
it('the load balance method should be changed', function () {
assert.equal(rpcControlServer.torPool.load_balance_method, 'weighted');
});
after(function () {
rpcControlServer.torPool.load_balance_method = 'round_robin';
});
});
describe("#getInstanceConfigByName(instance_name)", function () {
this.timeout(3000);
before('set config property', async function () {
await rpcControlServer.torPool.instance_by_name('instance-1').set_config('TestSocks', 1);
});
it('should retrieve the property from the tor instance', async function () {
let raw = await rpcClient.invokeAsync('getInstanceConfigByName', ['instance-1', "TestSocks"]);
let values = JSON.parse(raw).result;
assert.isNotEmpty(values);
assert.equal(values[0], "1");
});
after('unset config property', async function () {
await rpcControlServer.torPool.instance_by_name('instance-1').set_config('TestSocks', 0);
});
});
describe("#getInstanceConfigAt(index)", function () {
this.timeout(3000);
before('set config property', async function () {
await rpcControlServer.torPool.instance_at(0).set_config('TestSocks', 1);
});
it('should retrieve the property from the tor instance', async function () {
let raw = await rpcClient.invokeAsync('getInstanceConfigAt', [0, "TestSocks"]);
let values = JSON.parse(raw).result;
assert.isNotEmpty(values);
assert.equal(values[0], "1");
});
after('unset config property', async function () {
await rpcControlServer.torPool.instance_at(0).set_config('TestSocks', 0);
});
});
describe("#setInstanceConfigByName(instance_name)", function () {
this.timeout(3000);
before('set config property', async function () {
await rpcControlServer.torPool.instance_by_name('instance-1').set_config('TestSocks', 0);
});
it('should set the property for the tor instance', async function () {
await rpcClient.invokeAsync('setInstanceConfigByName', ['instance-1', 'TestSocks', 1]);
});
it('tor instance should have the modified property', async function () {
let value = await rpcControlServer.torPool.instance_by_name('instance-1').get_config('TestSocks');
assert.equal(value, 1);
});
after('unset config property', async function () {
await rpcControlServer.torPool.instance_by_name('instance-1').set_config('TestSocks', 0);
});
});
describe("#setInstanceConfigAt(index)", function () {
this.timeout(3000);
before('set config property', async function () {
await rpcControlServer.torPool.instance_at(0).set_config('TestSocks', 0);
});
it('should set the property for the tor instance', async function () {
await rpcClient.invokeAsync('setInstanceConfigAt', [0, 'TestSocks', 1]);
});
it('tor instance should have the modified property', async function () {
let value = await rpcControlServer.torPool.instance_at(0).get_config('TestSocks');
assert.equal(value, 1);
});
after('unset config property', async function () {
await rpcControlServer.torPool.instance_at(0).set_config('TestSocks', 0);
});
});
describe('#signalAllInstances(signal)', function () {
this.timeout(3000);
it('should signal to all interfaces', async function () {
await rpcClient.invokeAsync('signalAllInstances', [ 'DEBUG' ]);
});
});
describe('#signalInstanceAt(signal)', function () {
this.timeout(3000);
it('should signal to all interfaces', async function () {
await rpcClient.invokeAsync('signalInstanceAt', [ 0, 'DEBUG' ]);
});
});
describe('#signalAllInstances(signal)', function () {
this.timeout(3000);
it('should signal to all interfaces', async function () {
await rpcClient.invokeAsync('signalInstanceByName', [ 'instance-1', 'DEBUG' ]);
});
});
describe("#nextInstance()", function () {
this.timeout(3000);
let instance_name;
it('should rotate the 0th item in the instances array', async function () {
instance_name = rpcControlServer.torPool.instances[0].instance_name;
await rpcClient.invokeAsync('nextInstance', []);
});
it('0th item in the instances array should be different after nextInstance is called', function () {
assert.notEqual(rpcControlServer.torPool.instances[0].instance_name, instance_name);
});
});
var instance_num1, instance_num2, i_num;
describe('#removeInstanceAt(index)', function () {
this.timeout(10000);
it("should remove an instance at the position specified", async function () {
instance_num1 = rpcControlServer.torPool.instances.length;
await rpcClient.invokeAsync('removeInstanceAt', [0]);
});
it('the tor pool should contain one instance fewer', function () {
assert.equal(rpcControlServer.torPool.instances.length, (instance_num1 - 1));
});
});
describe('#removeInstanceByName(instance_name)', function () {
this.timeout(10000);
it("should remove an instance at the position specified", async function () {
instance_num2 = rpcControlServer.torPool.instances.length;
await rpcClient.invokeAsync('removeInstanceByName', [ "instance-1" ]);
});
it('the tor pool should contain one instance fewer', function () {
assert.equal(rpcControlServer.torPool.instances.length, (instance_num2 - 1));
});
});
describe('#closeInstances()', function () {
this.timeout(10000);
it('should shutdown all instances', async function () {
instance_num = rpcControlServer.torPool.instances.length;
await rpcClient.invokeAsync('closeInstances', [ ]);
});
it('no instances should be present in the pool', function () {
assert.equal(rpcControlServer.torPool.instances.length, 0);
assert.notEqual(rpcControlServer.torPool.instances.length, instance_num);
});
});
after('shutdown tor pool', async function () {
this.timeout(10000);
await rpcControlServer.torPool.exit();
});
});