aws / aws-lambda-dotnet

Libraries, samples and tools to help .NET Core developers develop AWS Lambda functions.
Apache License 2.0
1.58k stars 478 forks source link

Mimic lambda lifecycle in Lambda Test Tool #1247

Open avalara-stephen-hickey opened 2 years ago

avalara-stephen-hickey commented 2 years ago

Describe the feature

Currently, the Lambda Test Tool re-creates instances of a lambda every time the lambda function is invoked. I would expect that a lambda would be instantiated once and re-used for some configurable amount of time, similar to how it is hosted in AWS (FunctionInit).

In the following code sample, if I use the Lambda Test Tool to execute the function twice in quick succession, I would expect the results to look like:

First execution: "1, 1"
Second execution: "2, 1"

and for more consecutive executions to continue to increment the first number. Instead, the actual results look like:

First execution: "1, 1"
Second execution: "1, 1"

Example:

using Amazon.Lambda.Core;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace MyLambda;

public class Function
{
    private readonly Test _test;

    public Function()
    {
        var constructorInjected = new ConstructorInjected();
        _test = new Test(constructorInjected);
    }

    public string FunctionHandler(ILambdaContext context)
    {
        var functionInjected = new FunctionInjected();
        return _test.InjectionTest(functionInjected);
    }
}

public interface IConstructorInjected { public int Inc(); }

public class ConstructorInjected : IConstructorInjected
{
    private int _num;

    public int Inc() => ++_num;
}

public interface IFunctionInjected { public int Inc(); }

public class FunctionInjected : IFunctionInjected
{
    private int _num;

    public int Inc() => ++_num;
}

public class Test
{
    private readonly IConstructorInjected _constructorInjected;

    public Test(IConstructorInjected constructorInjected)
    {
        _constructorInjected = constructorInjected;
    }

    public string InjectionTest(IFunctionInjected functionInjected) =>
        $"{_constructorInjected.Inc()}, {functionInjected.Inc()}";
}
{
  "profile": "",
  "region": "",
  "configuration": "Release",
  "function-runtime": "dotnet6",
  "function-memory-size": 256,
  "function-timeout": 30,
  "function-handler": "MyLambda::MyLambda.Function::FunctionHandler"
}

Use Case

For testing lifetime management of objects in lambas, I need to be able to have the lambda last longer than a single execution in the test environment. This would mimic the lifecycle of a lambda in AWS.

Proposed Solution

A configuration entry in the configuration file (aws-lambda-tools-defaults.json) to configure the lifetime of a lambda.

{
  "lambda-lifetime": "0.00:00:30"
}

or if managing the life-cycle is too difficult, even just a setting to persist the lambda for the lifetime of the test tool.

{
  "persist-lambda": true
}

If this is already a feature, some documentation about the lifetime of a lambda in the test tool and how it differs from the lifetime in AWS (if at all) would be great.

Other Information

No response

Acknowledgements

AWS .NET SDK and/or Package version used

dotnet tools: amazon.lambda.testtool-6.0 0.12.3

NuGet packages Amazon.Lambda.Core 2.1.0 Amazon.Lambda.Serialization.SystemTextJson 2.3.0

Targeted .NET Platform

.NET 6

Operating System and version

Windows 10

avalara-stephen-hickey commented 2 years ago

I realized I should greatly simplify the example, I had leftovers from when I was playing around with object lifetimes.

using Amazon.Lambda.Core;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace MyLambda;

public class Function
{
    private int _num;

    public string FunctionHandler(ILambdaContext context) => $"{++_num}";
}

Expected output:

First execution: "1"
Second execution: "2"

Actual output

First execution: "1"
Second execution: "1"
ashishdhingra commented 2 years ago

Not sure if it's feasible since Lambda Test Tool only allows to test the function logic. Needs review by the team.