2019-06-21 05:57:43 -04:00
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
const path = require('path')
|
|
|
|
const modulePath = path.join(
|
|
|
|
__dirname,
|
|
|
|
'../../../../app/src/infrastructure/FaultTolerantRequest'
|
|
|
|
)
|
|
|
|
const sinon = require('sinon')
|
|
|
|
const { expect } = require('chai')
|
|
|
|
|
|
|
|
describe('FaultTolerantRequest', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.request = sinon.stub().yields()
|
|
|
|
this.logger = {
|
|
|
|
err: sinon.stub()
|
|
|
|
}
|
|
|
|
this.FaultTolerantRequest = SandboxedModule.require(modulePath, {
|
2019-07-15 06:33:47 -04:00
|
|
|
globals: {
|
|
|
|
console: console
|
|
|
|
},
|
2019-06-21 05:57:43 -04:00
|
|
|
requires: {
|
|
|
|
requestretry: this.request,
|
|
|
|
'logger-sharelatex': this.logger
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('exponentialBackoffStrategy', function() {
|
|
|
|
it('returns delays within expected range with default options', function() {
|
|
|
|
this.FaultTolerantRequest.request({}, () => {})
|
|
|
|
const delayStrategy = this.request.lastCall.args[0].delayStrategy
|
|
|
|
expect(delayStrategy()).to.be.closeTo(500, 250) // attempt 1
|
|
|
|
expect(delayStrategy()).to.be.closeTo(750, 375) // attempt 2
|
|
|
|
expect(delayStrategy()).to.be.closeTo(1125, 563) // attempt 3
|
|
|
|
expect(delayStrategy()).to.be.closeTo(1688, 844) // attempt 4
|
|
|
|
expect(delayStrategy()).to.be.closeTo(2531, 1266) // attempt 5
|
|
|
|
expect(delayStrategy()).to.be.closeTo(3797, 1899) // attempt 6
|
|
|
|
expect(delayStrategy()).to.be.closeTo(5695, 2848) // attempt 7
|
|
|
|
expect(delayStrategy()).to.be.closeTo(8543, 4272) // attempt 8
|
|
|
|
expect(delayStrategy()).to.be.closeTo(12814, 6408) // attempt 9
|
|
|
|
expect(delayStrategy()).to.be.closeTo(19222, 9610) // attempt 10
|
|
|
|
})
|
|
|
|
|
|
|
|
it('returns delays within expected range with custom options', function() {
|
|
|
|
const delayStrategy = this.FaultTolerantRequest.exponentialDelayStrategy(
|
|
|
|
3000,
|
|
|
|
3,
|
|
|
|
0.5
|
|
|
|
)
|
|
|
|
expect(delayStrategy()).to.be.closeTo(3000, 1500) // attempt 1
|
|
|
|
expect(delayStrategy()).to.be.closeTo(9000, 4500) // attempt 2
|
|
|
|
expect(delayStrategy()).to.be.closeTo(27000, 13500) // attempt 3
|
|
|
|
expect(delayStrategy()).to.be.closeTo(81000, 40500) // attempt 4
|
|
|
|
expect(delayStrategy()).to.be.closeTo(243000, 121500) // attempt 5
|
|
|
|
expect(delayStrategy()).to.be.closeTo(729000, 364500) // attempt 6
|
|
|
|
expect(delayStrategy()).to.be.closeTo(2187000, 1093500) // attempt 7
|
|
|
|
expect(delayStrategy()).to.be.closeTo(6561000, 3280500) // attempt 8
|
|
|
|
expect(delayStrategy()).to.be.closeTo(19683000, 9841500) // attempt 9
|
|
|
|
expect(delayStrategy()).to.be.closeTo(59049000, 29524500) // attempt 10
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('request', function() {
|
|
|
|
it('sets retry options', function(done) {
|
|
|
|
this.FaultTolerantRequest.request({}, error => {
|
|
|
|
expect(error).to.not.exist
|
|
|
|
sinon.assert.calledOnce(this.request)
|
|
|
|
|
|
|
|
const { delayStrategy, maxAttempts } = this.request.lastCall.args[0]
|
|
|
|
expect(delayStrategy).to.be.a('function')
|
|
|
|
expect(maxAttempts).to.be.a('number')
|
|
|
|
done()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it("don't overwrite retry options", function(done) {
|
|
|
|
const customMaxAttempts = Math.random()
|
|
|
|
const customBase = Math.random()
|
|
|
|
const customMultiplier = Math.random()
|
|
|
|
const customRandomFactor = Math.random()
|
|
|
|
this.FaultTolerantRequest.request(
|
|
|
|
{
|
|
|
|
maxAttempts: customMaxAttempts,
|
|
|
|
backoffBase: customBase,
|
|
|
|
backoffMultiplier: customMultiplier,
|
|
|
|
backoffRandomFactor: customRandomFactor
|
|
|
|
},
|
|
|
|
error => {
|
|
|
|
expect(error).to.not.exist
|
|
|
|
|
|
|
|
const {
|
|
|
|
maxAttempts,
|
|
|
|
backoffBase,
|
|
|
|
backoffMultiplier,
|
|
|
|
backoffRandomFactor
|
|
|
|
} = this.request.lastCall.args[0]
|
|
|
|
expect(maxAttempts).to.equal(customMaxAttempts)
|
|
|
|
expect(backoffBase).to.equal(customBase)
|
|
|
|
expect(backoffMultiplier).to.equal(customMultiplier)
|
|
|
|
expect(backoffRandomFactor).to.equal(customRandomFactor)
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('backgroundRequest', function() {
|
|
|
|
it('logs error in the background', function(done) {
|
|
|
|
this.request.yields(new Error('Nope'))
|
|
|
|
this.logger.err = (options, message) => {
|
|
|
|
expect(options.url).to.equal('test.url')
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
this.FaultTolerantRequest.backgroundRequest(
|
|
|
|
{ url: 'test.url' },
|
|
|
|
error => {
|
|
|
|
expect(error).to.not.exist
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|