Skip to content

Commit

Permalink
Merge branch 'develop' into improv/init-samples
Browse files Browse the repository at this point in the history
* develop:
  docs: Fix @mhart link in README (aws#562)
  docs: Change jest to mocha in Nodejs init README (aws#564)
  docs: Fix syntax highlighting in README.md (aws#561)
  fix: spacing typo in Log statement in start-lambda (aws#559)
  fix: Functional tests must run on localhost to work in Windows (aws#552)
  docs: Adding readme for "sam logs" and "sam local start-lambda" command (aws#557)
  docs: Accessibility and help text changes (aws#554)
  chore: Preparing for release - v0.5.0 (aws#553)
  feat(LocalLambdaService): Integ test for start-lambda command (aws#550)
  • Loading branch information
heitorlessa committed Jul 21, 2018
2 parents 1d96859 + 5da4174 commit 6b0469d
Show file tree
Hide file tree
Showing 25 changed files with 541 additions and 140 deletions.
199 changes: 180 additions & 19 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fellow community members and the AWS SAM team.
written with `AWS Serverless Application Model
(SAM) <https://github.com/awslabs/serverless-application-model>`__. SAM
CLI can be used to test functions locally, start a local API Gateway
from a SAM template, validate a SAM template, generate sample payloads
from a SAM template, validate a SAM template, fetch logs, generate sample payloads
for various event sources, and generate a SAM project in your favorite
Lambda Runtime.

Expand All @@ -35,13 +35,14 @@ Lambda Runtime.
- `Usage <#usage>`__

- `Invoke functions locally <#invoke-functions-locally>`__
- `Run automated tests for your Lambda functions locally <#run-automated-tests-for-your-lambda-functions-locally>`__
- `Generate sample event source
payloads <#generate-sample-event-source-payloads>`__
- `Run API Gateway locally <#run-api-gateway-locally>`__
- `Debugging Applications <#debugging-applications>`__

- `Debugging Python functions <#debugging-python-functions>`__

- `Fetch, tail, and filter Lambda function logs <#fetch-tail-and-filter-lambda-function-logs>`__
- `Validate SAM templates <#validate-sam-templates>`__
- `Package and Deploy to
Lambda <#package-and-deploy-to-lambda>`__
Expand Down Expand Up @@ -216,6 +217,99 @@ an event too.
# For more options
$ sam local invoke --help
Run automated tests for your Lambda functions locally
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can use the ``sam local invoke`` command to manually test your code
by running Lambda function locally. With SAM CLI, you can easily
author automated integration tests by
first running tests against local Lambda functions before deploying to the
cloud. The ``sam local start-lambda`` command starts a local
endpoint that emulates the AWS Lambda service’s invoke endpoint, and you
can invoke it from your automated tests. Because this endpoint emulates
the Lambda service's invoke endpoint, you can write tests once and run
them (without any modifications) against the local Lambda function or
against a deployed Lambda function. You can also run the same tests
against a deployed SAM stack in your CI/CD pipeline.

Here is how this works:

**1. Start the Local Lambda Endpoint**

Start the local Lambda endpoint by running the following command in the directory that contains your AWS
SAM template:

.. code:: bash
sam local start-lambda
This command starts a local endpoint at http://127.0.0.1:3001 that
emulates the AWS Lambda service, and you can run your automated tests
against this local Lambda endpoint. When you send an invoke to this
endpoint using the AWS CLI or SDK, it will locally execute the Lambda
function specified in the request and return a response.

**2. Run integration test against local Lambda endpoint**

In your integration test, you can use AWS SDK to invoke your Lambda function
with test data, wait for response, and assert that the response what you
expect. To run the integration test locally, you should configure AWS
SDK to send Lambda Invoke API call to local Lambda endpoint started in
previous step.

Here is an Python example (AWS SDK for other languages have similar
configurations):

.. code:: python
import boto3
# Set "running_locally" flag if you are running the integration test locally
if running_locally:
# Create Lambda SDK client to connect to appropriate Lambda endpoint
lambda_client = boto3.client('lambda',
endpoint_url="http://127.0.0.1:3001",
use_ssl=False,
verify=False,
config=Config(signature_version=UNSIGNED,
read_timeout=0,
retries={'max_attempts': 0}))
else:
lambda_client = boto3.client('lambda')
# Invoke your Lambda function as you normally usually do. The function will run
# locally if it is configured to do so
response = lambda_client.invoke(FunctionName="HelloWorldFunction")
# Verify the response
assert response == "Hello World"
This code can run without modifications against a Lambda function which
is deployed. To do so, set the ``running_locally`` flag to ``False`` .
This will setup AWS SDK to connect to AWS Lambda service on the cloud.

Connecting to docker network
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Both ``sam local invoke`` and ``sam local start-api`` support connecting
the create lambda docker containers to an existing docker network.

To connect the containers to an existing docker network, you can use the
``--docker-network`` command-line argument or the ``SAM_DOCKER_NETWORK``
environment variable along with the name or id of the docker network you
wish to connect to.

.. code:: bash
# Invoke a function locally and connect to a docker network
$ sam local invoke --docker-network my-custom-network <function logical id>
# Start local API Gateway and connect all containers to a docker network
$ sam local start-api --docker-network b91847306671 -d 5858
Generate sample event source payloads
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -348,7 +442,7 @@ Visual Studio Code:
In order to setup Visual Studio Code for debugging with AWS SAM CLI, use
the following launch configuration:

::
.. code:: json
{
"version": "0.2.0",
Expand Down Expand Up @@ -416,24 +510,91 @@ specified. In this case, your full SAM CLI command would be:
You may pass debugger arguments to functions of all runtimes.

Connecting to docker network
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To simplify troubleshooting, we added a new command called ``sam logs``
to SAM CLI. ``sam logs`` lets you fetch logs generated by your Lambda
function from the command line. In addition to printing the logs on the
terminal, this command has several nifty features to help you quickly
find the bug. Note: This command works for all AWS Lambda functions; not
just the ones you deploy using SAM.

Both ``sam local invoke`` and ``sam local start-api`` support connecting
the create lambda docker containers to an existing docker network.
Fetch, tail, and filter Lambda function logs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To simplify troubleshooting, SAM CLI has a command called ``sam logs``.
``sam logs`` lets you fetch logs generated by your Lambda
function from the command line. In addition to printing the logs on the
terminal, this command has several nifty features to help you quickly
find the bug.

To connect the containers to an existing docker network, you can use the
``--docker-network`` command-line argument or the ``SAM_DOCKER_NETWORK``
environment variable along with the name or id of the docker network you
wish to connect to.
Note: This command works for all AWS Lambda functions; not
just the ones you deploy using SAM.

**Basic Usage: Using CloudFormation Stack**

When your function is a part
of a CloudFormation stack, you can fetch logs using the function's
LogicalID:

.. code:: bash
# Invoke a function locally and connect to a docker network
$ sam local invoke --docker-network my-custom-network <function logical id>
sam logs -n HelloWorldFunction --stack-name mystack
# Start local API Gateway and connect all containers to a docker network
$ sam local start-api --docker-network b91847306671 -d 5858
**Basic Usage: Using Lambda Function name**

Or, you can fetch logs using the function's name

.. code:: bash
sam logs -n mystack-HelloWorldFunction-1FJ8PD
**Tail Logs**

Add ``--tail`` option to wait for new logs and see them as
they arrive. This is very handy during deployment or when
troubleshooting a production issue.

.. code:: bash
sam logs -n HelloWorldFunction --stack-name mystack --tail
**View logs for specific time range**
You can view logs for specific time range using the ``-s`` and ``-e`` options

.. code:: bash
sam logs -n HelloWorldFunction --stack-name mystack -s '10min ago' -e '2min ago'
**Filter Logs**

Use the ``--filter`` option to quickly find logs that
match terms, phrases or values in your log events

.. code:: bash
sam logs -n HelloWorldFunction --stack-name mystack --filter "error"
In the output, SAM CLI will underline all occurrences of the word
“error” so you can easily locate the filter keyword within the log
output.

**Error Highlighting**

When your Lambda function crashes or times out,
SAM CLI will highlight the timeout message in red. This will help you
easily locate specific executions that are timing out within a giant
stream of log output.

.. figure:: https://user-images.githubusercontent.com/22755571/42301038-3363a366-7fc8-11e8-9d0e-308b209cb92b.png
:alt: SAM CLI Logs Error Highlighting


**JSON pretty printing**

If your log messages print JSON strings, SAM
CLI will automatically pretty print the JSON to help you visually parse
and understand the JSON.

.. figure:: https://user-images.githubusercontent.com/22755571/42301064-50c6cffa-7fc8-11e8-8f31-04ef117a9c5a.png
:alt: SAM CLI Logs JSON Pretty Print

Validate SAM templates
~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -500,7 +661,7 @@ in your SAM template.

For example:

::
.. code:: yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Expand All @@ -517,7 +678,7 @@ You should then build your JAR file using your normal build process.
Please note that JAR files used with AWS Lambda should be a shaded JAR
file (or uber jar) containing all of the function dependencies.

::
.. code:: bash
// Build the JAR file
$ mvn package shade:shade
Expand Down Expand Up @@ -575,7 +736,7 @@ In order to test API Gateway with a non-default profile from your AWS
credentials file append ``--profile <profile name>`` to the
``start-api`` command:

::
.. code:: bash
// Test API Gateway locally with a credential profile.
$ sam local start-api --profile some_profile
Expand Down Expand Up @@ -851,7 +1012,7 @@ A special thank you

SAM CLI uses the open source
`docker-lambda <https://github.com/lambci/docker-lambda>`__ Docker
images created by [@mhart](https://github.com/mhart).
images created by `@mhart <https://github.com/mhart>`__.


.. raw:: html
Expand Down
2 changes: 1 addition & 1 deletion samcli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
SAM CLI version
"""

__version__ = '0.4.0'
__version__ = '0.5.0'
6 changes: 3 additions & 3 deletions samcli/cli/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def callback(ctx, param, value):
expose_value=False,
is_flag=True,
envvar="SAM_DEBUG",
help='Turn on debug logging',
help='Turn on debug logging to print debug message generated by SAM CLI.',
callback=callback)(f)


Expand All @@ -40,7 +40,7 @@ def callback(ctx, param, value):

return click.option('--region',
expose_value=False,
help='Set the AWS Region of the service',
help='Set the AWS Region of the service (e.g. us-east-1).',
callback=callback)(f)


Expand All @@ -57,5 +57,5 @@ def callback(ctx, param, value):

return click.option('--profile',
expose_value=False,
help='Select a specific profile from your credential file to get AWS credentials',
help='Select a specific profile from your credential file to get AWS credentials.',
callback=callback)(f)
10 changes: 5 additions & 5 deletions samcli/commands/local/cli_common/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def invoke_common_options(f):
envvar="SAM_DEBUG_PORT"),

click.option('--debug-args',
help="Additional arguments to be passed to the debugger",
help="Additional arguments to be passed to the debugger.",
envvar="DEBUGGER_ARGS"),

click.option('--docker-volume-basedir', '-v',
Expand All @@ -120,16 +120,16 @@ def invoke_common_options(f):

click.option('--docker-network',
envvar="SAM_DOCKER_NETWORK",
help="Specifies the name or id of an existing docker network to lambda docker"
"containers should connect to, along with the default bridge network. If not specified,"
help="Specifies the name or id of an existing docker network to lambda docker "
"containers should connect to, along with the default bridge network. If not specified, "
"the Lambda containers will only connect to the default bridge docker network."),

click.option('--log-file', '-l',
help="logfile to send runtime logs to"),
help="logfile to send runtime logs to."),

click.option('--skip-pull-image',
is_flag=True,
help="Specify whether CLI should skip pulling down the latest Docker image for Lambda runtime",
help="Specify whether CLI should skip pulling down the latest Docker image for Lambda runtime.",
envvar="SAM_SKIP_PULL_IMAGE"),

click.option('--profile',
Expand Down
20 changes: 10 additions & 10 deletions samcli/commands/local/generate_event/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@


HELP_TEXT = """
Generate a Lambda Event that can be used to invoke a Lambda Function.
Useful for developing serverless functions that handle asynchronous events (such as S3/Kinesis etc), or if you want to
compose a script of test cases. Event body can be passed in either by stdin (default), or by using the --event
parameter. Runtime output (logs etc) will be outputted to stderr, and the Lambda function result will be outputted to
stdout.
You can use this command to generate sample payloads from different event sources
such as S3, API Gateway, and SNS. These payloads contain the information that the
event sources send to your Lambda functions.\n
\b
Generate the event that S3 sends to your Lambda function when a new object is uploaded
$ sam local generate-event s3 --bucket <bucket> --key <key>\n
\b
After you generate a sample event, you can use it to test your Lambda function locally
$ sam local generate-event s3 --bucket <bucket> --key <key> | sam local invoke <function logical id>
"""


@click.group("generate-event")
@click.group("generate-event", help=HELP_TEXT)
def cli():
"""
Generate an event
"""
pass # pragma: no cover


Expand Down
17 changes: 10 additions & 7 deletions samcli/commands/local/invoke/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@


HELP_TEXT = """
Invokes a local Lambda function once and quits after invocation completes.
Useful for developing serverless functions that handle asynchronous events (such as S3/Kinesis etc), or if you want to
compose a script of test cases. Event body can be passed in either by stdin (default), or by using the --event
parameter. Runtime output (logs etc) will be outputted to stderr, and the Lambda function result will be outputted to
stdout.
You can use this command to execute your function in a Lambda-like environment locally.
You can pass in the event body via stdin or by using the -e (--event) parameter.
Logs from the Lambda function will be output via stdout.\n
\b
Invoking a Lambda function using an event file
$ sam local invoke "HelloWorldFunction" -e event.json\n
\b
Invoking a Lambda function using input from stdin
$ echo '{"message": "Hey, are you there?" }' | sam local invoke "HelloWorldFunction" \n
"""


@click.command("invoke", help=HELP_TEXT, short_help="Invokes a local Lambda function once")
@click.command("invoke", help=HELP_TEXT, short_help="Invokes a local Lambda function once.")
@click.option("--event", '-e',
type=click.Path(),
default="-", # Defaults to stdin
Expand Down
Loading

0 comments on commit 6b0469d

Please sign in to comment.