Ivan Socolsky
9 years ago
5 changed files with 270 additions and 34 deletions
@ -0,0 +1,57 @@ |
|||
var _ = require('lodash'); |
|||
var async = require('async'); |
|||
var $ = require('preconditions').singleton(); |
|||
|
|||
var log = require('npmlog'); |
|||
log.debug = log.verbose; |
|||
|
|||
/** |
|||
* Query a server, using one of the given options |
|||
* |
|||
* @param {Object} opts |
|||
* @param {Array} opts.hosts Array of hosts to query. Until the first success one. |
|||
* @param {Array} opts.path Path to request in each server |
|||
*/ |
|||
var requestList = function(args, cb) { |
|||
$.checkArgument(args.hosts); |
|||
request = args.request || require('request'); |
|||
|
|||
if (!_.isArray(args.hosts)) |
|||
args.hosts = [args.hosts]; |
|||
|
|||
var urls = _.map(args.hosts, function(x) { |
|||
return (x + args.path); |
|||
}); |
|||
var nextUrl, result, success; |
|||
|
|||
async.whilst( |
|||
function() { |
|||
nextUrl = urls.shift(); |
|||
return nextUrl && !success; |
|||
}, |
|||
function(a_cb) { |
|||
args.uri = nextUrl; |
|||
request(args, function(err, res, body) { |
|||
if (err) { |
|||
log.warn('REQUEST FAIL: ' + nextUrl + ' ERROR: ' + err); |
|||
} |
|||
|
|||
if (res) { |
|||
success = !!res.statusCode.toString().match(/^[1234]../); |
|||
if (!success) { |
|||
log.warn('REQUEST FAIL: ' + nextUrl + ' STATUS CODE: ' + res.statusCode); |
|||
} |
|||
} |
|||
|
|||
result = [err, res, body]; |
|||
return a_cb(); |
|||
}); |
|||
}, |
|||
function(err) { |
|||
if (err) return cb(err); |
|||
return cb(result[0], result[1], result[2]); |
|||
} |
|||
); |
|||
}; |
|||
|
|||
module.exports = requestList; |
@ -0,0 +1,170 @@ |
|||
'use strict'; |
|||
|
|||
var _ = require('lodash'); |
|||
var chai = require('chai'); |
|||
var sinon = require('sinon'); |
|||
var should = chai.should(); |
|||
var prequest = require('../lib/blockchainexplorers/request-list'); |
|||
|
|||
describe('request-list', function() { |
|||
var request; |
|||
|
|||
beforeEach(function() { |
|||
request = sinon.stub(); |
|||
}); |
|||
it('should support url as string', function(done) { |
|||
|
|||
request.yields(null, { |
|||
statusCode: 200 |
|||
}, 'abc'); |
|||
|
|||
prequest({ |
|||
hosts: 'url1', |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
body.should.be.equal('abc'); |
|||
res.statusCode.should.be.equal(200); |
|||
done(); |
|||
}); |
|||
}); |
|||
it('should support url as string (500 response)', function(done) { |
|||
request.yields(null, { |
|||
statusCode: 500 |
|||
}); |
|||
prequest({ |
|||
hosts: 'url1', |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
res.statusCode.should.be.equal(500); |
|||
done(); |
|||
}); |
|||
}); |
|||
it('should support url as array of strings', function(done) { |
|||
request.yields(null, { |
|||
statusCode: 200 |
|||
}, 'abc'); |
|||
prequest({ |
|||
hosts: ['url1', 'url2'], |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
body.should.be.equal('abc'); |
|||
done(); |
|||
}); |
|||
}); |
|||
it('should try 2nd url if first is unsuccessful (5xx)', function(done) { |
|||
request.onCall(0).yields(null, { |
|||
statusCode: 500 |
|||
}); |
|||
request.onCall(1).yields(null, { |
|||
statusCode: 550 |
|||
}); |
|||
prequest({ |
|||
hosts: ['url1', 'url2'], |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
res.statusCode.should.be.equal(550); |
|||
done(); |
|||
}); |
|||
}); |
|||
it('should query 3th url if first 2 are unsuccessful (5xx)', function(done) { |
|||
request.onCall(0).yields(null, { |
|||
statusCode: 500 |
|||
}); |
|||
request.onCall(1).yields(null, { |
|||
statusCode: 550 |
|||
}); |
|||
request.onCall(2).yields(null, { |
|||
statusCode: 200, |
|||
}, 'abc'); |
|||
prequest({ |
|||
hosts: ['url1', 'url2', 'url3'], |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
body.should.be.equal('abc'); |
|||
done(); |
|||
}); |
|||
}); |
|||
it('should query only the first url if response is 404', function(done) { |
|||
request.onCall(0).yields(null, { |
|||
statusCode: 404 |
|||
}); |
|||
request.onCall(1).yields(null, { |
|||
statusCode: 550 |
|||
}); |
|||
prequest({ |
|||
hosts: ['url1', 'url2'], |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
res.statusCode.should.be.equal(404); |
|||
done(); |
|||
}); |
|||
}); |
|||
it('should query only the first 2 urls if the second is successfull (5xx)', function(done) { |
|||
request.onCall(0).yields(null, { |
|||
statusCode: 500 |
|||
}); |
|||
request.onCall(1).yields(null, { |
|||
statusCode: 200, |
|||
}, '2nd'); |
|||
request.onCall(2).yields(null, { |
|||
statusCode: 200, |
|||
}, 'abc'); |
|||
prequest({ |
|||
hosts: ['url1', 'url2', 'url3'], |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
body.should.be.equal('2nd'); |
|||
res.statusCode.should.be.equal(200); |
|||
done(); |
|||
}); |
|||
}); |
|||
it('should query only the first 2 urls if the second is successfull (timeout)', function(done) { |
|||
request.onCall(0).yields({ |
|||
code: 'ETIMEDOUT', |
|||
connect: true |
|||
}); |
|||
request.onCall(1).yields(null, { |
|||
statusCode: 200, |
|||
}, '2nd'); |
|||
request.onCall(2).yields(null, { |
|||
statusCode: 200, |
|||
}, 'abc'); |
|||
prequest({ |
|||
hosts: ['url1', 'url2', 'url3'], |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
body.should.be.equal('2nd'); |
|||
res.statusCode.should.be.equal(200); |
|||
done(); |
|||
}); |
|||
|
|||
}); |
|||
it('should use the latest response if all requests are unsuccessfull', function(done) { |
|||
request.onCall(0).yields({ |
|||
code: 'ETIMEDOUT', |
|||
connect: true |
|||
}); |
|||
request.onCall(1).yields(null, { |
|||
statusCode: 505, |
|||
}, '2nd'); |
|||
request.onCall(2).yields(null, { |
|||
statusCode: 510, |
|||
}, 'abc'); |
|||
prequest({ |
|||
hosts: ['url1', 'url2', 'url3'], |
|||
request: request, |
|||
}, function(err, res, body) { |
|||
should.not.exist(err); |
|||
res.statusCode.should.be.equal(510); |
|||
done(); |
|||
}); |
|||
}); |
|||
}); |
Loading…
Reference in new issue