diff --git a/libraries/metrics/test/unit/coffee/timeAsyncMethodTests.coffee b/libraries/metrics/test/unit/coffee/timeAsyncMethodTests.coffee index 7cb8ad7aa5..b6a4d3cd6b 100644 --- a/libraries/metrics/test/unit/coffee/timeAsyncMethodTests.coffee +++ b/libraries/metrics/test/unit/coffee/timeAsyncMethodTests.coffee @@ -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 diff --git a/libraries/metrics/timeAsyncMethod.coffee b/libraries/metrics/timeAsyncMethod.coffee index 4134086418..f4eefef559 100644 --- a/libraries/metrics/timeAsyncMethod.coffee +++ b/libraries/metrics/timeAsyncMethod.coffee @@ -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