lambda-tester
Advanced tools
Comparing version
@@ -0,1 +1,7 @@ | ||
## 2.2.0 (TBD) | ||
Experimental: | ||
* Detects resources that might still be open and cause the Lambda handler to run longer than anticipated | ||
## 2.1.0 (2016-04-10) | ||
@@ -2,0 +8,0 @@ |
174
lib/index.js
'use strict'; | ||
var DEFAULT_TIMEOUT = 3000; // s3 | ||
const handleState = require( './handle_state' ); | ||
const DEFAULT_TIMEOUT = 3000; // s3 | ||
var checkForHandleLeak = false; | ||
function createContext( tester ) { | ||
@@ -109,3 +113,3 @@ | ||
function verifyResult( tester, result, verifier, resolve, reject ) { | ||
function verifyResult( tester, result, verifier, resolve, reject, savedHandleState ) { | ||
@@ -121,2 +125,15 @@ try { | ||
if( checkForHandleLeak ) { | ||
let handleDifference = savedHandleState.getDifferenceInHandles(); | ||
if( handleDifference.length > 0 ) { | ||
let err = new Error( 'Potential handle leakage detected' ); | ||
err.handles = handleDifference; | ||
throw err; | ||
} | ||
} | ||
resolve( verifier( result, { execTime } ) ); | ||
@@ -168,29 +185,37 @@ } | ||
var context = createContext( this ); | ||
let context = createContext( this ); | ||
var self = this; | ||
let self = this; | ||
let succeedPromise = new Promise( function( resolve, reject ) { | ||
let succeedPromise = Promise.resolve() | ||
.then( function() { | ||
context.succeed = function( result ) { | ||
let savedHandleState = handleState.capture(); | ||
// if memory is beyond, throw exception | ||
// need to do a nested promise because mocha injects a timer between the start of the | ||
// promise and .then() | ||
return new Promise( function( resolve, reject ) { | ||
context.succeed = function( result ) { | ||
verifyResult( self, result, resultVerifier, resolve, reject ); | ||
}; | ||
// if memory is beyond, throw exception | ||
context.fail = function( err ) { | ||
var failError = new Error( 'encountered error but expected the handler to succeed' ); | ||
failError.cause = err; | ||
verifyResult( self, result, resultVerifier, resolve, reject, savedHandleState ); | ||
}; | ||
reject( failError ); | ||
}; | ||
context.fail = function( err ) { | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
var failError = new Error( 'encountered error but expected the handler to succeed' ); | ||
failError.cause = err; | ||
let callback = createFailCallback( reject ); | ||
reject( failError ); | ||
}; | ||
runHandler( self, context, callback, reject ); | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
let callback = createFailCallback( reject ); | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
}); | ||
@@ -211,28 +236,36 @@ | ||
var context = createContext( this ); | ||
let context = createContext( this ); | ||
var self = this; | ||
let self = this; | ||
let failPromise = new Promise( function( resolve, reject ) { | ||
let failPromise = Promise.resolve() | ||
.then( function() { | ||
context.fail = function( errResult ) { | ||
let savedHandleState = handleState.capture(); | ||
verifyResult( self, errResult, resultVerifier, resolve, reject ); | ||
}; | ||
// need to do a nested promise because mocha injects a timer between the start of the | ||
// promise and .then() | ||
return new Promise( function( resolve, reject ) { | ||
context.succeed = function( result ) { | ||
context.fail = function( errResult ) { | ||
var failError = new Error( 'encountered successful operation but expected failure' ); | ||
failError.result = result; | ||
verifyResult( self, errResult, resultVerifier, resolve, reject, savedHandleState ); | ||
}; | ||
reject( failError ); | ||
}; | ||
context.succeed = function( result ) { | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
var failError = new Error( 'encountered successful operation but expected failure' ); | ||
failError.result = result; | ||
let callback = createFailCallback( reject ); | ||
reject( failError ); | ||
}; | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
let callback = createFailCallback( reject ); | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
}); | ||
// support for v1 users | ||
@@ -251,25 +284,33 @@ addLegecyVerify( failPromise ); | ||
var self = this; | ||
let self = this; | ||
return new Promise( function( resolve, reject ) { | ||
return Promise.resolve() | ||
.then( function() { | ||
var context = createCallbackContext( self, reject ); | ||
// need to do a nested promise because mocha injects a timer between the start of the | ||
// promise and .then() | ||
let savedHandleState = handleState.capture(); | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
return new Promise( function( resolve, reject ) { | ||
var callback = function( err, result ) { | ||
let context = createCallbackContext( self, reject ); | ||
if( err ) { | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
return verifyResult( self, err, resultVerifier, resolve, reject ); | ||
} | ||
var callback = function( err, result ) { | ||
var failError = new Error( 'expecting error' ); | ||
failError.result = result; | ||
if( err ) { | ||
reject( failError ); | ||
} | ||
return verifyResult( self, err, resultVerifier, resolve, reject, savedHandleState ); | ||
} | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
let failError = new Error( 'expecting error' ); | ||
failError.result = result; | ||
reject( failError ); | ||
} | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
}); | ||
} | ||
@@ -284,25 +325,33 @@ | ||
var self = this; | ||
let self = this; | ||
return new Promise( function( resolve, reject ) { | ||
return Promise.resolve() | ||
.then( function() { | ||
var context = createCallbackContext( self, reject ); | ||
// need to do a nested promise because mocha injects a timer between the start of the | ||
// promise and .then() | ||
let savedHandleState = handleState.capture(); | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
return new Promise( function( resolve, reject ) { | ||
var callback = function( err, result ) { | ||
let context = createCallbackContext( self, reject ); | ||
if( err ) { | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
var failError = new Error( 'expecting result' ); | ||
failError.cause = err; | ||
let callback = function( err, result ) { | ||
return reject( failError ); | ||
} | ||
if( err ) { | ||
verifyResult( self, result, resultVerifier, resolve, reject ); | ||
} | ||
let failError = new Error( 'expecting result' ); | ||
failError.cause = err; | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
return reject( failError ); | ||
} | ||
verifyResult( self, result, resultVerifier, resolve, reject, savedHandleState ); | ||
} | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
}); | ||
} | ||
@@ -321,2 +370,7 @@ } | ||
LambdaTesterModule.checkForResourceLeak = function( enable ) { | ||
checkForHandleLeak = (enable === true); | ||
} | ||
// Set the task root to the app's root if not already set | ||
@@ -323,0 +377,0 @@ process.env.LAMBDA_TASK_ROOT = require( 'app-root-path' ); |
{ | ||
"name": "lambda-tester", | ||
"version": "2.1.0", | ||
"description": "Helps unit test AWS Lambda handlers", | ||
"version": "2.2.0", | ||
"description": "Unit/Integration tests for AWS Lambda handlers", | ||
"main": "index.js", | ||
@@ -11,3 +11,7 @@ "keywords": [ | ||
"mocha", | ||
"TDD", | ||
"unit test", | ||
"unit testing", | ||
"integration test", | ||
"integration testing", | ||
"serverless" | ||
@@ -20,9 +24,11 @@ ], | ||
"type": "git", | ||
"url": "https://github.com/vandium-io/lambda-tester.git" | ||
"url": "git+https://github.com/vandium-io/lambda-tester.git" | ||
}, | ||
"scripts": { | ||
"test": "./node_modules/.bin/mocha --recursive", | ||
"coverage": "./node_modules/.bin/istanbul cover node_modules/mocha/bin/_mocha -- -R spec --recursive" | ||
"test": "mocha --recursive", | ||
"coverage": "istanbul cover node_modules/mocha/bin/_mocha -- -R spec --recursive" | ||
}, | ||
"author": "Vandium Software Inc.", | ||
"author": { | ||
"name": "Vandium Software Inc." | ||
}, | ||
"license": "BSD-3-Clause", | ||
@@ -37,3 +43,14 @@ "devDependencies": { | ||
"app-root-path": "^1.0.0" | ||
} | ||
}, | ||
"readme": "[](https://travis-ci.org/vandium-io/lambda-tester)\n\n# lambda-tester\n\nSimplifies writing unit tests for [AWS Lambda](https://aws.amazon.com/lambda/details) functions using [Node.js](https://nodejs.org).\n\n## Features\n* Verifies correct handler behavior\n* Works asynchronously like Lambda does\n* Detects resource leaks [experimental]\n* Supports Promises\n* Easily integrates with test frameworks\n* Lightweight and won't impact performance\n* Maps the environment variable `LAMBDA_TASK_ROOT` to the application's root\n* Works with Node 4.3.2+\n\n## Installation\nInstall via npm.\n\n\tnpm install lambda-tester --save-dev\n\n\n## Getting Started\n\nLambda handlers with support for callbacks use the typical Node.js asynchronous signature:\n\n```js\nexports.handler = function( event, context, callback ) {\n\n callback( null, 'success!' );\n}\n```\n\n\nThe following example shows a simple case for validating that the Lambda (handler) was called successfully (i.e. `callback( null, result )`:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\nconst myHandler = require( '../index' ).handler;\n\ndescribe( 'handler', function() {\n\n\tit( 'test success', function() {\n\n\t\treturn LambdaTester( myHandler )\n\t\t\t.event( { name: 'Fred' } )\n\t\t\t.expectResult();\n\t});\n});\n```\n\nIf the handler decides to call `callback( err )` then the verification will fail and the test will fail.\n\nAdditionally, if one wanted to test for failure, then the following code would be used:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\nconst myHandler = require( '../index' ).handler;\n\ndescribe( 'handler', function() {\n\n\tit( 'test failure', function() {\n\n\t\treturn LambdaTester( myHandler )\n\t\t\t.event( { name: 'Unknown' } )\n\t\t\t.expectError();\n\t});\n});\n```\n\nPlease note that you must return the `LambdaTester` back to the framework since `lambda-tester` is asynchronous and uses Promises.\n\n\n## Verifying Callbacks\n\n\nTo verify that `callback( null, result )` was called:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\n// your favorite validation tool here\nconst expect = require( 'chai' ).expect;\n\nconst myHandler = require( '../index' ).handler;\n\ndescribe( 'handler', function() {\n\n\tit( 'test callback( null, result )', function() {\n\n\t\treturn LambdaTester( myHandler )\n\t\t\t.event( { name: 'Fred' } )\n\t\t\t.expectResult( function( result ) {\n\n expect( result.userId ).to.exist;\n expect( result.user ).to.equal( 'fredsmith' );\n });\n\t});\n});\n```\n\nTo verify that `callback( err )` was called:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\n// your favorite validation tool here\nconst expect = require( 'chai' ).expect;\n\nconst myHandler = require( '../index' ).handler;\n\ndescribe( 'handler', function() {\n\n\tit( 'test callback( err )', function() {\n\n\t\treturn LambdaTester( myHandler )\n\t\t\t.event( { name: 'Unknown' } )\n\t\t\t.expectError( function( err ) {\n\n\t\t\t\texpect( err.message ).to.equal( 'User not found' );\n\t\t\t});\n\t});\n});\n```\n\n## Detecting Handlers than Run for Too Long\n\nFor Lambda handlers that must run within a specific time period, you can specify a timeout value. This value will not stop execution of your code, but will detect an error condition.\n\nTo use the timeout feature, specify a timeout value in seconds using `timeout()` as in the example below:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\n// your favorite validation tool here\nconst expect = require( 'chai' ).expect;\n\nconst myHandler = require( '../index' ).handler;\n\ndescribe( 'handler', function() {\n\n\tit( 'test callback( null, result )', function() {\n\n\t\treturn LambdaTester( myHandler )\n\t\t\t.event( { name: 'Fred' } )\n\t\t\t.timeout( 1 /* fail if longer than 1 second */ )\n\t\t\t.expectResult( function( result ) {\n\n expect( result.userId ).to.exist;\n expect( result.user ).to.equal( 'fredsmith' );\n });\n\t});\n});\n```\n\n## Verifying `context.succeed()`, `context.fail` and `context.done()`\n\nOn April 8, 2016 AWS Lambda introduced support for Lambda callbacks that replace the need to call `context.fail()` or `context.succeed()`.\n\n### Verifying `context.succeed()`\n\nWhen `expectSucceed()` is called, one can pass a function to perform additional validation. For example:\n\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\n// your favorite validation tool here\nconst expect = require( 'chai' ).expect;\n\nconst myHandler = require( '../index' ).handler;\n\ndescribe( 'handler', function() {\n\n\tit( 'test success', function() {\n\n\t\treturn LambdaTester( myHandler )\n\t\t\t.event( { name: 'Fred' } )\n\t\t\t.expectSucceed( function( result ) {\n\n\t\t\t\texpect( result.userId ).to.exist;\n\t\t\t\texpect( result.user ).to.equal( 'fredsmith' );\n\t\t\t});\n\t});\n});\n```\n\n### Verifying `context.fail()`\n\nAs with verifying success, `expectFail` has an optional parameter that can specify a function that will verify the error condition. For example:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\n// your favorite validation tool here\nconst expect = require( 'chai' ).expect;\n\nconst myHandler = require( '../index' ).handler;\n\ndescribe( 'handler', function() {\n\n\tit( 'test failure', function() {\n\n\t\treturn LambdaTester( myHandler )\n\t\t\t.event( { name: 'Unknown' } )\n\t\t\t.expectFail( function( err ) {\n\n\t\t\t\texpect( err.message ).to.equal( 'User not found' );\n\t\t\t});\n\t});\n});\n```\n\n### Verifying `context.done()`\n\nAWS Lambda routes `context.done()` to `context.succed()` and `context.fail()` for results or errors respectively, thus you can use the methods described above to verify those scenarios.\n\n## Resource Leak detection\n\n**Note**: This feature is experimental and disabled by default.\n\nResource leaks (i.e. streams and other callback events like timers) can be detected and reported. Timers or streams than continue to be active post `callback()` will cause the Lambda handler to execute in the AWS environment until a timeout condition is reached.\n\nTo enable leak detection:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\nLambdaTester.checkForResourceLeak( true );\n```\n\nWhen a leak is caught, it will cause an exception to be thrown on. For example, the following code will cause a timer to live past the callback:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\nconst expect = require( 'chai' ).expect;\n\nconst myHandler = require( '../index' ).handler;\n\nLambdaTester.checkForResourceLeak( true );\n\ndescribe( 'handler', function() {\n\n\tit( 'test callback( null, result )', function() {\n\n\t\treturn LambdaTester( function( event, context, callback ) {\n\n setTimeout( function() {}, 100 );\n\n callback( null, 'ok' );\n })\n\t\t\t.expectResult( function( result ) {\n\n // will never get here\n });\n\t});\n});\n```\n\nExamining the exception thrown will indicate a leak was detected and the handles for the resources that are still open:\n\n```js\n{ [Error: Potential handle leakage detected]\n handles:\n [ Timer {\n '0': [Function: listOnTimeout],\n _idleNext: [Object],\n _idlePrev: [Object],\n msecs: 100 } ] }\n```\n\nIf you are adding leak detection as one of your unit tests, then the previous code should be changed to:\n\n```js\nconst LambdaTester = require( 'lambda-tester' );\n\nconst expect = require( 'chai' ).expect;\n\nconst myHandler = require( '../index' ).handler;\n\nLambdaTester.checkForResourceLeak( true );\n\ndescribe( 'handler', function() {\n\n\tit( 'test callback( null, result )', function() {\n\n\t\treturn LambdaTester( function( event, context, callback ) {\n\n setTimeout( function() {}, 100 );\n\n callback( null, 'ok' );\n })\n\t\t\t.expectResult( function( result ) {\n\n throw new Error( 'should not produce a result' );\n })\n .catch( function( err ) {\n\n /* err will be:\n\n { [Error: Potential handle leakage detected]\n handles:\n [ Timer {\n '0': [Function: listOnTimeout],\n _idleNext: [Object],\n _idlePrev: [Object],\n msecs: 100 } ] }\n */\n\n expect( err.message ).to.contain( 'Potential handle leakage detected' );\n\n // TODO: add further validation here\n });\n\t});\n});\n```\n\n\n## Feedback\n\nWe'd love to get feedback on how you're using lambda-tester and things we could add to make this tool better. Feel free to contact us at `feedback@vandium.io`\n\n\n## Compatibility\n\nVersion 2.x targets Lambda handlers using Node 4.3.2. If you require support for Node 0.10.36 then use version 1.0.x.\n\n\n## License\n\n[BSD-3-Clause](https://en.wikipedia.org/wiki/BSD_licenses)\n\nCopyright (c) 2016, Vandium Software Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n * Neither the name of Vandium Software Inc. nor the\n names of its contributors may be used to endorse or promote products\n derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n", | ||
"readmeFilename": "README.md", | ||
"gitHead": "aa382e6c80ac02ab7a9d600ffdeecdbd11fb232a", | ||
"bugs": { | ||
"url": "https://github.com/vandium-io/lambda-tester/issues" | ||
}, | ||
"homepage": "https://github.com/vandium-io/lambda-tester#readme", | ||
"_id": "lambda-tester@2.2.0", | ||
"_shasum": "c626cced7bbb5c810716426b3a670f2d93a5c99e", | ||
"_from": "../lambda-tester", | ||
"_resolved": "file:../lambda-tester" | ||
} |
144
README.md
@@ -10,2 +10,3 @@ [](https://travis-ci.org/vandium-io/lambda-tester) | ||
* Works asynchronously like Lambda does | ||
* Detects resource leaks [experimental] | ||
* Supports Promises | ||
@@ -38,5 +39,5 @@ * Easily integrates with test frameworks | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
const LambdaTester = require( 'lambda-tester' ); | ||
var myHandler = require( '../index' ).handler; | ||
const myHandler = require( '../index' ).handler; | ||
@@ -59,5 +60,5 @@ describe( 'handler', function() { | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
const LambdaTester = require( 'lambda-tester' ); | ||
var myHandler = require( '../index' ).handler; | ||
const myHandler = require( '../index' ).handler; | ||
@@ -84,8 +85,8 @@ describe( 'handler', function() { | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
const LambdaTester = require( 'lambda-tester' ); | ||
// your favorite validation tool here | ||
var expect = require( 'chai' ).expect; | ||
const expect = require( 'chai' ).expect; | ||
var myHandler = require( '../index' ).handler; | ||
const myHandler = require( '../index' ).handler; | ||
@@ -110,8 +111,8 @@ describe( 'handler', function() { | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
const LambdaTester = require( 'lambda-tester' ); | ||
// your favorite validation tool here | ||
var expect = require( 'chai' ).expect; | ||
const expect = require( 'chai' ).expect; | ||
var myHandler = require( '../index' ).handler; | ||
const myHandler = require( '../index' ).handler; | ||
@@ -139,8 +140,8 @@ describe( 'handler', function() { | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
const LambdaTester = require( 'lambda-tester' ); | ||
// your favorite validation tool here | ||
var expect = require( 'chai' ).expect; | ||
const expect = require( 'chai' ).expect; | ||
var myHandler = require( '../index' ).handler; | ||
const myHandler = require( '../index' ).handler; | ||
@@ -173,8 +174,8 @@ describe( 'handler', function() { | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
const LambdaTester = require( 'lambda-tester' ); | ||
// your favorite validation tool here | ||
var expect = require( 'chai' ).expect; | ||
const expect = require( 'chai' ).expect; | ||
var myHandler = require( '../index' ).handler; | ||
const myHandler = require( '../index' ).handler; | ||
@@ -201,8 +202,8 @@ describe( 'handler', function() { | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
const LambdaTester = require( 'lambda-tester' ); | ||
// your favorite validation tool here | ||
var expect = require( 'chai' ).expect; | ||
const expect = require( 'chai' ).expect; | ||
var myHandler = require( '../index' ).handler; | ||
const myHandler = require( '../index' ).handler; | ||
@@ -227,6 +228,107 @@ describe( 'handler', function() { | ||
## Resource Leak detection | ||
**Note**: This feature is experimental and disabled by default. | ||
Resource leaks (i.e. streams and other callback events like timers) can be detected and reported. Timers or streams than continue to be active post `callback()` will cause the Lambda handler to execute in the AWS environment until a timeout condition is reached. | ||
To enable leak detection: | ||
```js | ||
const LambdaTester = require( 'lambda-tester' ); | ||
LambdaTester.checkForResourceLeak( true ); | ||
``` | ||
When a leak is caught, it will cause an exception to be thrown on. For example, the following code will cause a timer to live past the callback: | ||
```js | ||
const LambdaTester = require( 'lambda-tester' ); | ||
const expect = require( 'chai' ).expect; | ||
const myHandler = require( '../index' ).handler; | ||
LambdaTester.checkForResourceLeak( true ); | ||
describe( 'handler', function() { | ||
it( 'test callback( null, result )', function() { | ||
return LambdaTester( function( event, context, callback ) { | ||
setTimeout( function() {}, 100 ); | ||
callback( null, 'ok' ); | ||
}) | ||
.expectResult( function( result ) { | ||
// will never get here | ||
}); | ||
}); | ||
}); | ||
``` | ||
Examining the exception thrown will indicate a leak was detected and the handles for the resources that are still open: | ||
```js | ||
{ [Error: Potential handle leakage detected] | ||
handles: | ||
[ Timer { | ||
'0': [Function: listOnTimeout], | ||
_idleNext: [Object], | ||
_idlePrev: [Object], | ||
msecs: 100 } ] } | ||
``` | ||
If you are adding leak detection as one of your unit tests, then the previous code should be changed to: | ||
```js | ||
const LambdaTester = require( 'lambda-tester' ); | ||
const expect = require( 'chai' ).expect; | ||
const myHandler = require( '../index' ).handler; | ||
LambdaTester.checkForResourceLeak( true ); | ||
describe( 'handler', function() { | ||
it( 'test callback( null, result )', function() { | ||
return LambdaTester( function( event, context, callback ) { | ||
setTimeout( function() {}, 100 ); | ||
callback( null, 'ok' ); | ||
}) | ||
.expectResult( function( result ) { | ||
throw new Error( 'should not produce a result' ); | ||
}) | ||
.catch( function( err ) { | ||
/* err will be: | ||
{ [Error: Potential handle leakage detected] | ||
handles: | ||
[ Timer { | ||
'0': [Function: listOnTimeout], | ||
_idleNext: [Object], | ||
_idlePrev: [Object], | ||
msecs: 100 } ] } | ||
*/ | ||
expect( err.message ).to.contain( 'Potential handle leakage detected' ); | ||
// TODO: add further validation here | ||
}); | ||
}); | ||
}); | ||
``` | ||
## Feedback | ||
We'd love to get feedback on how to make this tool better. Feel free to contact us at `feedback@vandium.io` | ||
We'd love to get feedback on how you're using lambda-tester and things we could add to make this tool better. Feel free to contact us at `feedback@vandium.io` | ||
@@ -236,3 +338,3 @@ | ||
Version 2.0 targets Lambda handlers using Node 4.3.2. If you require support for Node 0.10.36 then use version 1.0.x. | ||
Version 2.x targets Lambda handlers using Node 4.3.2. If you require support for Node 0.10.36 then use version 1.0.x. | ||
@@ -239,0 +341,0 @@ |
Sorry, the diff of this file is not supported yet
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
35354
99.21%281
44.1%1
-50%0
-100%360
39.53%8
-20%