lambda-tester
Advanced tools
Comparing version
@@ -0,4 +1,18 @@ | ||
## 2.1.0 (2016-04-10) | ||
New: | ||
* Support for using `GetRemainingTimeInMillis()` from the context object | ||
* Timeout can be set for the tester so that it detects when the Lambda handler has run for too long | ||
* Environment variable `LAMBDA_TASK_ROOT` is now set to the application root folder | ||
Fixed: | ||
* Updated documentation | ||
## 2.0.0 (2016-04-09) | ||
New: | ||
* Can now use Promises within verifiers | ||
@@ -8,5 +22,7 @@ * Supports Lambda Callbacks | ||
Improved: | ||
* No longer requires the 'done' callback from mocha. Expect handlers now return promises that can be resolved/rejected by mocha. | ||
Compatibility: | ||
* Node.js 4.3.2 or higher | ||
@@ -17,2 +33,3 @@ | ||
Fixed: | ||
* Documentation examples contained some errors | ||
@@ -19,0 +36,0 @@ * NPM package now smaller |
114
lib/index.js
'use strict'; | ||
var DEFAULT_TIMEOUT = 3000; // s3 | ||
function createContext( tester ) { | ||
@@ -61,2 +63,31 @@ | ||
function runHandler( tester, context, callback, reject ) { | ||
try { | ||
tester._startTime = Date.now(); | ||
tester._handler( tester._event, context, callback ); | ||
} | ||
catch( err ) { | ||
reject( err ); | ||
} | ||
} | ||
function createGetRemainingTimeInMillis( tester ) { | ||
return function() { | ||
let remaining = tester._timeout - (Date.now() - tester._startTime); | ||
if( remaining < 0 ) { | ||
remaining = 0; | ||
} | ||
return remaining; | ||
} | ||
} | ||
function addLegecyVerify( promise ) { | ||
@@ -79,7 +110,14 @@ | ||
function verifyResult( result, verifier, resolve, reject ) { | ||
function verifyResult( tester, result, verifier, resolve, reject ) { | ||
try { | ||
resolve( verifier( result ) ); | ||
let execTime = (Date.now() - tester._startTime); | ||
if( tester._enforceTimeout && (execTime >= tester._timeout) ) { | ||
throw new Error( 'handler timed out - execution time: ' + execTime + 'ms, timeout after: ' + tester._timeout + 'ms' ); | ||
} | ||
resolve( verifier( result, { execTime } ) ); | ||
} | ||
@@ -99,2 +137,4 @@ catch( err ) { | ||
this._event = {}; | ||
this._timeout = DEFAULT_TIMEOUT; | ||
} | ||
@@ -114,2 +154,10 @@ | ||
timeout( seconds ) { | ||
this._timeout = seconds * 1000; | ||
this._enforceTimeout = true; | ||
return this; | ||
} | ||
expectSucceed( resultVerifier ) { | ||
@@ -130,3 +178,6 @@ | ||
verifyResult( result, resultVerifier, resolve, reject ); | ||
// if memory is beyond, throw exception | ||
verifyResult( self, result, resultVerifier, resolve, reject ); | ||
}; | ||
@@ -142,12 +193,7 @@ | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
let callback = createFailCallback( reject ); | ||
try { | ||
self._handler( self._event, context, callback ); | ||
} | ||
catch( err ) { | ||
reject( err ); | ||
} | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
@@ -176,3 +222,3 @@ | ||
verifyResult( errResult, resultVerifier, resolve, reject ); | ||
verifyResult( self, errResult, resultVerifier, resolve, reject ); | ||
}; | ||
@@ -188,12 +234,7 @@ | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
let callback = createFailCallback( reject ); | ||
try { | ||
self._handler( self._event, context, callback ); | ||
} | ||
catch( err ) { | ||
reject( err ); | ||
} | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
@@ -220,2 +261,4 @@ | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
var callback = function( err, result ) { | ||
@@ -225,3 +268,3 @@ | ||
return verifyResult( err, resultVerifier, resolve, reject ); | ||
return verifyResult( self, err, resultVerifier, resolve, reject ); | ||
} | ||
@@ -235,10 +278,3 @@ | ||
try { | ||
self._handler( self._event, context, callback ); | ||
} | ||
catch( err ) { | ||
reject( err ); | ||
} | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
@@ -260,2 +296,4 @@ } | ||
context.getRemainingTimeInMillis = createGetRemainingTimeInMillis( self ); | ||
var callback = function( err, result ) { | ||
@@ -271,13 +309,6 @@ | ||
return verifyResult( result, resultVerifier, resolve, reject ); | ||
verifyResult( self, result, resultVerifier, resolve, reject ); | ||
} | ||
try { | ||
self._handler( self._event, context, callback ); | ||
} | ||
catch( err ) { | ||
reject( err ); | ||
} | ||
runHandler( self, context, callback, reject ); | ||
}); | ||
@@ -287,3 +318,3 @@ } | ||
function create( handler ) { | ||
function LambdaTesterModule( handler ) { | ||
@@ -298,2 +329,5 @@ if( !handler ) { | ||
module.exports = create; | ||
// Set the task root to the app's root if not already set | ||
process.env.LAMBDA_TASK_ROOT = require( 'app-root-path' ); | ||
module.exports = LambdaTesterModule; |
{ | ||
"name": "lambda-tester", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "Helps unit test AWS Lambda handlers", | ||
@@ -11,3 +11,4 @@ "main": "index.js", | ||
"mocha", | ||
"unit test" | ||
"unit test", | ||
"serverless" | ||
], | ||
@@ -32,3 +33,6 @@ "engines": { | ||
"sinon": "^1.17.3" | ||
}, | ||
"dependencies": { | ||
"app-root-path": "^1.0.0" | ||
} | ||
} |
114
README.md
@@ -12,4 +12,4 @@ [](https://travis-ci.org/vandium-io/lambda-tester) | ||
* Easily integrates with test frameworks | ||
* No external dependencies | ||
* Lightweight and won't impact performance | ||
* Maps the environment variable `LAMBDA_TASK_ROOT` to the application's root | ||
* Works with Node 4.3.2+ | ||
@@ -22,11 +22,18 @@ | ||
## Compatibility | ||
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. | ||
## Getting Started | ||
The following example shows a simple case for validating that the Lambda (handler) was called successfully: | ||
Lambda handlers with support for callbacks use the typical Node.js asynchronous signature: | ||
```js | ||
exports.handler = function( event, context, callback ) { | ||
callback( null, 'success!' ); | ||
} | ||
``` | ||
The following example shows a simple case for validating that the Lambda (handler) was called successfully (i.e. `callback( null, result )`: | ||
```js | ||
var LambdaTester = require( 'lambda-tester' ); | ||
@@ -42,3 +49,3 @@ | ||
.event( { name: 'Fred' } ) | ||
.expectSucceed(); | ||
.expectResult(); | ||
}); | ||
@@ -48,3 +55,3 @@ }); | ||
If the handler decides to call `context.fail()` or `context.done( err )` then the verification will fail and the test will fail. | ||
If the handler decides to call `callback( err )` then the verification will fail and the test will fail. | ||
@@ -64,3 +71,3 @@ Additionally, if one wanted to test for failure, then the following code would be used: | ||
.event( { name: 'Unknown' } ) | ||
.expectFail(); | ||
.expectError(); | ||
}); | ||
@@ -70,11 +77,10 @@ }); | ||
As with the "succeed" example, if the handler calls `context.succeed()` or `context.done( null, result )` then the test will fail. | ||
Please note that you must return the `LambdaTester` back to the framework since `lambda-tester` is asynchronous and uses Promises. | ||
## Verifying Success | ||
When `expectSucceed()` is called, one can pass a function to perform additional validation. For example: | ||
## Verifying Callbacks | ||
To verify that `callback( null, result )` was called: | ||
```js | ||
@@ -90,11 +96,11 @@ var LambdaTester = require( 'lambda-tester' ); | ||
it( 'test success', function() { | ||
it( 'test callback( null, result )', function() { | ||
return LambdaTester( myHandler ) | ||
.event( { name: 'Fred' } ) | ||
.expectSucceed( function( result ) { | ||
.expectResult( function( result ) { | ||
expect( result.userId ).to.exist; | ||
expect( result.user ).to.equal( 'fredsmith' ); | ||
}); | ||
expect( result.userId ).to.exist; | ||
expect( result.user ).to.equal( 'fredsmith' ); | ||
}); | ||
}); | ||
@@ -104,6 +110,4 @@ }); | ||
## Verifying Failure | ||
To verify that `callback( err )` was called: | ||
As with verifying success, `expectFail` has an optional parameter that can specify a function that will verify the error condition. For example: | ||
```js | ||
@@ -119,7 +123,7 @@ var LambdaTester = require( 'lambda-tester' ); | ||
it( 'test failure', function() { | ||
it( 'test callback( err )', function() { | ||
return LambdaTester( myHandler ) | ||
.event( { name: 'Unknown' } ) | ||
.expectFail( function( err ) { | ||
.expectError( function( err ) { | ||
@@ -132,18 +136,41 @@ expect( err.message ).to.equal( 'User not found' ); | ||
## Verifying Lambda Callbacks | ||
## Detecting Handlers than Run for Too Long | ||
On April 8, 2016 AWS Lambda introduced support for Lambda callbacks that replace the need to call `context.fail()` or `context.succeed()`. | ||
For 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. | ||
Lambda handlers with support for callbacks use the typical Node.js asynchronous signature: | ||
To use the timeout feature, specify a timeout value in seconds using `timeout()` as in the example below: | ||
```js | ||
exports.handler = function( event, context, callback ) { | ||
var LambdaTester = require( 'lambda-tester' ); | ||
callback( null, 'success!' ); | ||
} | ||
// your favorite validation tool here | ||
var expect = require( 'chai' ).expect; | ||
var myHandler = require( '../index' ).handler; | ||
describe( 'handler', function() { | ||
it( 'test callback( null, result )', function() { | ||
return LambdaTester( myHandler ) | ||
.event( { name: 'Fred' } ) | ||
.timeout( 1 /* fail if longer than 1 second */ ) | ||
.expectResult( function( result ) { | ||
expect( result.userId ).to.exist; | ||
expect( result.user ).to.equal( 'fredsmith' ); | ||
}); | ||
}); | ||
}); | ||
``` | ||
## Verifying `context.succeed()`, `context.fail` and `context.done()` | ||
To verify that `callback( null, result )` was called: | ||
On April 8, 2016 AWS Lambda introduced support for Lambda callbacks that replace the need to call `context.fail()` or `context.succeed()`. | ||
### Verifying `context.succeed()` | ||
When `expectSucceed()` is called, one can pass a function to perform additional validation. For example: | ||
```js | ||
@@ -159,11 +186,11 @@ var LambdaTester = require( 'lambda-tester' ); | ||
it( 'test callback( null, result )', function() { | ||
it( 'test success', function() { | ||
return LambdaTester( myHandler ) | ||
.event( { name: 'Fred' } ) | ||
.expectResult( function( result ) { | ||
.expectSucceed( function( result ) { | ||
expect( result.userId ).to.exist; | ||
expect( result.user ).to.equal( 'fredsmith' ); | ||
}); | ||
expect( result.userId ).to.exist; | ||
expect( result.user ).to.equal( 'fredsmith' ); | ||
}); | ||
}); | ||
@@ -173,4 +200,6 @@ }); | ||
To verify that `callback( err )` was called: | ||
### Verifying `context.fail()` | ||
As with verifying success, `expectFail` has an optional parameter that can specify a function that will verify the error condition. For example: | ||
```js | ||
@@ -186,7 +215,7 @@ var LambdaTester = require( 'lambda-tester' ); | ||
it( 'test callback( err )', function() { | ||
it( 'test failure', function() { | ||
return LambdaTester( myHandler ) | ||
.event( { name: 'Unknown' } ) | ||
.expectError( function( err ) { | ||
.expectFail( function( err ) { | ||
@@ -199,2 +228,7 @@ expect( err.message ).to.equal( 'User not found' ); | ||
### Verifying `context.done()` | ||
AWS 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. | ||
## Feedback | ||
@@ -204,2 +238,8 @@ | ||
## Compatibility | ||
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. | ||
## License | ||
@@ -206,0 +246,0 @@ |
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
17747
17.37%195
8.94%258
18.35%1
Infinity%1
Infinity%+ Added
+ Added