Skip to content

Commit d62319a

Browse files
committed
PR comments
1 parent ceea346 commit d62319a

File tree

7 files changed

+88
-94
lines changed

7 files changed

+88
-94
lines changed

Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Components/Pages/Home.razor.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using BlazorMonaco.Editor;
1111
using Microsoft.JSInterop;
1212
using Microsoft.AspNetCore.WebUtilities;
13+
using Microsoft.Extensions.Options;
1314

1415
namespace Amazon.Lambda.TestTool.Components.Pages;
1516

@@ -22,8 +23,8 @@ public partial class Home : ComponentBase, IDisposable
2223
[Inject] public required IDirectoryManager DirectoryManager { get; set; }
2324
[Inject] public required IThemeService ThemeService { get; set; }
2425
[Inject] public required IJSRuntime JsRuntime { get; set; }
25-
2626
[Inject] public required ILambdaClient LambdaClient { get; set; }
27+
[Inject] public IOptions<LambdaOptions> LambdaOptions { get; set; }
2728

2829
private StandaloneCodeEditor? _editor;
2930
private StandaloneCodeEditor? _activeEditor;
@@ -345,16 +346,17 @@ private async Task<bool> InvokeLambdaFunction(string payload)
345346

346347
try
347348
{
348-
await LambdaClient.InvokeAsync(invokeRequest);
349+
await LambdaClient.InvokeAsync(invokeRequest, LambdaOptions.Value.Endpoint);
349350
_errorMessage = string.Empty;
350351
return true;
351352
}
352353
catch (AmazonLambdaException e)
353354
{
354355
// lambda client automatically adds some extra verbiage: "The service returned an error with Error Code xxxx and HTTP Body: <bodyhere>".
355356
// removing the extra verbiage to make the error message smaller and look better on the ui.
356-
_errorMessage = e.Message.Split("HTTP Body: ")[1];
357-
}
357+
_errorMessage = e.Message.Contains("HTTP Body: ")
358+
? e.Message.Split("HTTP Body: ")[1]
359+
: e.Message; }
358360
return false;
359361
}
360362
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
namespace Amazon.Lambda.TestTool.Models;
5+
6+
public class LambdaOptions
7+
{
8+
public string Endpoint { get; set; } = string.Empty;
9+
}

Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Processes/ApiGatewayEmulatorProcess.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,8 @@ public static ApiGatewayEmulatorProcess Startup(RunCommandSettings settings, Can
5252
Utils.ConfigureWebApplicationBuilder(builder);
5353

5454
builder.Services.AddApiGatewayEmulatorServices();
55-
builder.Services.Configure<RunCommandSettings>(options =>
56-
{
57-
options.LambdaEmulatorHost = settings.LambdaEmulatorHost;
58-
options.LambdaEmulatorPort = settings.LambdaEmulatorPort;
59-
});
60-
6155
builder.Services.AddSingleton<ILambdaClient, LambdaClient>();
6256

63-
6457
var serviceUrl = $"http://{settings.LambdaEmulatorHost}:{settings.ApiGatewayEmulatorPort}";
6558
builder.WebHost.UseUrls(serviceUrl);
6659
builder.WebHost.SuppressStatusMessages(true);
@@ -112,9 +105,7 @@ public static ApiGatewayEmulatorProcess Startup(RunCommandSettings settings, Can
112105
try
113106
{
114107
var endpoint = routeConfig.Endpoint ?? $"http://{settings.LambdaEmulatorHost}:{settings.LambdaEmulatorPort}";
115-
lambdaClient.SetEndpoint(endpoint);
116-
117-
var response = await lambdaClient.InvokeAsync(invokeRequest);
108+
var response = await lambdaClient.InvokeAsync(invokeRequest, endpoint);
118109

119110
if (response.FunctionError == null) // response is successful
120111
{

Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Processes/TestToolProcess.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Amazon.Lambda.TestTool.Commands.Settings;
66
using Amazon.Lambda.TestTool.Components;
77
using Amazon.Lambda.TestTool.Configuration;
8+
using Amazon.Lambda.TestTool.Models;
89
using Amazon.Lambda.TestTool.Services;
910
using Amazon.Lambda.TestTool.Services.IO;
1011
using Amazon.Lambda.TestTool.Utilities;
@@ -44,13 +45,13 @@ public static TestToolProcess Startup(RunCommandSettings settings, CancellationT
4445

4546
builder.Services.AddSingleton<IRuntimeApiDataStoreManager, RuntimeApiDataStoreManager>();
4647
builder.Services.AddSingleton<IThemeService, ThemeService>();
47-
builder.Services.Configure<RunCommandSettings>(options =>
48+
builder.Services.AddSingleton<ILambdaClient, LambdaClient>();
49+
50+
builder.Services.Configure<LambdaOptions>(options =>
4851
{
49-
options.LambdaEmulatorHost = settings.LambdaEmulatorHost;
50-
options.LambdaEmulatorPort = settings.LambdaEmulatorPort;
52+
options.Endpoint = $"http://{settings.LambdaEmulatorHost}:{settings.LambdaEmulatorPort}";
5153
});
5254

53-
builder.Services.AddSingleton<ILambdaClient, LambdaClient>();
5455

5556
// Add services to the container.
5657
builder.Services.AddRazorComponents()

Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Services/ILambdaClient.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,7 @@ public interface ILambdaClient
1414
/// Invokes a Lambda function asynchronously.
1515
/// </summary>
1616
/// <param name="request">The request object containing details for the Lambda function invocation.</param>
17+
/// <param name="endpoint">The endpoint for the lambda to connect invoke.</param>
1718
/// <returns>A task that represents the asynchronous operation. The task result contains the response from the Lambda function invocation.</returns>
18-
Task<InvokeResponse> InvokeAsync(InvokeRequest request);
19-
20-
/// <summary>
21-
/// Sets the endpoint for the Lambda client.
22-
/// </summary>
23-
/// <param name="endpoint">The URL of the endpoint to be used for Lambda operations.</param>
24-
void SetEndpoint(string endpoint);
19+
Task<InvokeResponse> InvokeAsync(InvokeRequest request, string endpoint);
2520
}

Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Services/LambdaClient.cs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1+
using System.Collections.Concurrent;
12
using Amazon.Lambda.Model;
2-
using Amazon.Lambda.TestTool.Commands.Settings;
3-
using Microsoft.Extensions.Options;
43

54
namespace Amazon.Lambda.TestTool.Services;
65

@@ -9,35 +8,21 @@ namespace Amazon.Lambda.TestTool.Services;
98
/// </summary>
109
public class LambdaClient : ILambdaClient, IDisposable
1110
{
12-
internal Dictionary<string, IAmazonLambda> Clients => _clients; // used for unit tests only
13-
private readonly Dictionary<string, IAmazonLambda> _clients;
14-
private string _currentEndpoint;
11+
internal ConcurrentDictionary<string, IAmazonLambda> Clients => _clients; // used for unit tests only
12+
private readonly ConcurrentDictionary<string, IAmazonLambda> _clients;
1513

1614
/// <summary>
1715
/// Initializes a new instance of the <see cref="LambdaClient"/> class.
1816
/// </summary>
19-
/// <param name="settings">The run command settings containing Lambda emulator configuration.</param>
20-
public LambdaClient(IOptions<RunCommandSettings> settings)
17+
public LambdaClient()
2118
{
22-
_clients = new Dictionary<string, IAmazonLambda>();
23-
_currentEndpoint = $"http://{settings.Value.LambdaEmulatorHost}:{settings.Value.LambdaEmulatorPort}";
24-
_clients[_currentEndpoint] = CreateClient(_currentEndpoint);
19+
_clients = new ConcurrentDictionary<string, IAmazonLambda>();
2520
}
2621

2722
/// <inheritdoc />
28-
public Task<InvokeResponse> InvokeAsync(InvokeRequest request)
23+
public Task<InvokeResponse> InvokeAsync(InvokeRequest request, string endpoint)
2924
{
30-
return _clients[_currentEndpoint].InvokeAsync(request);
31-
}
32-
33-
/// <inheritdoc />
34-
public void SetEndpoint(string endpoint)
35-
{
36-
if (!_clients.ContainsKey(endpoint))
37-
{
38-
_clients[endpoint] = CreateClient(endpoint);
39-
}
40-
_currentEndpoint = endpoint;
25+
return _clients.GetOrAdd(endpoint, CreateClient(endpoint)).InvokeAsync(request);
4126
}
4227

4328
/// <summary>
Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,118 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
45
using Amazon.Lambda.Model;
5-
using Amazon.Lambda.TestTool.Commands.Settings;
66
using Amazon.Lambda.TestTool.Services;
7-
using Microsoft.Extensions.Options;
87
using Moq;
98
using Xunit;
109

1110
namespace Amazon.Lambda.TestTool.UnitTests.Services
1211
{
13-
public class LambdaClientTests : IDisposable
12+
public class LambdaClientTests : IDisposable
1413
{
15-
private readonly Mock<IOptions<RunCommandSettings>> _mockSettings;
16-
private readonly RunCommandSettings _settings;
17-
private readonly LambdaClient _client;
14+
private readonly LambdaClient _lambdaClient;
15+
private readonly InvokeRequest _validRequest;
1816

1917
public LambdaClientTests()
2018
{
21-
_settings = new RunCommandSettings
19+
_lambdaClient = new LambdaClient();
20+
_validRequest = new InvokeRequest
2221
{
23-
LambdaEmulatorHost = "localhost",
24-
LambdaEmulatorPort = 5050
22+
FunctionName = "TestFunction",
23+
Payload = "{}"
2524
};
26-
_mockSettings = new Mock<IOptions<RunCommandSettings>>();
27-
_mockSettings.Setup(s => s.Value).Returns(_settings);
28-
_client = new LambdaClient(_mockSettings.Object);
2925
}
3026

3127
[Fact]
32-
public void Constructor_InitializesCorrectly()
33-
{
34-
// Assert
35-
var expectedEndpoint = $"http://{_settings.LambdaEmulatorHost}:{_settings.LambdaEmulatorPort}";
36-
Assert.Single(_client.Clients);
37-
Assert.True(_client.Clients.ContainsKey(expectedEndpoint));
38-
}
39-
40-
[Fact]
41-
public async Task InvokeAsync_UsesCurrentEndpoint()
28+
public void InvokeAsync_CreatesNewClientForNewEndpoint()
4229
{
4330
// Arrange
44-
var request = new InvokeRequest();
31+
var endpoint = "invalid://example.com";
32+
33+
// Act
34+
_lambdaClient.InvokeAsync(_validRequest, endpoint);
4535

46-
// Act & Assert
47-
await Assert.ThrowsAsync<AmazonLambdaException>(
48-
async () => await _client.InvokeAsync(request));
36+
// Assert
37+
Assert.Single(_lambdaClient.Clients);
38+
Assert.True(_lambdaClient.Clients.ContainsKey(endpoint));
4939
}
5040

5141
[Fact]
52-
public void SetEndpoint_CreatesNewClientForNewEndpoint()
42+
public void InvokeAsync_ReuseExistingClientForSameEndpoint()
5343
{
5444
// Arrange
55-
var newEndpoint = "http://newhost:1234";
56-
var initialCount = _client.Clients.Count;
45+
var endpoint = "invalid://example.com";
5746

5847
// Act
59-
_client.SetEndpoint(newEndpoint);
48+
_lambdaClient.InvokeAsync(_validRequest, endpoint);
49+
_lambdaClient.InvokeAsync(_validRequest, endpoint);
6050

6151
// Assert
62-
Assert.True(_client.Clients.ContainsKey(newEndpoint));
63-
Assert.Equal(initialCount + 1, _client.Clients.Count);
52+
Assert.Single(_lambdaClient.Clients);
53+
Assert.True(_lambdaClient.Clients.ContainsKey(endpoint));
6454
}
6555

6656
[Fact]
67-
public void SetEndpoint_ReuseExistingClientForSameEndpoint()
57+
public void InvokeAsync_CreatesSeparateClientsForDifferentEndpoints()
6858
{
6959
// Arrange
70-
var initialEndpoint = $"http://{_settings.LambdaEmulatorHost}:{_settings.LambdaEmulatorPort}";
71-
var initialCount = _client.Clients.Count;
60+
var endpoint1 = "invalid://example1.com";
61+
var endpoint2 = "invalid://example2.com";
7262

7363
// Act
74-
_client.SetEndpoint(initialEndpoint);
64+
_lambdaClient.InvokeAsync(_validRequest, endpoint1);
65+
_lambdaClient.InvokeAsync(_validRequest, endpoint2);
7566

7667
// Assert
77-
Assert.Equal(initialCount, _client.Clients.Count);
78-
Assert.True(_client.Clients.ContainsKey(initialEndpoint));
68+
Assert.Equal(2, _lambdaClient.Clients.Count);
69+
Assert.True(_lambdaClient.Clients.ContainsKey(endpoint1));
70+
Assert.True(_lambdaClient.Clients.ContainsKey(endpoint2));
7971
}
8072

8173
[Fact]
82-
public void Dispose_ClearsAllClients()
74+
public void Dispose_ClearsClientDictionary()
8375
{
76+
// Arrange
77+
var endpoint = "invalid://example.com";
78+
_lambdaClient.InvokeAsync(_validRequest, endpoint);
79+
Assert.Single(_lambdaClient.Clients);
80+
8481
// Act
85-
_client.Dispose();
82+
_lambdaClient.Dispose();
8683

8784
// Assert
88-
Assert.Empty(_client.Clients);
85+
Assert.Empty(_lambdaClient.Clients);
8986
}
9087

9188
[Fact]
92-
public async Task Dispose_PreventsSubsequentOperations()
89+
public void MultipleEndpoints_CreateCorrectNumberOfClients()
9390
{
9491
// Arrange
95-
_client.Dispose();
92+
var endpoints = new[]
93+
{
94+
"invalid://example1.com",
95+
"invalid://example2.com",
96+
"invalid://example3.com",
97+
"invalid://example1.com" // Duplicate to test reuse
98+
};
9699

97-
// Act & Assert
98-
await Assert.ThrowsAnyAsync<Exception>(
99-
async () => await _client.InvokeAsync(new InvokeRequest()));
100+
// Act
101+
foreach (var endpoint in endpoints)
102+
{
103+
_lambdaClient.InvokeAsync(_validRequest, endpoint);
104+
}
105+
106+
// Assert
107+
Assert.Equal(3, _lambdaClient.Clients.Count);
108+
Assert.True(_lambdaClient.Clients.ContainsKey("invalid://example1.com"));
109+
Assert.True(_lambdaClient.Clients.ContainsKey("invalid://example2.com"));
110+
Assert.True(_lambdaClient.Clients.ContainsKey("invalid://example3.com"));
100111
}
101112

102113
public void Dispose()
103114
{
104-
_client?.Dispose();
115+
_lambdaClient.Dispose();
105116
}
106117
}
107118
}

0 commit comments

Comments
 (0)