aws / aws-lambda-dotnet

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

Lambda Test Tool using wrong directory to find configuration JSON files #1482

Open BradKnowles opened 1 year ago

BradKnowles commented 1 year ago

Describe the bug

When using Microsoft.Extensions.Configuration.Json version 7.0.0 and specifying a path for a JSON file, like so

var logConfig = new ConfigurationBuilder()
    .AddJsonFile("logging.json")
    .Build();

logging.json is not found, even when present in the output directory.

Instead of searching ..\bin\Debug\net6.0\logging.json it uses %USERPROFILE%\.dotnet\tools\.store\amazon.lambda.testtool-6.0\0.13.0\amazon.lambda.testtool-6.0\0.13.0\tools\net6.0\any\logging.json.

If specifying appsettings.json in the AddJsonFile() method, the appsettings.json file from the Mock Lambda Test tool is injected into logConfig instead of the one supplied with the Lambda project.

Expected Behavior

I expect logging.json to be parsed from ..\bin\Debug\net6.0\logging.json and become part of the logConfig configuration as mentioned above.

Current Behavior

logging.json is serached for in %USERPROFILE%\.dotnet\tools\.store\amazon.lambda.testtool-6.0\0.13.0\amazon.lambda.testtool-6.0\0.13.0\tools\net6.0\any\logging.json, is not found, and logConfig remains empty.

Reproduction Steps

This will throw an exception saying it can't find logging.json, which is correct since we didn't add the file. However, the error message will show the path it tried to search for the file. Instead of searching ..\AWSLambda1\AWSLambda1\bin\Debug\net6.0\logging.json it uses %USERPROFILE%\.dotnet\tools\.store\amazon.lambda.testtool-6.0\0.13.0\amazon.lambda.testtool-6.0\0.13.0\tools\net6.0\any\logging.json.

Possible Solution

I believe the issue might be in this area. Even though AppBaseCompilationAssemblyResolver(Path.GetDirectoryName(rootAssemblyPath)) uses the correct directory, debugging into .NET source shows that DependencyContext of the assemblyResolver points to the wrong location. This is still a educated guess though, I wasn't able to dig too much further as of yet.

https://github.com/aws/aws-lambda-dotnet/blob/630d1d38e9e51399110aba87aca4bf0e83075efd/Tools/LambdaTestTool/src/Amazon.Lambda.TestTool/Runtime/LambdaAssemblyLoadContext.cs#L124-L130

Additional Information/Context

A workaround does exist. Adding .SetBasePath(Environment.CurrentDirectory) to the ConfigurationBuilder will cause the configuration system to use the correct path.

AWS .NET SDK and/or Package version used

<PackageReference Include="Amazon.Lambda.Core" Version="2.1.0" /> <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.3.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />

Targeted .NET Platform

.NET 6

Operating System and version

Windows 10

ashishdhingra commented 1 year ago

Hi @BradKnowles,

Good morning. Thanks for reporting the issue.

The root path for the file provider used by new ConfigurationBuilder() is the path of the current executing assembly. When using Lambda Test Tool, since Visual Studio is actually executing the Lambda Test tool, this is the path of the test tool, not the path of the current project assembly. Lambda Test Tool loads the current project assemblies using reflection to enable testing Lambda functions using the tool. You could use the workaround .SetBasePath(Environment.CurrentDirectory) as you suggested in combination with the #if DEBUG preprocessor directive. The reason that the Environment.CurrentDirectory would work is that the when Lambda test tool is launched, the current directory is set as the root of the project assemblies.

Thanks, Ashish

BradKnowles commented 1 year ago

I was doing some more testing and everything works correctly if the project is made from the Lambda ASP.NET Core Web API (AWS) blueprint. Is it somehow hosted differently?

ashishdhingra commented 1 year ago

I was doing some more testing and everything works correctly if the project is made from the Lambda ASP.NET Core Web API (AWS) blueprint. Is it somehow hosted differently?

@BradKnowles The project created from Lambda ASP.NET Core Web API (AWS) blueprint is by default executed (debugged) using the built in IIS Express (Kestrel) server. Hence it works fine. Although you could use Lambda Test Tool and use API Gateway sample requests, test tool is better used while testing simple Lambda functions.

Thanks, Ashish

github-actions[bot] commented 1 year ago

This issue has not received a response in 5 days. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled.

normj commented 1 year ago

@ashishdhingra I asked @BradKnowles to submit this. The problem is the test tool's process has its current working directory set to where it was executed so if the Lambda function is looking for files relative to its location thinking that is where the current working directory is then it will fail. We need to make sure before we call the function that we change the Lambda test tool process's current working directory to the location of the Lambda function so the behavior will be the same as it is in the real Lambda service.

BradKnowles commented 1 week ago

Is there any more help I can provide in tracking this down?