Skip to content

Commit 900e67b

Browse files
committed
chore: improve test flakiness
1 parent 2efa321 commit 900e67b

File tree

10 files changed

+71
-27
lines changed

10 files changed

+71
-27
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"Projects": [
3+
{
4+
"Name": "Amazon.Lambda.TestTool.BlazorTester",
5+
"Type": "Patch",
6+
"ChangelogMessages": [
7+
"Minor fixes and improvements"
8+
]
9+
}
10+
]
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"Projects": [
3+
{
4+
"Name": "Amazon.Lambda.RuntimeSupport",
5+
"Type": "Patch",
6+
"ChangelogMessages": [
7+
"Minor fixes and improvements"
8+
]
9+
}
10+
]
11+
}

Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/ConsoleLoggerWriter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ public LogLevelLoggerWriter(IEnvironmentVariables environmentVariables)
227227
/// <param name="stdErrorWriter"></param>
228228
public LogLevelLoggerWriter(TextWriter stdOutWriter, TextWriter stdErrorWriter)
229229
{
230+
_environmentVariables = new SystemEnvironmentVariables();
230231
Initialize(stdOutWriter, stdErrorWriter);
231232
}
232233

@@ -325,15 +326,15 @@ public IRuntimeApiHeaders CurrentRuntimeApiHeaders
325326
{
326327
get
327328
{
328-
if (Utils.IsUsingMultiConcurrency(_environmentVariables))
329+
if (_currentRuntimeApiHeadersStorage != null && Utils.IsUsingMultiConcurrency(_environmentVariables))
329330
{
330331
return _currentRuntimeApiHeadersStorage.Value;
331332
}
332333
return _currentRuntimeApiHeaders;
333334
}
334335
set
335336
{
336-
if (Utils.IsUsingMultiConcurrency(_environmentVariables))
337+
if (_currentRuntimeApiHeadersStorage != null && Utils.IsUsingMultiConcurrency(_environmentVariables))
337338
{
338339
_currentRuntimeApiHeadersStorage.Value = value;
339340
}

Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/HandlerTests.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ private async Task<Exception> TestHandlerFailAsync(string handler, string expect
250250
var userCodeLoader = new UserCodeLoader(new SystemEnvironmentVariables(), handler, _internalLogger);
251251
var initializer = new UserCodeInitializer(userCodeLoader, _internalLogger);
252252
var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke);
253-
var bootstrap = new LambdaBootstrap(handlerWrapper, initializer.InitializeAsync)
253+
var bootstrap = new LambdaBootstrap(handlerWrapper.Handler, initializer.InitializeAsync, null, _environmentVariables)
254254
{
255255
Client = testRuntimeApiClient
256256
};
@@ -388,7 +388,9 @@ private async Task<ExecutionInfo> ExecHandlerAsync(string handler, string dataIn
388388
var userCodeLoader = new UserCodeLoader(new SystemEnvironmentVariables(), handler, _internalLogger);
389389
var handlerWrapper = HandlerWrapper.GetHandlerWrapper(userCodeLoader.Invoke);
390390
var initializer = new UserCodeInitializer(userCodeLoader, _internalLogger);
391-
var bootstrap = new LambdaBootstrap(handlerWrapper, initializer.InitializeAsync)
391+
// Pass null initializer to bootstrap so RunAsync won't re-invoke Init(),
392+
// which would re-register AssemblyLoad event handlers and re-construct the invoke delegate.
393+
var bootstrap = new LambdaBootstrap(handlerWrapper.Handler, null, null, _environmentVariables)
392394
{
393395
Client = testRuntimeApiClient
394396
};
@@ -403,7 +405,13 @@ private async Task<ExecutionInfo> ExecHandlerAsync(string handler, string dataIn
403405
Assert.DoesNotContain($"^^[{assertLoggedByInitialize}]^^", actionWriter.ToString());
404406
}
405407

406-
await bootstrap.InitializeAsync();
408+
await initializer.InitializeAsync();
409+
410+
// Re-set logging actions after initialization in case Init's AssemblyLoad event
411+
// handler overwrote them when loading Amazon.Lambda.Core as a handler dependency.
412+
UserCodeLoader.SetCustomerLoggerLogAction(assembly, actionWriter.ToLoggingAction(), _internalLogger);
413+
UserCodeLoader.SetCustomerLoggerLogAction(assembly, actionWriter.ToLoggingWithLevelAction(), _internalLogger);
414+
UserCodeLoader.SetCustomerLoggerLogAction(assembly, actionWriter.ToLoggingWithLevelAndExceptionAction(), _internalLogger);
407415

408416
if (assertLoggedByInitialize != null)
409417
{

Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LambdaBootstrapTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public async Task TraceIdEnvironmentVariableIsSet()
165165
[Fact]
166166
public async Task HandlerThrowsException()
167167
{
168-
using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerThrowsAsync, null))
168+
using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerThrowsAsync, null, null, _environmentVariables))
169169
{
170170
bootstrap.Client = _testRuntimeApiClient;
171171
Assert.Null(_environmentVariables.GetEnvironmentVariable(LambdaEnvironment.EnvVarTraceId));
@@ -183,7 +183,7 @@ public async Task HandlerInputAndOutputWork()
183183
{
184184
const string testInput = "a MiXeD cAsE sTrInG";
185185

186-
using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerToUpperAsync, null))
186+
using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerToUpperAsync, null, null, _environmentVariables))
187187
{
188188
_testRuntimeApiClient.FunctionInput = Encoding.UTF8.GetBytes(testInput);
189189
bootstrap.Client = _testRuntimeApiClient;
@@ -201,7 +201,7 @@ public async Task HandlerInputAndOutputWork()
201201
[Fact]
202202
public async Task HandlerReturnsNull()
203203
{
204-
using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerReturnsNullAsync, null))
204+
using (var bootstrap = new LambdaBootstrap(_testFunction.BaseHandlerReturnsNullAsync, null, null, _environmentVariables))
205205
{
206206
_testRuntimeApiClient.FunctionInput = new byte[0];
207207
bootstrap.Client = _testRuntimeApiClient;

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/BaseApiGatewayTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ protected async Task CleanupAsync()
4848
CancellationTokenSource.Dispose();
4949
CancellationTokenSource = new CancellationTokenSource();
5050
}
51+
Environment.SetEnvironmentVariable("APIGATEWAY_EMULATOR_ROUTE_CONFIG", null);
5152
}
5253

5354
protected async Task StartTestToolProcessAsync(ApiGatewayEmulatorMode apiGatewayMode, string routeName, int lambdaPort, int apiGatewayPort, CancellationTokenSource cancellationTokenSource, string httpMethod = "POST")

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/SQSEventSourceTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public async Task ProcessMessagesFromMultipleEventSources()
183183
await sqsClient.SendMessageAsync(queueUrl2, "MessageFromQueue2");
184184

185185
var startTime = DateTime.UtcNow;
186-
while (listOfProcessedMessages.Count == 0 && DateTime.UtcNow < startTime.AddMinutes(2))
186+
while (listOfProcessedMessages.Count < 2 && DateTime.UtcNow < startTime.AddMinutes(2))
187187
{
188188
Assert.False(lambdaTask.IsFaulted, "Lambda function failed: " + lambdaTask.Exception?.ToString());
189189
await Task.Delay(500);

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.Tests.Common/Helpers/TestHelpers.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
using System.Net;
5+
using System.Net.Sockets;
6+
47
namespace Amazon.Lambda.TestTool.Tests.Common.Helpers;
58

69
public static class TestHelpers
@@ -39,16 +42,22 @@ public static async Task<HttpResponseMessage> SendRequest(string url)
3942
}
4043
}
4144

42-
private static int _maxLambdaRuntimePort = 6000;
43-
private static int _maxApiGatewayPort = 9000;
45+
private static int GetFreePort()
46+
{
47+
var listener = new TcpListener(IPAddress.Loopback, 0);
48+
listener.Start();
49+
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
50+
listener.Stop();
51+
return port;
52+
}
4453

4554
public static int GetNextLambdaRuntimePort()
4655
{
47-
return Interlocked.Increment(ref _maxLambdaRuntimePort);
56+
return GetFreePort();
4857
}
4958

5059
public static int GetNextApiGatewayPort()
5160
{
52-
return Interlocked.Increment(ref _maxApiGatewayPort);
61+
return GetFreePort();
5362
}
5463
}

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/RuntimeApiTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public async Task AddEventToDataStore()
3939
var testToolProcess = TestToolProcess.Startup(options, cancellationTokenSource.Token);
4040
try
4141
{
42+
Assert.True(await TestHelpers.WaitForApiToStartAsync($"{testToolProcess.ServiceUrl}/lambda-runtime-api/healthcheck"));
43+
4244
var lambdaClient = ConstructLambdaServiceClient(testToolProcess.ServiceUrl);
4345
var invokeFunction = new InvokeRequest
4446
{
@@ -92,6 +94,8 @@ public async Task InvokeRequestResponse()
9294
var testToolProcess = TestToolProcess.Startup(options, cancellationTokenSource.Token);
9395
try
9496
{
97+
Assert.True(await TestHelpers.WaitForApiToStartAsync($"{testToolProcess.ServiceUrl}/lambda-runtime-api/healthcheck"));
98+
9599
var handler = (string input, ILambdaContext context) =>
96100
{
97101
Thread.Sleep(1000); // Add a sleep to prove the LambdaRuntimeApi waited for the completion.

Tools/LambdaTestTool/src/Amazon.Lambda.TestTool/TestToolStartup.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace Amazon.Lambda.TestTool
1010
{
1111
public class TestToolStartup
1212
{
13-
private static bool shouldDisableLogs;
1413

1514
public class RunConfiguration
1615
{
@@ -37,7 +36,7 @@ public static void Startup(string productName, Action<LocalLambdaOptions, bool>
3736
try
3837
{
3938
var commandOptions = CommandLineOptions.Parse(args);
40-
shouldDisableLogs = Utils.ShouldDisableLogs(commandOptions);
39+
var shouldDisableLogs = Utils.ShouldDisableLogs(commandOptions);
4140

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

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

7776
if (commandOptions.NoUI)
7877
{
79-
ExecuteWithNoUi(localLambdaOptions, commandOptions, lambdaAssemblyDirectory, runConfiguration);
78+
ExecuteWithNoUi(localLambdaOptions, commandOptions, lambdaAssemblyDirectory, runConfiguration, shouldDisableLogs);
8079
}
8180
else
8281
{
@@ -118,16 +117,16 @@ public static void Startup(string productName, Action<LocalLambdaOptions, bool>
118117
}
119118

120119

121-
public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, RunConfiguration runConfiguration)
120+
public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs)
122121
{
123122
if (!shouldDisableLogs) runConfiguration.OutputWriter.WriteLine("Executing Lambda function without web interface");
124123
var lambdaProjectDirectory = Utils.FindLambdaProjectDirectory(lambdaAssemblyDirectory);
125124

126-
string configFile = DetermineConfigFile(commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory);
127-
LambdaConfigInfo configInfo = LoadLambdaConfigInfo(configFile, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration);
128-
LambdaFunction lambdaFunction = LoadLambdaFunction(configInfo, localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration);
125+
string configFile = DetermineConfigFile(commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, shouldDisableLogs: shouldDisableLogs);
126+
LambdaConfigInfo configInfo = LoadLambdaConfigInfo(configFile, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration, shouldDisableLogs: shouldDisableLogs);
127+
LambdaFunction lambdaFunction = LoadLambdaFunction(configInfo, localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration, shouldDisableLogs: shouldDisableLogs);
129128

130-
string payload = DeterminePayload(localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration);
129+
string payload = DeterminePayload(localLambdaOptions, commandOptions, lambdaAssemblyDirectory: lambdaAssemblyDirectory, lambdaProjectDirectory: lambdaProjectDirectory, runConfiguration, shouldDisableLogs: shouldDisableLogs);
131130

132131
var awsProfile = commandOptions.AWSProfile ?? configInfo.AWSProfile;
133132
if (!string.IsNullOrEmpty(awsProfile))
@@ -166,7 +165,7 @@ public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, Comman
166165
Function = lambdaFunction
167166
};
168167

169-
ExecuteRequest(request, localLambdaOptions, runConfiguration);
168+
ExecuteRequest(request, localLambdaOptions, runConfiguration, shouldDisableLogs);
170169

171170

172171
if (runConfiguration.Mode == RunConfiguration.RunMode.Normal && commandOptions.PauseExit)
@@ -176,7 +175,7 @@ public static void ExecuteWithNoUi(LocalLambdaOptions localLambdaOptions, Comman
176175
}
177176
}
178177

179-
private static string DetermineConfigFile(CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory)
178+
private static string DetermineConfigFile(CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, bool shouldDisableLogs)
180179
{
181180
string configFile = null;
182181
if (string.IsNullOrEmpty(commandOptions.ConfigFile))
@@ -199,7 +198,7 @@ private static string DetermineConfigFile(CommandLineOptions commandOptions, str
199198
return configFile;
200199
}
201200

202-
private static LambdaConfigInfo LoadLambdaConfigInfo(string configFile, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration)
201+
private static LambdaConfigInfo LoadLambdaConfigInfo(string configFile, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs)
203202
{
204203
LambdaConfigInfo configInfo;
205204
if (configFile != null)
@@ -226,7 +225,7 @@ private static LambdaConfigInfo LoadLambdaConfigInfo(string configFile, CommandL
226225
return configInfo;
227226
}
228227

229-
private static LambdaFunction LoadLambdaFunction(LambdaConfigInfo configInfo, LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration)
228+
private static LambdaFunction LoadLambdaFunction(LambdaConfigInfo configInfo, LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs)
230229
{
231230
// 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.
232231
var functionHandler = commandOptions.FunctionHandler;
@@ -264,7 +263,7 @@ private static LambdaFunction LoadLambdaFunction(LambdaConfigInfo configInfo, Lo
264263
return lambdaFunction;
265264
}
266265

267-
private static string DeterminePayload(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration)
266+
private static string DeterminePayload(LocalLambdaOptions localLambdaOptions, CommandLineOptions commandOptions, string lambdaAssemblyDirectory, string lambdaProjectDirectory, RunConfiguration runConfiguration, bool shouldDisableLogs)
268267
{
269268
var payload = commandOptions.Payload;
270269

@@ -346,7 +345,7 @@ private static string DeterminePayload(LocalLambdaOptions localLambdaOptions, Co
346345
return payload;
347346
}
348347

349-
private static void ExecuteRequest(ExecutionRequest request, LocalLambdaOptions localLambdaOptions, RunConfiguration runConfiguration)
348+
private static void ExecuteRequest(ExecutionRequest request, LocalLambdaOptions localLambdaOptions, RunConfiguration runConfiguration, bool shouldDisableLogs)
350349
{
351350
try
352351
{

0 commit comments

Comments
 (0)