Search code examples
typescriptaws-lambdaaws-cdkts-jest

Unit tests written for AWS CDK fail due to change in s3key hash value


I've written some unit tests for my AWS CDK inside my TS project. I'm using AWS::Lambda::Function inside my stack.

My unit test is as follows: I'm trying to see whether the directory location of the compiled code has been configured correctly with no errors.

test('is lambda code location correct',()=>{
template.hasResourceProperties("AWS::Lambda::Function",{
    Code:{
    S3Key:"d3c2479c6eb03922101251992e353c5e3f631cf5a055030bbf6cc6cab81e5198.zip"
}})
});

And I'm using aws-cdk-lib/assertions Template to test my stack.

I tried to dig a little bit before writing this test to make sure this s3Key hash won't change. Some topics indicated that this s3Key is an md5 hash of your code directory path and won't change. the problem is it did get change after a while. I'm assuming it depends on some other aspects rather than just the path.

How am I going to assert that my lambda function's location will stay intact?

My lambda configuration is as follows:

 const lambdaFunction = new lambda.Function(this, 'alb-request', {
                codeSigningConfig,
                runtime: lambda.Runtime.NODEJS_16_X,
                handler: 'index.handler',
                code: lambda.Code.fromAsset(path.join(__dirname, '../src/lambdas/alb-request/dist')),
            });

Solution

  • You are currently making a snapshot-like assertion that the code has not changed*.

    Docs: The AWS CDK generates a source hash for assets. This can be used at construction time to determine whether the contents of an asset have changed.

    To assert that the function resource's code comes from a given directory, compare the template S3Key with a DIY hash generated by the AssetStaging construct:

    test("The function's code comes from dist", () => {
      const staging = new AssetStaging(app, "Staging", {
        sourcePath: path.join(__dirname, "../src/lambdas/alb-request/dist"),
      });
    
      template.hasResourceProperties("AWS::Lambda::Function", {
        Code: { S3Key: staging.assetHash + ".zip" },
      });
    });
    

    To assert more generally that the Lambda resource has any code bundle, use stringLikeRegexp Matcher, which matches any .zip file:

    template.hasResourceProperties("AWS::Lambda::Function", {
      Code: { S3Key: Match.stringLikeRegexp(".*.zip$") },
    });
    

    * The code directory path is not considered in the hash calculation: identical code at two paths will produce the same .zip file name.