From be90d7435dd7ab7851f5712d5659eecf4174a779 Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 7 Apr 2026 11:03:04 -0400 Subject: [PATCH 01/10] commit 1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 405e952a5..37f6a1d3e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# AWS Lambda for .NET +# AWS Lambda for .NET (Draft) Repository for the AWS NuGet packages and Blueprints to support writing AWS Lambda functions using .NET Core. From c3a8e84001ae391cbc66455a867d790d98c01839 Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 7 Apr 2026 11:57:53 -0400 Subject: [PATCH 02/10] commit 2 --- .../Helpers/TestHelpers.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.Tests.Common/Helpers/TestHelpers.cs b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.Tests.Common/Helpers/TestHelpers.cs index 79c618d48..9def24fe2 100644 --- a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.Tests.Common/Helpers/TestHelpers.cs +++ b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.Tests.Common/Helpers/TestHelpers.cs @@ -1,6 +1,9 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +using System.Net; +using System.Net.Sockets; + namespace Amazon.Lambda.TestTool.Tests.Common.Helpers; public static class TestHelpers @@ -39,16 +42,22 @@ public static async Task SendRequest(string url) } } - private static int _maxLambdaRuntimePort = 6000; - private static int _maxApiGatewayPort = 9000; + private static int GetFreePort() + { + var listener = new TcpListener(IPAddress.Loopback, 0); + listener.Start(); + var port = ((IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + return port; + } public static int GetNextLambdaRuntimePort() { - return Interlocked.Increment(ref _maxLambdaRuntimePort); + return GetFreePort(); } public static int GetNextApiGatewayPort() { - return Interlocked.Increment(ref _maxApiGatewayPort); + return GetFreePort(); } } From 288e4cafbfc9e05040b18d727a07ec05841641cb Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 7 Apr 2026 12:16:37 -0400 Subject: [PATCH 03/10] commit 3 --- .../SQSEventSourceTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/SQSEventSourceTests.cs b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/SQSEventSourceTests.cs index fc4aa1882..f02ee3abe 100644 --- a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/SQSEventSourceTests.cs +++ b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/SQSEventSourceTests.cs @@ -183,7 +183,7 @@ public async Task ProcessMessagesFromMultipleEventSources() await sqsClient.SendMessageAsync(queueUrl2, "MessageFromQueue2"); var startTime = DateTime.UtcNow; - while (listOfProcessedMessages.Count == 0 && DateTime.UtcNow < startTime.AddMinutes(2)) + while (listOfProcessedMessages.Count < 2 && DateTime.UtcNow < startTime.AddMinutes(2)) { Assert.False(lambdaTask.IsFaulted, "Lambda function failed: " + lambdaTask.Exception?.ToString()); await Task.Delay(500); From 237525df5798ff1a9e73b080f330fff2d376e358 Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 7 Apr 2026 12:42:00 -0400 Subject: [PATCH 04/10] commit 4 --- .../LambdaBootstrapTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs index e1636ff16..97b40cb60 100644 --- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs @@ -165,7 +165,7 @@ public async Task TraceIdEnvironmentVariableIsSet() [Fact] public async Task HandlerThrowsException() { - using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerThrowsAsync, null)) + using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerThrowsAsync, null, null, _environmentVariables)) { bootstrap.Client = _testRuntimeApiClient; Assert.Null(_environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarTraceId)); @@ -183,7 +183,7 @@ public async Task HandlerInputAndOutputWork() { const string testInput = "a MiXeD cAsE sTrInG"; - using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerToUpperAsync, null)) + using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerToUpperAsync, null, null, _environmentVariables)) { _testRuntimeApiClient.FunctionInput = Encoding.UTF8.GetBytes(testInput); bootstrap.Client = _testRuntimeApiClient; @@ -201,7 +201,7 @@ public async Task HandlerInputAndOutputWork() [Fact] public async Task HandlerReturnsNull() { - using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerReturnsNullAsync, null)) + using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerReturnsNullAsync, null, null, _environmentVariables)) { _testRuntimeApiClient.FunctionInput = new byte[0]; bootstrap.Client = _testRuntimeApiClient; From 7eefe550d78e24993556b2ee4880fbea99890bc1 Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 7 Apr 2026 14:55:49 -0400 Subject: [PATCH 05/10] commit 5 --- .../BaseApiGatewayTest.cs | 1 + .../tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/BaseApiGatewayTest.cs b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/BaseApiGatewayTest.cs index f277ffa2a..c9998141c 100644 --- a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/BaseApiGatewayTest.cs +++ b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/BaseApiGatewayTest.cs @@ -48,6 +48,7 @@ protected async Task CleanupAsync() CancellationTokenSource.Dispose(); CancellationTokenSource = new CancellationTokenSource(); } + Environment.SetEnvironmentVariable("APIGATEWAY_EMULATOR_ROUTE_CONFIG", null); } protected async Task StartTestToolProcessAsync(ApiGatewayEmulatorMode apiGatewayMode, string routeName, int lambdaPort, int apiGatewayPort, CancellationTokenSource cancellationTokenSource, string httpMethod = "POST") diff --git a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs index 998460411..8fe4024be 100644 --- a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs +++ b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs @@ -32,7 +32,7 @@ public async Task AddEventToDataStore() var lambdaPort = TestHelpers.GetNextLambdaRuntimePort(); var cancellationTokenSource = new CancellationTokenSource(); - cancellationTokenSource.CancelAfter(15_000); + cancellationTokenSource.CancelAfter(60_000); var options = new RunCommandSettings(); options.LambdaEmulatorPort = lambdaPort; Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); @@ -85,7 +85,7 @@ public async Task InvokeRequestResponse() var lambdaPort = TestHelpers.GetNextLambdaRuntimePort(); var cancellationTokenSource = new CancellationTokenSource(); - cancellationTokenSource.CancelAfter(15_000); + cancellationTokenSource.CancelAfter(60_000); var options = new RunCommandSettings(); options.LambdaEmulatorPort = lambdaPort; Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); From 9c5a454e92f5159ee9a29d43c539e71bc44a8031 Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 7 Apr 2026 15:09:43 -0400 Subject: [PATCH 06/10] commit 6 --- .../Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs index 8fe4024be..cb2afa01a 100644 --- a/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs +++ b/Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs @@ -32,13 +32,15 @@ public async Task AddEventToDataStore() var lambdaPort = TestHelpers.GetNextLambdaRuntimePort(); var cancellationTokenSource = new CancellationTokenSource(); - cancellationTokenSource.CancelAfter(60_000); + cancellationTokenSource.CancelAfter(15_000); var options = new RunCommandSettings(); options.LambdaEmulatorPort = lambdaPort; Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); var testToolProcess = TestToolProcess.Startup(options, cancellationTokenSource.Token); try { + Assert.True(await TestHelpers.WaitForApiToStartAsync($"{testToolProcess.ServiceUrl}/lambda-runtime-api/healthcheck")); + var lambdaClient = ConstructLambdaServiceClient(testToolProcess.ServiceUrl); var invokeFunction = new InvokeRequest { @@ -85,13 +87,15 @@ public async Task InvokeRequestResponse() var lambdaPort = TestHelpers.GetNextLambdaRuntimePort(); var cancellationTokenSource = new CancellationTokenSource(); - cancellationTokenSource.CancelAfter(60_000); + cancellationTokenSource.CancelAfter(15_000); var options = new RunCommandSettings(); options.LambdaEmulatorPort = lambdaPort; Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); var testToolProcess = TestToolProcess.Startup(options, cancellationTokenSource.Token); try { + Assert.True(await TestHelpers.WaitForApiToStartAsync($"{testToolProcess.ServiceUrl}/lambda-runtime-api/healthcheck")); + var handler = (string input, ILambdaContext context) => { Thread.Sleep(1000); // Add a sleep to prove the LambdaRuntimeApi waited for the completion. From 1daf3859c5439d3caeeef85d6ea820ffbde07a67 Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Tue, 7 Apr 2026 16:32:36 -0400 Subject: [PATCH 07/10] commit 7 --- .../Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs index 80f9d13d0..bb4fd93a1 100644 --- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs @@ -250,7 +250,7 @@ private async Task TestHandlerFailAsync(string handler, string expect var userCodeLoader = new UserCodeLoader(new SystemEnvironmentVariables(), handler, _internalLogger); var initializer = new UserCodeInitializer(userCodeLoader, _internalLogger); var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke); - var bootstrap = new LambdaBootstrap(handlerWrapper, initializer.InitializeAsync) + var bootstrap = new LambdaBootstrap(handlerWrapper.Handler, initializer.InitializeAsync, null, _environmentVariables) { Client = testRuntimeApiClient }; @@ -388,7 +388,7 @@ private async Task ExecHandlerAsync(string handler, string dataIn var userCodeLoader = new UserCodeLoader(new SystemEnvironmentVariables(), handler, _internalLogger); var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke); var initializer = new UserCodeInitializer(userCodeLoader, _internalLogger); - var bootstrap = new LambdaBootstrap(handlerWrapper, initializer.InitializeAsync) + var bootstrap = new LambdaBootstrap(handlerWrapper.Handler, initializer.InitializeAsync, null, _environmentVariables) { Client = testRuntimeApiClient }; From f850dce08247bffe1e651af6ccf6a6a7c0851d9d Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Wed, 8 Apr 2026 12:40:02 -0400 Subject: [PATCH 08/10] commit 8 --- .../Amazon.Lambda.TestTool/TestToolStartup.cs | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Tools/LambdaTestTool/src/Amazon.Lambda.TestTool/TestToolStartup.cs b/Tools/LambdaTestTool/src/Amazon.Lambda.TestTool/TestToolStartup.cs index 9693d64e4..87353be34 100644 --- a/Tools/LambdaTestTool/src/Amazon.Lambda.TestTool/TestToolStartup.cs +++ b/Tools/LambdaTestTool/src/Amazon.Lambda.TestTool/TestToolStartup.cs @@ -10,7 +10,6 @@ namespace Amazon.Lambda.TestTool { public class TestToolStartup { - private static bool shouldDisableLogs; public class RunConfiguration { @@ -37,7 +36,7 @@ public static void Startup(string productName, Action try { var commandOptions = CommandLineOptions.Parse(args); - shouldDisableLogs = Utils.ShouldDisableLogs(commandOptions); + var shouldDisableLogs = Utils.ShouldDisableLogs(commandOptions); if (!shouldDisableLogs) Utils.PrintToolTitle(productName); @@ -76,7 +75,7 @@ public static void Startup(string productName, Action if (commandOptions.NoUI) { - ExecuteWithNoUi(localLambdaOptions, commandOptions, lambdaAssemblyDirectory, runConfiguration); + ExecuteWithNoUi(localLambdaOptions, commandOptions, lambdaAssemblyDirectory, runConfiguration, shouldDisableLogs); } else { @@ -118,16 +117,16 @@ public static void Startup(string productName, Action } - public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, RunConfiguration runConfiguration) + public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs) { if (!shouldDisableLogs) runConfiguration.OutputWriter.WriteLine("Executing Lambda function without web interface"); var lambdaProjectDirectory = Utils.FindLambdaProjectDirectory(lambdaAssemblyDirectory); - string configFile = DetermineConfigFile(commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory); - LambdaConfigInfo configInfo = LoadLambdaConfigInfo(configFile, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration); - LambdaFunction lambdaFunction = LoadLambdaFunction(configInfo, localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration); + string configFile = DetermineConfigFile(commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, shouldDisableLogs: shouldDisableLogs); + LambdaConfigInfo configInfo = LoadLambdaConfigInfo(configFile, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration, shouldDisableLogs: shouldDisableLogs); + LambdaFunction lambdaFunction = LoadLambdaFunction(configInfo, localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration, shouldDisableLogs: shouldDisableLogs); - string payload = DeterminePayload(localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration); + string payload = DeterminePayload(localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration, shouldDisableLogs: shouldDisableLogs); var awsProfile = commandOptions.AWSProfile ?? configInfo.AWSProfile; if (!string.IsNullOrEmpty(awsProfile)) @@ -166,7 +165,7 @@ public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, Comman Function = lambdaFunction }; - ExecuteRequest(request, localLambdaOptions, runConfiguration); + ExecuteRequest(request, localLambdaOptions, runConfiguration, shouldDisableLogs); if (runConfiguration.Mode == RunConfiguration.RunMode.Normal && commandOptions.PauseExit) @@ -176,7 +175,7 @@ public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, Comman } } - private static string DetermineConfigFile(CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory) + private static string DetermineConfigFile(CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, bool shouldDisableLogs) { string configFile = null; if (string.IsNullOrEmpty(commandOptions.ConfigFile)) @@ -199,7 +198,7 @@ private static string DetermineConfigFile(CommandLineOptions commandOptions, str return configFile; } - private static LambdaConfigInfo LoadLambdaConfigInfo(string configFile, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration) + private static LambdaConfigInfo LoadLambdaConfigInfo(string configFile, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs) { LambdaConfigInfo configInfo; if (configFile != null) @@ -226,7 +225,7 @@ private static LambdaConfigInfo LoadLambdaConfigInfo(string configFile, CommandL return configInfo; } - private static LambdaFunction LoadLambdaFunction(LambdaConfigInfo configInfo, LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration) + private static LambdaFunction LoadLambdaFunction(LambdaConfigInfo configInfo, LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs) { // If no function handler was explicitly set and there is only one function defined in the config file then assume the user wants to debug that function. var functionHandler = commandOptions.FunctionHandler; @@ -264,7 +263,7 @@ private static LambdaFunction LoadLambdaFunction(LambdaConfigInfo configInfo, Lo return lambdaFunction; } - private static string DeterminePayload(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration) + private static string DeterminePayload(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs) { var payload = commandOptions.Payload; @@ -346,7 +345,7 @@ private static string DeterminePayload(LocalLambdaOptions localLambdaOptions, Co return payload; } - private static void ExecuteRequest(ExecutionRequest request, LocalLambdaOptions localLambdaOptions, RunConfiguration runConfiguration) + private static void ExecuteRequest(ExecutionRequest request, LocalLambdaOptions localLambdaOptions, RunConfiguration runConfiguration, bool shouldDisableLogs) { try { From 7a719d2912970c7c2ac0534a00b496a6646e501d Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Wed, 8 Apr 2026 13:12:06 -0400 Subject: [PATCH 09/10] commit 9 --- .../HandlerTests.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs index bb4fd93a1..20340f561 100644 --- a/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs +++ b/Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs @@ -388,7 +388,9 @@ private async Task ExecHandlerAsync(string handler, string dataIn var userCodeLoader = new UserCodeLoader(new SystemEnvironmentVariables(), handler, _internalLogger); var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke); var initializer = new UserCodeInitializer(userCodeLoader, _internalLogger); - var bootstrap = new LambdaBootstrap(handlerWrapper.Handler, initializer.InitializeAsync, null, _environmentVariables) + // Pass null initializer to bootstrap so RunAsync won't re-invoke Init(), + // which would re-register AssemblyLoad event handlers and re-construct the invoke delegate. + var bootstrap = new LambdaBootstrap(handlerWrapper.Handler, null, null, _environmentVariables) { Client = testRuntimeApiClient }; @@ -403,7 +405,13 @@ private async Task ExecHandlerAsync(string handler, string dataIn Assert.DoesNotContain($"^^[{assertLoggedByInitialize}]^^", actionWriter.ToString()); } - await bootstrap.InitializeAsync(); + await initializer.InitializeAsync(); + + // Re-set logging actions after initialization in case Init's AssemblyLoad event + // handler overwrote them when loading Amazon.Lambda.Core as a handler dependency. + UserCodeLoader.SetCustomerLoggerLogAction(assembly, actionWriter.ToLoggingAction(), _internalLogger); + UserCodeLoader.SetCustomerLoggerLogAction(assembly, actionWriter.ToLoggingWithLevelAction(), _internalLogger); + UserCodeLoader.SetCustomerLoggerLogAction(assembly, actionWriter.ToLoggingWithLevelAndExceptionAction(), _internalLogger); if (assertLoggedByInitialize != null) { From 56034d84dab15ae2e2aee1310d37bda4aa63c0de Mon Sep 17 00:00:00 2001 From: Phil Asmar Date: Wed, 8 Apr 2026 13:30:12 -0400 Subject: [PATCH 10/10] commit 10 --- .../Helpers/ConsoleLoggerWriter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs index 2caa708e3..a2417cbcc 100644 --- a/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs +++ b/Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs @@ -227,6 +227,7 @@ public LogLevelLoggerWriter(IEnvironmentVariables environmentVariables) /// public LogLevelLoggerWriter(TextWriter stdOutWriter, TextWriter stdErrorWriter) { + _environmentVariables = new SystemEnvironmentVariables(); Initialize(stdOutWriter, stdErrorWriter); } @@ -325,7 +326,7 @@ public IRuntimeApiHeaders CurrentRuntimeApiHeaders { get { - if (Utils.IsUsingMultiConcurrency(_environmentVariables)) + if (_currentRuntimeApiHeadersStorage != null && Utils.IsUsingMultiConcurrency(_environmentVariables)) { return _currentRuntimeApiHeadersStorage.Value; } @@ -333,7 +334,7 @@ public IRuntimeApiHeaders CurrentRuntimeApiHeaders } set { - if (Utils.IsUsingMultiConcurrency(_environmentVariables)) + if (_currentRuntimeApiHeadersStorage != null && Utils.IsUsingMultiConcurrency(_environmentVariables)) { _currentRuntimeApiHeadersStorage.Value = value; }