Each Lambda function is small, you may not feel the need to write many tests. It’s worth it to write them anyways, you never know what modifications you’ll want to make in the future. Emulambda provides a CLI harness to test your Python functions and profile their resource usage.
Let’s make a Python function and try benchmarking it and calculate costs. Beyond cost planning, I would use Emulambda to test functions that do a lot of parsing of event data, or are invoked in more than one context.
Note: emulambda does not currently support Windows, but can be used if you
comment out the usage of the signal
and resource
modules.
Install Emulambda
If you want to keep your Emulambda setup separate from your system packages, or if your OS doesn’t use Python 2.7 as the default, create a new virtualenv or use pipsi. For this function, we’ll only require Python 2.7 so there won’t be any dependencies other than emulambda.
pip install git+https://github.com/fugue/emulambda.git
Now that it’s installed, make sure the executable is accessible from your shell
by running emulambda
. You should see something like this:
usage: emulambda [-h] [-s] [-t TIMEOUT] [-v] lambdapath eventfile
emulambda: error: too few arguments
Great, now we can test some code.
Test Lambda Function
Our simple function will just make an HTTP request to the AWS Lambda homepage and check to make sure Lambda still doesn’t need any servers.
import urllib2
def lambda_handler(event, context):
print "Hello, AWS Lambda"
lambda_home = urllib2.urlopen("https://aws.amazon.com/lambda/")
if "No Servers" in lambda_home.read():
print "Yay, no servers"
Save the function as test_event.py
on your local machine. Normally, functions
will include libraries, or at least more code, but that’s not the point of this
demo.
Test Event Data
To run our test, we need to provide an event for it to react to. The simplest
kind of event is a scheduled invocation, so let’s make a test event and save it
as test-event.json
.
{
"account": "123456789012",
"region": "us-east-1",
"detail": {},
"detail-type": "Scheduled Event",
"source": "aws.events",
"time": "1970-01-01T00:00:00Z",
"id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c",
"resources": [
"arn:aws:events:us-east-1:123456789012:rule/my-schedule"
]
}
You can find other example events in the Lambda console by configuring the test event for your function.
Running the Test
When we run the test, emulambda
will be:
- Loading the code in the
lambda_handler
function. - Parsing the provided test JSON.
- Running the function with the input(s) given.
- Printing resource usage.
Run the test by supplying the import path for the Lambda function and the test data.
$ emulambda -v test_event.lambda_handler test-event.json
Hello, AWS Lambda
Yay, no servers
Executed test_event.lambda_handler
Estimated...
...execution clock time: 882ms (900ms billing bucket)
...execution peak RSS memory: 3K (3496 bytes)
----------------------RESULT----------------------
None
Since the code does so little, we can choose to use the smallest Lambda environment, which gives us 128 MB of memory for just 208 nanodollars (0.000000208 USD) per 100 milliseconds. Scaled up, this is 2.08 microdollars per second.
Our function takes 882 milliseconds to run, so we would be billed for 900ms of compute time since Lambda rounds to the next 100ms. Each run costs 1.872 microdollars, meaning for three dollars (the price of a fancy coffee) our test function can run 534,188 times.
Recap
In this post, we’ve seen how to supply events to Lambda functions for local testing, review the memory usage and runtime of our functions, and predict how much they will cost to run.
If you want to hear more about testing Lambda functions, have other questions, or know of a cool project that uses AWS Lambda, drop me a line at ryan@serverlesscode.com or keep up via RSS.