aws-cloudformation / custom-resource-helper

Simplify best practice Custom Resource creation, sending responses to CloudFormation and providing exception, timeout trapping, and detailed configurable logging.
Apache License 2.0
376 stars 57 forks source link

How to test Lambdas using crhelper #52

Open SchnitzelKopf opened 3 years ago

SchnitzelKopf commented 3 years ago

Sorry for this stupid question...

How do I run tests? When using cfnresponse I could simply create a standard Lambda Cloudformation TestEvent and somewhat test my lambda (besides the cfnresponse failing in the end).

When trying the same with a Lambda using crhelper I run into loads of errors as I do not want to specify a CFN Stack to send the response to. I simply want to run my code and not communicate with CFN-Stacks (as there are none so far).

Here is my sample test event which returns this error. Basically it's a createSnapshot for elastiCache, however I don't think this is relevant. The final product would be a CFN Template accessible via ServiceCatalog where customers enter their ReplicationGroupId to create a snapshot. " socket.gaierror: [Errno -2] Name or service not known[ERROR] Unexpected failure sending response to CloudFormation [Errno -2] Name or service not known "

{ "RequestType": "Create", "ResponseURL": "http://pre-signed-S3-url-for-response", "StackId": "arn:aws:cloudformation:eu-central-1:123456789012:stack/MyStack/guid", "RequestId": "unique id for this create request", "ResourceType": "Custom::TestResource", "LogicalResourceId": "MyTestResource", "ResourceProperties": { "StackName": "MyStack", "ApplicationName": "abcd", "SnapshotMode": "Create", "CacheClusterId": "", "ReplicationGroupId": "abcd-ttwoshards", "CostReference": "abc", "KmsKeyId": "abc", "SnapshotName": "mySnapshotviaLambda" } }

Thanks you for helping a newb out. If this isn't the right place to ask this question please let me know the right place to ask, or link a me docs explaining what I am tryin to achieve.

nikoizs commented 3 years ago

+1. I am encountering a similar situation where I am trying to test my custom resource lambda function locally with local-invoke, I want to be able to return a success in a local test without calling Cloudformation.

Lewenhaupt commented 2 years ago

You should be able to create a mock endpoint for the ResponseURL?

iainelder commented 2 years ago

You don't need to create a stack to test it. (And it's just as well because a broken custom resource lambda can all too easily cause CloudFormation to hang for an hour or more!)

You can do this by mocking the _send method of the CfnResource class. I described it in more detail in #54. Does it help?

Following @Lewenhaupt's suggestion, if you don't mind creating a temporary S3 bucket for the test, then you could just create a bucket and use its URL for your test requests. According to the _send_response function then it should work, but I'll admit I haven't tried this yet.

mdavis-xyz commented 1 year ago

Alternatively if you assume this library is bug-free and you want to test just your own code (e.g. you don't want the library to catch and ignore exceptions during deletion) just use a wrapper.


@helper.create
def create(event, context):
    return _create(event, context)
def _create(event, context=None):
    your code here

Then in your test:

def my_test():
    ret = _create(event)