Skip to content

Commit 79ef0b5

Browse files
committed
Update TestToolv2 Lambda Runtime API to partition the events per listening function and support for RequestResponse invocation type.
1 parent 8b90fa5 commit 79ef0b5

File tree

8 files changed

+321
-69
lines changed

8 files changed

+321
-69
lines changed

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

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@page "/"
1+
@page "/"
22

33
@using Amazon.Lambda.TestTool.Commands
44
@using Amazon.Lambda.TestTool.Services
@@ -9,7 +9,7 @@
99
@using Microsoft.AspNetCore.Http;
1010

1111
@inject IHttpContextAccessor HttpContextAccessor
12-
@inject IRuntimeApiDataStore RuntimeApiModel
12+
@inject IRuntimeApiDataStoreManager DataStoreManager
1313
@inject IDirectoryManager DirectoryManager
1414

1515
<PageTitle>Lambd Function Tester</PageTitle>
@@ -58,33 +58,33 @@
5858
</div>
5959
<div class="col-sm-6">
6060
<h3>Active Event:</h3>
61-
@if (RuntimeApiModel.ActiveEvent == null)
61+
@if (DataStore.ActiveEvent == null)
6262
{
6363
<h2>No active event</h2>
6464
}
6565
else
6666
{
6767
<div>
68-
<div style="cursor: pointer" @onclick="() => OnRequeue(RuntimeApiModel.ActiveEvent.AwsRequestId)">
68+
<div style="cursor: pointer" @onclick="() => OnRequeue(DataStore.ActiveEvent.AwsRequestId)">
6969
@((MarkupString)REBOOT_ICON)
7070
</div>
71-
<p><b>Request ID:</b> @RuntimeApiModel.ActiveEvent.AwsRequestId</p>
72-
<p><b>Status:</b> <span style="@GetStatusStyle(RuntimeApiModel.ActiveEvent.EventStatus)">@RuntimeApiModel.ActiveEvent.EventStatus</span></p>
73-
<p><b>Last Updated:</b> @RuntimeApiModel.ActiveEvent.LastUpdated</p>
74-
<p><b>Event JSON:</b><span class="event-value"><span class="fake-link" @onclick="() => ShowEventJson(RuntimeApiModel.ActiveEvent)">@CreateSnippet(RuntimeApiModel.ActiveEvent.EventJson)</span></span></p>
75-
@if (RuntimeApiModel.ActiveEvent.EventStatus == EventContainer.Status.Failure)
71+
<p><b>Request ID:</b> @DataStore.ActiveEvent.AwsRequestId</p>
72+
<p><b>Status:</b> <span style="@GetStatusStyle(DataStore.ActiveEvent.EventStatus)">@DataStore.ActiveEvent.EventStatus</span></p>
73+
<p><b>Last Updated:</b> @DataStore.ActiveEvent.LastUpdated</p>
74+
<p><b>Event JSON:</b><span class="event-value"><span class="fake-link" @onclick="() => ShowEventJson(DataStore.ActiveEvent)">@CreateSnippet(DataStore.ActiveEvent.EventJson)</span></span></p>
75+
@if (DataStore.ActiveEvent.EventStatus == EventContainer.Status.Failure)
7676
{
77-
<p><b>Error Type:</b> @RuntimeApiModel.ActiveEvent.ErrorType</p>
77+
<p><b>Error Type:</b> @DataStore.ActiveEvent.ErrorType</p>
7878
<p>
7979
<b>Error Response:</b>
80-
<pre class="form-control" style="@Constants.ResponseErrorStyleSizeConstraint">@RuntimeApiModel.ActiveEvent.ErrorResponse</pre>
80+
<pre class="form-control" style="@Constants.ResponseErrorStyleSizeConstraint">@DataStore.ActiveEvent.ErrorResponse</pre>
8181
</p>
8282
}
8383
else
8484
{
8585
<p>
8686
<b>Response:</b>
87-
<pre class="form-control" style="@Constants.ResponseSuccessStyleSizeConstraint">@Utils.TryPrettyPrintJson(RuntimeApiModel.ActiveEvent.Response)</pre>
87+
<pre class="form-control" style="@Constants.ResponseSuccessStyleSizeConstraint">@Utils.TryPrettyPrintJson(DataStore.ActiveEvent.Response)</pre>
8888
</p>
8989
}
9090
</div>
@@ -97,7 +97,7 @@
9797
<div class="col-sm-6">
9898
<h3>Queued Events: <button class="btn btn-secondary btn-sm" @onclick="OnClearQueued">Clear</button></h3>
9999
<div class="col-xs-5 event-list">
100-
@foreach (var evnt in @RuntimeApiModel.QueuedEvents)
100+
@foreach (var evnt in @DataStore.QueuedEvents)
101101
{
102102
<div class="event-list-item">
103103
<div class="row" style="padding: 2px">
@@ -119,7 +119,7 @@
119119
<div class="col-sm-6">
120120
<h3>Executed Events: <button class="btn btn-secondary btn-sm" @onclick="OnClearExecuted">Clear</button></h3>
121121
<div class="col-xs-5 event-list">
122-
@foreach (var evnt in @RuntimeApiModel.ExecutedEvents.OrderByDescending(x => x.LastUpdated))
122+
@foreach (var evnt in @DataStore.ExecutedEvents.OrderByDescending(x => x.LastUpdated))
123123
{
124124
<div class="event-list-item">
125125
<div class="row" style="padding: 2px">
@@ -183,6 +183,8 @@
183183

184184
private IDictionary<string, IList<LambdaRequest>> SampleRequests { get; set; } = new Dictionary<string, IList<LambdaRequest>>();
185185

186+
private IRuntimeApiDataStore DataStore => DataStoreManager.GetLambdaRuntimeDataStore(LambdaRuntimeApi.DefaultFunctionName);
187+
186188
string? _selectedSampleRequestName;
187189
string? SelectedSampleRequestName
188190
{
@@ -209,7 +211,7 @@
209211

210212
protected override void OnInitialized()
211213
{
212-
RuntimeApiModel.StateChange += RuntimeApiModelOnStateChange;
214+
DataStore.StateChange += RuntimeApiModelOnStateChange;
213215
this.SampleRequestManager = new SampleRequestManager(DirectoryManager.GetCurrentDirectory());
214216
this.SampleRequests = SampleRequestManager.GetSampleRequests();
215217
}
@@ -221,46 +223,46 @@
221223

222224
void OnAddEventClick()
223225
{
224-
RuntimeApiModel.QueueEvent(this.FunctionInput);
226+
DataStore.QueueEvent(this.FunctionInput, false);
225227
this.FunctionInput = "";
226228
this.SelectedSampleRequestName = NO_SAMPLE_SELECTED_ID;
227229
this.StateHasChanged();
228230
}
229231

230232
void OnClearQueued()
231233
{
232-
this.RuntimeApiModel.ClearQueued();
234+
this.DataStore.ClearQueued();
233235
this.StateHasChanged();
234236
}
235237

236238
void OnClearExecuted()
237239
{
238-
this.RuntimeApiModel.ClearExecuted();
240+
this.DataStore.ClearExecuted();
239241
this.StateHasChanged();
240242
}
241243

242244
void OnRequeue(string awsRequestId)
243245
{
244246
EventContainer? evnt = null;
245-
if (string.Equals(this.RuntimeApiModel.ActiveEvent?.AwsRequestId, awsRequestId))
247+
if (string.Equals(this.DataStore.ActiveEvent?.AwsRequestId, awsRequestId))
246248
{
247-
evnt = this.RuntimeApiModel.ActiveEvent;
249+
evnt = this.DataStore.ActiveEvent;
248250
}
249251
else
250252
{
251-
evnt = this.RuntimeApiModel.ExecutedEvents.FirstOrDefault(x => string.Equals(x.AwsRequestId, awsRequestId));
253+
evnt = this.DataStore.ExecutedEvents.FirstOrDefault(x => string.Equals(x.AwsRequestId, awsRequestId));
252254
}
253255

254256
if (evnt == null)
255257
return;
256258

257-
this.RuntimeApiModel.QueueEvent(evnt.EventJson);
259+
this.DataStore.QueueEvent(evnt.EventJson, false);
258260
this.StateHasChanged();
259261
}
260262

261263
void OnDeleteEvent(string awsRequestId)
262264
{
263-
this.RuntimeApiModel.DeleteEvent(awsRequestId);
265+
this.DataStore.DeleteEvent(awsRequestId);
264266
this.StateHasChanged();
265267
}
266268

Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Models/EventContainer.cs

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

44
using Amazon.Lambda.TestTool.Services;
55

66
namespace Amazon.Lambda.TestTool.Models;
77

8-
public class EventContainer
8+
public class EventContainer : IDisposable
99
{
1010
public enum Status { Queued, Executing, Success, Failure }
1111

@@ -21,6 +21,9 @@ public enum Status { Queued, Executing, Success, Failure }
2121
public DateTime LastUpdated { get; private set; }
2222

2323
private Status _status = Status.Queued;
24+
25+
private ManualResetEventSlim? _resetEvent;
26+
2427
public Status EventStatus
2528
{
2629
get => _status;
@@ -33,12 +36,17 @@ public Status EventStatus
3336

3437
private readonly RuntimeApiDataStore _dataStore;
3538

36-
public EventContainer(RuntimeApiDataStore dataStore, int eventCount, string eventJson)
39+
public EventContainer(RuntimeApiDataStore dataStore, int eventCount, string eventJson, bool isRequestResponseMode)
3740
{
3841
LastUpdated = DateTime.Now;
3942
_dataStore = dataStore;
4043
AwsRequestId = eventCount.ToString("D12");
4144
EventJson = eventJson;
45+
46+
if (isRequestResponseMode)
47+
{
48+
_resetEvent = new ManualResetEventSlim(false);
49+
}
4250
}
4351

4452
public string FunctionArn
@@ -51,6 +59,12 @@ public void ReportSuccessResponse(string response)
5159
LastUpdated = DateTime.Now;
5260
Response = response;
5361
EventStatus = Status.Success;
62+
63+
if (_resetEvent != null)
64+
{
65+
_resetEvent.Set();
66+
}
67+
5468
_dataStore.RaiseStateChanged();
5569
}
5670

@@ -60,6 +74,50 @@ public void ReportErrorResponse(string errorType, string errorBody)
6074
ErrorType = errorType;
6175
ErrorResponse = errorBody;
6276
EventStatus = Status.Failure;
77+
78+
if (_resetEvent != null)
79+
{
80+
_resetEvent.Set();
81+
}
82+
6383
_dataStore.RaiseStateChanged();
6484
}
85+
86+
public bool WaitForCompletion()
87+
{
88+
if (_resetEvent == null)
89+
{
90+
return false;
91+
}
92+
93+
// The 15 minutes is a fail safe so we at some point we unblock the thread. It is intentionally
94+
// long to give the user time to debug the Lambda function.
95+
return _resetEvent.Wait(TimeSpan.FromMinutes(15));
96+
}
97+
98+
public void Dispose()
99+
{
100+
Dispose(true);
101+
GC.SuppressFinalize(this);
102+
}
103+
104+
private bool _disposed = false;
105+
protected virtual void Dispose(bool disposing)
106+
{
107+
if (_disposed)
108+
{
109+
return;
110+
}
111+
112+
if (disposing)
113+
{
114+
if (_resetEvent != null)
115+
{
116+
_resetEvent.Dispose();
117+
_resetEvent = null;
118+
}
119+
}
120+
121+
_disposed = true;
122+
}
65123
}

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

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

44
using Amazon.Lambda.TestTool.Commands.Settings;
@@ -37,7 +37,7 @@ public static TestToolProcess Startup(RunCommandSettings settings, CancellationT
3737
{
3838
var builder = WebApplication.CreateBuilder();
3939

40-
builder.Services.AddSingleton<IRuntimeApiDataStore, RuntimeApiDataStore>();
40+
builder.Services.AddSingleton<IRuntimeApiDataStoreManager, RuntimeApiDataStoreManager>();
4141

4242
// Add services to the container.
4343
builder.Services.AddRazorComponents()
@@ -65,7 +65,7 @@ public static TestToolProcess Startup(RunCommandSettings settings, CancellationT
6565
app.MapRazorComponents<App>()
6666
.AddInteractiveServerRenderMode();
6767

68-
_ = new LambdaRuntimeApi(app, app.Services.GetService<IRuntimeApiDataStore>()!);
68+
LambdaRuntimeApi.SetupLambdaRuntimeApiEndpoints(app);
6969

7070
var runTask = app.RunAsync(cancellationToken);
7171

0 commit comments

Comments
 (0)