2015-08-31 06:00:00 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var should = require('chai').should();
|
2015-08-31 08:09:24 -07:00
|
|
|
var sinon = require('sinon');
|
2015-08-31 06:00:00 -07:00
|
|
|
var proxyquire = require('proxyquire');
|
|
|
|
var fs = require('fs');
|
|
|
|
var sinon = require('sinon');
|
2015-08-31 08:09:24 -07:00
|
|
|
var readFileSync = sinon.stub().returns(fs.readFileSync(__dirname + '/../data/bitcoin.conf'));
|
2015-08-31 06:00:00 -07:00
|
|
|
var BitcoinService = proxyquire('../../lib/services/bitcoind', {
|
2015-08-31 06:00:00 -07:00
|
|
|
fs: {
|
2015-08-31 08:09:24 -07:00
|
|
|
readFileSync: readFileSync
|
2015-08-31 06:00:00 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-08-31 06:00:00 -07:00
|
|
|
describe('Bitcoin Service', function() {
|
2015-08-31 06:00:00 -07:00
|
|
|
var baseConfig = {
|
|
|
|
node: {
|
|
|
|
datadir: 'testdir',
|
|
|
|
network: {
|
|
|
|
name: 'regtest'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-08-31 08:09:24 -07:00
|
|
|
describe('@constructor', function() {
|
|
|
|
it('will create an instance', function() {
|
|
|
|
var bitcoind = new BitcoinService(baseConfig);
|
|
|
|
should.exist(bitcoind);
|
|
|
|
});
|
|
|
|
it('will create an instance without `new`', function() {
|
|
|
|
var bitcoind = BitcoinService(baseConfig);
|
|
|
|
should.exist(bitcoind);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe('@dependencies', function() {
|
|
|
|
it('will have no dependencies', function() {
|
|
|
|
BitcoinService.dependencies.should.deep.equal([]);
|
|
|
|
});
|
|
|
|
});
|
2015-08-31 06:00:00 -07:00
|
|
|
describe('#_loadConfiguration', function() {
|
|
|
|
it('will parse a bitcoin.conf file', function() {
|
2015-08-31 08:09:24 -07:00
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync,
|
|
|
|
existsSync: sinon.stub().returns(true)
|
|
|
|
},
|
|
|
|
mkdirp: {
|
|
|
|
sync: sinon.stub()
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
2015-08-31 06:00:00 -07:00
|
|
|
bitcoind._loadConfiguration({datadir: process.env.HOME + '/.bitcoin'});
|
|
|
|
should.exist(bitcoind.configuration);
|
|
|
|
bitcoind.configuration.should.deep.equal({
|
|
|
|
server: 1,
|
|
|
|
whitelist: '127.0.0.1',
|
|
|
|
txindex: 1,
|
|
|
|
port: 20000,
|
|
|
|
rpcallowip: '127.0.0.1',
|
|
|
|
rpcuser: 'bitcoin',
|
|
|
|
rpcpassword: 'local321'
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it('should throw an exception if txindex isn\'t enabled in the configuration', function() {
|
2015-08-31 08:09:24 -07:00
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: sinon.stub().returns(fs.readFileSync(__dirname + '/../data/badbitcoin.conf')),
|
|
|
|
existsSync: sinon.stub().returns(true),
|
|
|
|
},
|
|
|
|
mkdirp: {
|
|
|
|
sync: sinon.stub()
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
2015-08-31 06:00:00 -07:00
|
|
|
(function() {
|
|
|
|
bitcoind._loadConfiguration({datadir: './test'});
|
|
|
|
}).should.throw('Txindex option');
|
|
|
|
});
|
|
|
|
});
|
2015-08-31 08:09:24 -07:00
|
|
|
describe('#_registerEventHandlers', function() {
|
|
|
|
it('will emit tx with transactions from bindings', function(done) {
|
|
|
|
var transaction = {};
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
onTipUpdate: sinon.stub(),
|
|
|
|
startTxMon: sinon.stub().callsArgWith(0, [transaction])
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
bitcoind.on('tx', function(tx) {
|
|
|
|
tx.should.equal(transaction);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
bitcoind._registerEventHandlers();
|
|
|
|
});
|
|
|
|
it('will emit tip from bindings', function(done) {
|
|
|
|
var height = 1;
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
syncPercentage: function() {
|
|
|
|
return height * 10;
|
|
|
|
},
|
|
|
|
onTipUpdate: function(callback) {
|
|
|
|
if (height >= 10) {
|
|
|
|
return callback(undefined);
|
|
|
|
}
|
|
|
|
setImmediate(function() {
|
|
|
|
callback(height++);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
startTxMon: sinon.stub()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
var tipCallCount = 0;
|
|
|
|
bitcoind.on('tip', function(height) {
|
|
|
|
should.exist(height);
|
|
|
|
tipCallCount++;
|
|
|
|
if (height === 9) {
|
|
|
|
tipCallCount.should.equal(9);
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
bitcoind._registerEventHandlers();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe('#_onReady', function(done) {
|
|
|
|
var genesisBuffer = new Buffer('0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0420e7494d017f062f503253482fffffffff0100f2052a010000002321021aeaf2f8638a129a3156fbe7e5ef635226b0bafd495ff03afe2c843d7e3a4b51ac00000000', 'hex');
|
|
|
|
it('will emit ready and set the height and genesisBuffer', function(done) {
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
onTipUpdate: sinon.stub(),
|
|
|
|
startTxMon: sinon.stub(),
|
|
|
|
getInfo: sinon.stub().returns({
|
|
|
|
blocks: 101
|
|
|
|
}),
|
|
|
|
getBlock: sinon.stub().callsArgWith(1, null, genesisBuffer)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
bitcoind._registerEventHandlers = sinon.stub();
|
|
|
|
var result = {};
|
|
|
|
var readyCallCount = 0;
|
|
|
|
bitcoind.on('ready', function() {
|
|
|
|
readyCallCount++;
|
|
|
|
});
|
|
|
|
bitcoind._onReady(result, function(err) {
|
|
|
|
if (err) {
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
bitcoind._registerEventHandlers.callCount.should.equal(1);
|
|
|
|
readyCallCount.should.equal(1);
|
|
|
|
bitcoind.genesisBuffer.should.equal(genesisBuffer);
|
|
|
|
bitcoind.height.should.equal(101);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe('#start', function() {
|
|
|
|
it('call bindings start with the correct arguments', function(done) {
|
|
|
|
var startCallCount = 0;
|
|
|
|
var start = function(obj, cb) {
|
|
|
|
startCallCount++;
|
|
|
|
obj.datadir.should.equal('testdir');
|
|
|
|
obj.network.should.equal('regtest');
|
|
|
|
cb();
|
|
|
|
};
|
|
|
|
var onBlocksReady = sinon.stub().callsArg(0);
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
start: start,
|
|
|
|
onBlocksReady: onBlocksReady
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
bitcoind._loadConfiguration = sinon.stub();
|
|
|
|
bitcoind._onReady = sinon.stub().callsArg(1);
|
|
|
|
bitcoind.start(function(err) {
|
|
|
|
should.not.exist(err);
|
|
|
|
bitcoind._loadConfiguration.callCount.should.equal(1);
|
|
|
|
startCallCount.should.equal(1);
|
|
|
|
onBlocksReady.callCount.should.equal(1);
|
|
|
|
bitcoind._onReady.callCount.should.equal(1);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it('will give an error from bindings.start', function(done) {
|
|
|
|
var start = sinon.stub().callsArgWith(1, new Error('test'));
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
start: start
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
bitcoind._loadConfiguration = sinon.stub();
|
|
|
|
bitcoind.start(function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal('test');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it('will give an error from bindings.onBlocksReady', function(done) {
|
|
|
|
var start = sinon.stub().callsArgWith(1, null);
|
|
|
|
var onBlocksReady = sinon.stub().callsArgWith(0, new Error('test'));
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
start: start,
|
|
|
|
onBlocksReady: onBlocksReady
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
bitcoind._onReady = sinon.stub().callsArg(1);
|
|
|
|
bitcoind._loadConfiguration = sinon.stub();
|
|
|
|
bitcoind.start(function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal('test');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe('#stop', function() {
|
|
|
|
it('will call bindings stop', function() {
|
|
|
|
var stop = sinon.stub().callsArgWith(0, null, 'status');
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
stop: stop
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
bitcoind.stop(function(err, status) {
|
|
|
|
stop.callCount.should.equal(1);
|
|
|
|
should.not.exist(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it('will give an error from bindings stop', function() {
|
|
|
|
var stop = sinon.stub().callsArgWith(0, new Error('test'));
|
|
|
|
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
|
|
|
|
fs: {
|
|
|
|
readFileSync: readFileSync
|
|
|
|
},
|
|
|
|
bindings: function(name) {
|
|
|
|
name.should.equal('bitcoind.node');
|
|
|
|
return {
|
|
|
|
stop: stop
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var bitcoind = new TestBitcoin(baseConfig);
|
|
|
|
bitcoind.stop(function(err) {
|
|
|
|
stop.callCount.should.equal(1);
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal('test');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2015-08-31 06:00:00 -07:00
|
|
|
|
2015-08-31 08:09:24 -07:00
|
|
|
});
|