Increment stats for success/failure of wrapped async calls

This commit is contained in:
Shane Kilkelly 2017-03-20 16:54:40 +00:00
parent 1f77cc0fd3
commit f2ebdd1662
2 changed files with 29 additions and 7 deletions

View file

@ -15,6 +15,7 @@ describe 'timeAsyncMethod', ->
@TimerConstructor = sinon.stub().returns(@Timer)
@metrics = {
Timer: @TimerConstructor
inc: sinon.stub()
}
@timeAsyncMethod = SandboxedModule.require modulePath, requires:
'./metrics': @metrics
@ -35,11 +36,11 @@ describe 'timeAsyncMethod', ->
done()
it 'should wrap method without error', (done) ->
@timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber'
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject'
done()
it 'should transparently wrap method invocation in timer', (done) ->
@timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber'
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject'
@testObject.nextNumber 2, (err, result) =>
expect(err).to.not.exist
expect(result).to.equal 3
@ -47,8 +48,17 @@ describe 'timeAsyncMethod', ->
expect(@Timer.done.callCount).to.equal 1
done()
it 'should increment success count', (done) ->
@metrics.inc = sinon.stub()
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject'
@testObject.nextNumber 2, (err, result) =>
expect(@metrics.inc.callCount).to.equal 1
expect(@metrics.inc.calledWith('someContext.TestObject.nextNumber.success')).to.equal true
done()
describe 'when base method produces an error', ->
beforeEach ->
@metrics.inc = sinon.stub()
@testObject.nextNumber = (n, callback=(err, result)->) ->
setTimeout(
() ->
@ -57,19 +67,26 @@ describe 'timeAsyncMethod', ->
)
it 'should propagate the error transparently', (done) ->
@timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber'
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject'
@testObject.nextNumber 2, (err, result) =>
expect(err).to.exist
expect(err).to.be.instanceof Error
expect(result).to.not.exist
done()
it 'should increment failure count', (done) ->
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject'
@testObject.nextNumber 2, (err, result) =>
expect(@metrics.inc.callCount).to.equal 1
expect(@metrics.inc.calledWith('someContext.TestObject.nextNumber.failure')).to.equal true
done()
describe 'when a logger is supplied', ->
beforeEach ->
@logger = {log: sinon.stub()}
it 'should also call logger.log', (done) ->
@timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber', @logger
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject', @logger
@testObject.nextNumber 2, (err, result) =>
expect(err).to.not.exist
expect(result).to.equal 3
@ -83,7 +100,7 @@ describe 'timeAsyncMethod', ->
it 'should raise an error', ->
badWrap = () =>
@timeAsyncMethod @testObject, 'DEFINITELY_NOT_A_REAL_METHOD', 'test.nextNumber'
@timeAsyncMethod @testObject, 'DEFINITELY_NOT_A_REAL_METHOD', 'someContext.TestObject'
expect(badWrap).to.throw(
/^.*expected object property 'DEFINITELY_NOT_A_REAL_METHOD' to be a function.*$/
)
@ -94,13 +111,13 @@ describe 'timeAsyncMethod', ->
@testObject.nextNumber = @realMethod
it 'should not throw an error', ->
@timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber'
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject'
badCall = () =>
@testObject.nextNumber 2
expect(badCall).to.not.throw(Error)
it 'should call the underlying method', ->
@timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber'
@timeAsyncMethod @testObject, 'nextNumber', 'someContext.TestObject'
result = @testObject.nextNumber(12)
expect(@realMethod.callCount).to.equal 1
expect(@realMethod.calledWith(12)).to.equal true

View file

@ -21,6 +21,11 @@ module.exports = (obj, methodName, prefix, logger) ->
realMethod.call this, firstArgs..., (callbackArgs...) ->
elapsedTime = timer.done()
possibleError = callbackArgs[0]
if possibleError? && possibleError.message? && possibleError.stack?
metrics.inc "#{key}.failure"
else
metrics.inc "#{key}.success"
if logger?
loggableArgs = {}
try