diff --git a/lib/services/bitcoind.js b/lib/services/bitcoind.js index 90614201..da702678 100644 --- a/lib/services/bitcoind.js +++ b/lib/services/bitcoind.js @@ -54,6 +54,7 @@ function Bitcoin(options) { // spawn restart setting this.spawnRestartTime = options.spawnRestartTime || Bitcoin.DEFAULT_SPAWN_RESTART_TIME; + this.spawnStopTime = options.spawnStopTime || Bitcoin.DEFAULT_SPAWN_STOP_TIME; // try all interval this.tryAllInterval = options.tryAllInterval || Bitcoin.DEFAULT_TRY_ALL_INTERVAL; @@ -62,6 +63,9 @@ function Bitcoin(options) { // available bitcoind nodes this._initClients(); + // for testing purposes + this._process = options.process || process; + this.on('error', function(err) { log.error(err.stack); }); @@ -74,6 +78,7 @@ Bitcoin.DEFAULT_MAX_HISTORY = 10; Bitcoin.DEFAULT_SHUTDOWN_TIMEOUT = 15000; Bitcoin.DEFAULT_MAX_ADDRESSES_QUERY = 10000; Bitcoin.DEFAULT_SPAWN_RESTART_TIME = 5000; +Bitcoin.DEFAULT_SPAWN_STOP_TIME = 10000; Bitcoin.DEFAULT_TRY_ALL_INTERVAL = 1000; Bitcoin.DEFAULT_REINDEX_INTERVAL = 10000; Bitcoin.DEFAULT_START_RETRY_INTERVAL = 5000; @@ -618,6 +623,7 @@ Bitcoin.prototype._loadTipFromNode = function(node, callback) { }; Bitcoin.prototype._stopSpawnedBitcoin = function(callback) { + var self = this; var spawnOptions = this.options.spawn; var pidPath = spawnOptions.datadir + '/bitcoind.pid'; @@ -630,9 +636,9 @@ Bitcoin.prototype._stopSpawnedBitcoin = function(callback) { return callback(err); } pid = parseInt(pid); - log.warn('Stopping existing spawned bitcoin process with pid: ' + pid); try { - process.kill(pid, 'SIGINT'); + log.warn('Stopping existing spawned bitcoin process with pid: ' + pid); + self._process.kill(pid, 'SIGINT'); } catch(err) { if (err && err.code === 'ESRCH') { log.warn('Unclean bitcoin process shutdown, process not found with pid: ' + pid); @@ -643,7 +649,7 @@ Bitcoin.prototype._stopSpawnedBitcoin = function(callback) { } setTimeout(function() { stopProcess(); - }, 10000); + }, self.spawnStopTime); }); } diff --git a/regtest/bitcoind.js b/regtest/bitcoind.js index 485b33dc..9d729845 100644 --- a/regtest/bitcoind.js +++ b/regtest/bitcoind.js @@ -131,6 +131,7 @@ describe('Bitcoind Functionality', function() { after(function(done) { this.timeout(20000); + bitcoind.node.stopping = true; bitcoind.stop(function(err, result) { done(); }); diff --git a/regtest/p2p.js b/regtest/p2p.js index acf718d1..4af160bd 100644 --- a/regtest/p2p.js +++ b/regtest/p2p.js @@ -163,6 +163,7 @@ describe('P2P Functionality', function() { this.timeout(20000); peer.on('disconnect', function() { log.info('Peer disconnected'); + bitcoind.node.stopping = true; bitcoind.stop(function(err, result) { done(); }); diff --git a/test/services/bitcoind.unit.js b/test/services/bitcoind.unit.js index 7d3d227a..1699e554 100644 --- a/test/services/bitcoind.unit.js +++ b/test/services/bitcoind.unit.js @@ -1001,6 +1001,66 @@ describe('Bitcoin Service', function() { }); }); + describe('#_stopSpawnedProcess', function() { + var sandbox = sinon.sandbox.create(); + beforeEach(function() { + sandbox.stub(log, 'warn'); + }); + afterEach(function() { + sandbox.restore(); + }); + it('it will kill process and resume', function(done) { + var readFile = sandbox.stub(); + readFile.onCall(0).callsArgWith(2, null, '4321'); + var error = new Error('Test error'); + error.code = 'ENOENT'; + readFile.onCall(1).callsArgWith(2, error); + var TestBitcoinService = proxyquire('../../lib/services/bitcoind', { + fs: { + readFile: readFile + } + }); + var bitcoind = new TestBitcoinService(baseConfig); + bitcoind.spawnStopTime = 1; + bitcoind._process = {}; + bitcoind._process.kill = sinon.stub(); + bitcoind._stopSpawnedBitcoin(function(err) { + if (err) { + return done(err); + } + bitcoind._process.kill.callCount.should.equal(1); + log.warn.callCount.should.equal(1); + done(); + }); + }); + it('it will attempt to kill process and resume', function(done) { + var readFile = sandbox.stub(); + readFile.onCall(0).callsArgWith(2, null, '4321'); + var error = new Error('Test error'); + error.code = 'ENOENT'; + readFile.onCall(1).callsArgWith(2, error); + var TestBitcoinService = proxyquire('../../lib/services/bitcoind', { + fs: { + readFile: readFile + } + }); + var bitcoind = new TestBitcoinService(baseConfig); + bitcoind.spawnStopTime = 1; + bitcoind._process = {}; + var error2 = new Error('Test error'); + error2.code = 'ESRCH'; + bitcoind._process.kill = sinon.stub().throws(error2); + bitcoind._stopSpawnedBitcoin(function(err) { + if (err) { + return done(err); + } + bitcoind._process.kill.callCount.should.equal(1); + log.warn.callCount.should.equal(2); + done(); + }); + }); + }); + describe('#_spawnChildProcess', function() { it('will give error from spawn config', function(done) { var bitcoind = new BitcoinService(baseConfig);