Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .autover/changes/9cf844c3-1a90-46ec-9430-93724dcb4512.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"Projects": [
{
"Name": "Amazon.Lambda.TestTool.BlazorTester",
"Type": "Patch",
"ChangelogMessages": [
"Minor fixes and improvements"
]
}
]
}
11 changes: 11 additions & 0 deletions .autover/changes/a119819e-ba57-424d-a0be-d941eea599f9.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"Projects": [
{
"Name": "Amazon.Lambda.RuntimeSupport",
"Type": "Patch",
"ChangelogMessages": [
"Minor fixes and improvements"
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ public LogLevelLoggerWriter(IEnvironmentVariables environmentVariables)
/// <param name="stdErrorWriter"></param>
public LogLevelLoggerWriter(TextWriter stdOutWriter, TextWriter stdErrorWriter)
{
_environmentVariables = new SystemEnvironmentVariables();
Initialize(stdOutWriter, stdErrorWriter);
}

Expand Down Expand Up @@ -325,15 +326,15 @@ public IRuntimeApiHeaders CurrentRuntimeApiHeaders
{
get
{
if (Utils.IsUsingMultiConcurrency(_environmentVariables))
if (_currentRuntimeApiHeadersStorage != null && Utils.IsUsingMultiConcurrency(_environmentVariables))
{
return _currentRuntimeApiHeadersStorage.Value;
}
return _currentRuntimeApiHeaders;
}
set
{
if (Utils.IsUsingMultiConcurrency(_environmentVariables))
if (_currentRuntimeApiHeadersStorage != null && Utils.IsUsingMultiConcurrency(_environmentVariables))
{
_currentRuntimeApiHeadersStorage.Value = value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ private async Task<Exception> 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
};
Expand Down Expand Up @@ -388,7 +388,9 @@ private async Task<ExecutionInfo> 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)
// 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
};
Expand All @@ -403,7 +405,13 @@ private async Task<ExecutionInfo> 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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -39,16 +42,22 @@ public static async Task<HttpResponseMessage> 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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public async Task AddEventToDataStore()
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
{
Expand Down Expand Up @@ -92,6 +94,8 @@ public async Task InvokeRequestResponse()
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.
Expand Down
27 changes: 13 additions & 14 deletions Tools/LambdaTestTool/src/Amazon.Lambda.TestTool/TestToolStartup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Amazon.Lambda.TestTool
{
public class TestToolStartup
{
private static bool shouldDisableLogs;

public class RunConfiguration
{
Expand All @@ -37,7 +36,7 @@ public static void Startup(string productName, Action<LocalLambdaOptions, bool>
try
{
var commandOptions = CommandLineOptions.Parse(args);
shouldDisableLogs = Utils.ShouldDisableLogs(commandOptions);
var shouldDisableLogs = Utils.ShouldDisableLogs(commandOptions);

if (!shouldDisableLogs) Utils.PrintToolTitle(productName);

Expand Down Expand Up @@ -76,7 +75,7 @@ public static void Startup(string productName, Action<LocalLambdaOptions, bool>

if (commandOptions.NoUI)
{
ExecuteWithNoUi(localLambdaOptions, commandOptions, lambdaAssemblyDirectory, runConfiguration);
ExecuteWithNoUi(localLambdaOptions, commandOptions, lambdaAssemblyDirectory, runConfiguration, shouldDisableLogs);
}
else
{
Expand Down Expand Up @@ -118,16 +117,16 @@ public static void Startup(string productName, Action<LocalLambdaOptions, bool>
}


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))
Expand Down Expand Up @@ -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)
Expand All @@ -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))
Expand All @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
{
Expand Down
Loading