test: unit tests for connect and spawn processes

This commit is contained in:
Braydon Fuller 2016-04-18 13:08:57 -04:00
parent e09cc3d1fc
commit 7c37eba91e
2 changed files with 240 additions and 7 deletions

View File

@ -52,6 +52,7 @@ function Bitcoin(options) {
// try all interval
this.tryAllInterval = options.tryAllInterval || Bitcoin.DEFAULT_TRY_ALL_INTERVAL;
this.startRetryInterval = options.startRetryInterval || Bitcoin.DEFAULT_START_RETRY_INTERVAL;
// available bitcoind nodes
this._initClients();
@ -62,6 +63,7 @@ Bitcoin.dependencies = [];
Bitcoin.DEFAULT_MAX_ADDRESSES_QUERY = 10000;
Bitcoin.DEFAULT_TRY_ALL_INTERVAL = 1000;
Bitcoin.DEFAULT_START_RETRY_INTERVAL = 5000;
Bitcoin.DEFAULT_CONFIG_SETTINGS = {
server: 1,
whitelist: '127.0.0.1',
@ -528,7 +530,7 @@ Bitcoin.prototype._spawnChildProcess = function(callback) {
}
var options = [
'--conf=' + path.resolve(this.spawn.configPath),
'--conf=' + this.spawn.configPath,
'--datadir=' + this.spawn.datadir,
];
@ -541,7 +543,7 @@ Bitcoin.prototype._spawnChildProcess = function(callback) {
log.error(err);
});
async.retry({times: 60, interval: 5000}, function(done) {
async.retry({times: 60, interval: self.startRetryInterval}, function(done) {
if (self.node.stopping) {
return done(new Error('Stopping while trying to connect to bitcoind.'));
}
@ -563,7 +565,7 @@ Bitcoin.prototype._spawnChildProcess = function(callback) {
self._initZmqSubSocket(node, self.spawn.config.zmqpubrawtx);
self._checkReindex(node, function() {
self._checkReindex(node, function(err) {
if (err) {
return callback(err);
}
@ -578,7 +580,7 @@ Bitcoin.prototype._connectProcess = function(config, callback) {
var self = this;
var node = {};
async.retry({times: 60, interval: 5000}, function(done) {
async.retry({times: 60, interval: self.startRetryInterval}, function(done) {
if (self.node.stopping) {
return done(new Error('Stopping while trying to connect to bitcoind.'));
}

View File

@ -264,12 +264,12 @@ describe('Bitcoin Service', function() {
});
describe('#_checkConfigIndexes', function() {
var stub;
var sandbox = sinon.sandbox.create();
beforeEach(function() {
stub = sinon.stub(log, 'warn');
sandbox.stub(log, 'warn');
});
after(function() {
stub.restore();
sandbox.restore();
});
it('should warn the user if reindex is set to 1 in the bitcoin.conf file', function() {
var bitcoind = new BitcoinService(baseConfig);
@ -764,12 +764,243 @@ describe('Bitcoin Service', function() {
});
describe('#_loadTipFromNode', function() {
var sandbox = sinon.sandbox.create();
beforeEach(function() {
sandbox.stub(log, 'warn');
});
afterEach(function() {
sandbox.restore();
});
it('will give rpc from client getbestblockhash', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var getBestBlockHash = sinon.stub().callsArgWith(0, {code: -1, message: 'Test error'});
var node = {
client: {
getBestBlockHash: getBestBlockHash
}
};
bitcoind._loadTipFromNode(node, function(err) {
err.should.be.instanceof(Error);
log.warn.callCount.should.equal(0);
done();
});
});
it('will give rpc from client getblock', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var getBestBlockHash = sinon.stub().callsArgWith(0, null, {
result: '00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45'
});
var getBlock = sinon.stub().callsArgWith(1, new Error('Test error'));
var node = {
client: {
getBestBlockHash: getBestBlockHash,
getBlock: getBlock
}
};
bitcoind._loadTipFromNode(node, function(err) {
getBlock.args[0][0].should.equal('00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45');
err.should.be.instanceof(Error);
log.warn.callCount.should.equal(0);
done();
});
});
it('will log when error is RPC_IN_WARMUP', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var getBestBlockHash = sinon.stub().callsArgWith(0, {code: -28, message: 'Verifying blocks...'});
var node = {
client: {
getBestBlockHash: getBestBlockHash
}
};
bitcoind._loadTipFromNode(node, function(err) {
err.should.be.instanceof(Error);
log.warn.callCount.should.equal(1);
done();
});
});
it('will set height and emit tip', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var getBestBlockHash = sinon.stub().callsArgWith(0, null, {
result: '00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45'
});
var getBlock = sinon.stub().callsArgWith(1, null, {
result: {
height: 100
}
});
var node = {
client: {
getBestBlockHash: getBestBlockHash,
getBlock: getBlock
}
};
bitcoind.on('tip', function(height) {
height.should.equal(100);
bitcoind.height.should.equal(100);
done();
});
bitcoind._loadTipFromNode(node, function(err) {
if (err) {
return done(err);
}
});
});
});
describe('#_spawnChildProcess', function() {
it('will give error from spawn config', function(done) {
var bitcoind = new BitcoinService(baseConfig);
bitcoind._loadSpawnConfiguration = sinon.stub().throws(new Error('test'));
bitcoind._spawnChildProcess(function(err) {
err.should.be.instanceof(Error);
err.message.should.equal('test');
done();
});
});
it('will include network with spawn command and init zmq/rpc on node', function(done) {
var process = new EventEmitter();
var spawn = sinon.stub().returns(process);
var TestBitcoinService = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
child_process: {
spawn: spawn
}
});
var bitcoind = new TestBitcoinService(baseConfig);
bitcoind._loadSpawnConfiguration = sinon.stub();
bitcoind.spawn = {};
bitcoind.spawn.exec = 'testexec';
bitcoind.spawn.configPath = 'testdir/bitcoin.conf';
bitcoind.spawn.datadir = 'testdir';
bitcoind.spawn.config = {};
bitcoind.spawn.config.rpcport = 20001;
bitcoind.spawn.config.rpcuser = 'bitcoin';
bitcoind.spawn.config.rpcpassword = 'password';
bitcoind.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001';
bitcoind._loadTipFromNode = sinon.stub().callsArgWith(1, null);
bitcoind._initZmqSubSocket = sinon.stub();
bitcoind._subscribeZmqEvents = sinon.stub();
bitcoind._checkReindex = sinon.stub().callsArgWith(1, null);
bitcoind._spawnChildProcess(function(err, node) {
should.not.exist(err);
spawn.callCount.should.equal(1);
spawn.args[0][0].should.equal('testexec');
spawn.args[0][1].should.deep.equal([
'--conf=testdir/bitcoin.conf',
'--datadir=testdir',
'--testnet'
]);
spawn.args[0][2].should.deep.equal({
stdio: 'inherit'
});
bitcoind._loadTipFromNode.callCount.should.equal(1);
bitcoind._initZmqSubSocket.callCount.should.equal(1);
should.exist(bitcoind._initZmqSubSocket.args[0][0].client);
bitcoind._initZmqSubSocket.args[0][1].should.equal('tcp://127.0.0.1:30001');
bitcoind._subscribeZmqEvents.callCount.should.equal(1);
should.exist(bitcoind._subscribeZmqEvents.args[0][0].client);
should.exist(node);
should.exist(node.client);
done();
});
});
it('will give error after 60 retries', function(done) {
var process = new EventEmitter();
var spawn = sinon.stub().returns(process);
var TestBitcoinService = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
child_process: {
spawn: spawn
}
});
var bitcoind = new TestBitcoinService(baseConfig);
bitcoind.startRetryInterval = 1;
bitcoind._loadSpawnConfiguration = sinon.stub();
bitcoind.spawn = {};
bitcoind.spawn.exec = 'testexec';
bitcoind.spawn.configPath = 'testdir/bitcoin.conf';
bitcoind.spawn.datadir = 'testdir';
bitcoind.spawn.config = {};
bitcoind.spawn.config.rpcport = 20001;
bitcoind.spawn.config.rpcuser = 'bitcoin';
bitcoind.spawn.config.rpcpassword = 'password';
bitcoind.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001';
bitcoind._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test'));
bitcoind._spawnChildProcess(function(err) {
err.should.be.instanceof(Error);
done();
});
});
it('will give error from check reindex', function(done) {
var process = new EventEmitter();
var spawn = sinon.stub().returns(process);
var TestBitcoinService = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
child_process: {
spawn: spawn
}
});
var bitcoind = new TestBitcoinService(baseConfig);
bitcoind._loadSpawnConfiguration = sinon.stub();
bitcoind.spawn = {};
bitcoind.spawn.exec = 'testexec';
bitcoind.spawn.configPath = 'testdir/bitcoin.conf';
bitcoind.spawn.datadir = 'testdir';
bitcoind.spawn.config = {};
bitcoind.spawn.config.rpcport = 20001;
bitcoind.spawn.config.rpcuser = 'bitcoin';
bitcoind.spawn.config.rpcpassword = 'password';
bitcoind.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001';
bitcoind._loadTipFromNode = sinon.stub().callsArgWith(1, null);
bitcoind._initZmqSubSocket = sinon.stub();
bitcoind._subscribeZmqEvents = sinon.stub();
bitcoind._checkReindex = sinon.stub().callsArgWith(1, new Error('test'));
bitcoind._spawnChildProcess(function(err) {
err.should.be.instanceof(Error);
done();
});
});
});
describe('#_connectProcess', function() {
it('will give error from loadTipFromNode after 60 retries', function(done) {
var bitcoind = new BitcoinService(baseConfig);
bitcoind._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test'));
bitcoind.startRetryInterval = 1;
var config = {};
bitcoind._connectProcess(config, function(err) {
err.should.be.instanceof(Error);
bitcoind._loadTipFromNode.callCount.should.equal(60);
done();
});
});
it('will init zmq/rpc on node', function(done) {
var bitcoind = new BitcoinService(baseConfig);
bitcoind._initZmqSubSocket = sinon.stub();
bitcoind._subscribeZmqEvents = sinon.stub();
bitcoind._loadTipFromNode = sinon.stub().callsArgWith(1, null);
var config = {};
bitcoind._connectProcess(config, function(err, node) {
should.not.exist(err);
bitcoind._loadTipFromNode.callCount.should.equal(1);
bitcoind._initZmqSubSocket.callCount.should.equal(1);
bitcoind._loadTipFromNode.callCount.should.equal(1);
should.exist(node);
should.exist(node.client);
done();
});
});
});
describe('#start', function() {