Skip to content

Commit 4422cca

Browse files
committed
Add more tests
1 parent bb4d25d commit 4422cca

2 files changed

Lines changed: 175 additions & 0 deletions

File tree

Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.IntegrationTests/ApiGatewayStreamingTests.cs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,91 @@ public async Task StreamingErrorEndpoint_StreamIsTruncated()
127127
_output.WriteLine($"Expected error: {ex.Message}");
128128
}
129129
}
130+
131+
[Fact]
132+
public async Task OnCompletedCallback_IsExecuted()
133+
{
134+
var apiUrl = await _fixture.GetApiUrlAsync();
135+
using var httpClient = new HttpClient();
136+
137+
// First request registers the OnCompleted callback
138+
var response = await httpClient.GetWithRetryAsync($"{apiUrl}oncompleted-test");
139+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
140+
var body = await response.Content.ReadAsStringAsync();
141+
_output.WriteLine($"Body: {body}");
142+
Assert.Contains("OnCompleted callback registered", body);
143+
144+
// Second request verifies the callback was executed
145+
var verifyResponse = await httpClient.GetWithRetryAsync($"{apiUrl}oncompleted-verify");
146+
Assert.Equal(HttpStatusCode.OK, verifyResponse.StatusCode);
147+
var verifyBody = await verifyResponse.Content.ReadAsStringAsync();
148+
_output.WriteLine($"Verify body: {verifyBody}");
149+
150+
var doc = JsonDocument.Parse(verifyBody);
151+
Assert.True(doc.RootElement.GetProperty("onCompletedExecuted").GetBoolean(),
152+
"OnCompleted callback should have been executed");
153+
}
154+
155+
[Fact]
156+
public async Task CustomHeaders_PassedThroughApiGateway()
157+
{
158+
var apiUrl = await _fixture.GetApiUrlAsync();
159+
using var httpClient = new HttpClient();
160+
161+
var response = await httpClient.GetWithRetryAsync($"{apiUrl}custom-headers", HttpStatusCode.Created);
162+
163+
_output.WriteLine($"Status: {response.StatusCode}");
164+
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
165+
166+
var body = await response.Content.ReadAsStringAsync();
167+
Assert.Contains("Custom headers response", body);
168+
169+
// Verify custom headers are present in the response
170+
Assert.True(response.Headers.Contains("X-Custom-Header"), "X-Custom-Header should be present");
171+
Assert.Equal("custom-value", response.Headers.GetValues("X-Custom-Header").First());
172+
Assert.True(response.Headers.Contains("X-Another-Header"), "X-Another-Header should be present");
173+
Assert.Equal("another-value", response.Headers.GetValues("X-Another-Header").First());
174+
}
175+
176+
[Fact]
177+
public async Task SetCookie_PassedThroughApiGateway()
178+
{
179+
var apiUrl = await _fixture.GetApiUrlAsync();
180+
var handler = new HttpClientHandler { UseCookies = false };
181+
using var httpClient = new HttpClient(handler);
182+
183+
var response = await httpClient.GetWithRetryAsync($"{apiUrl}set-cookie");
184+
185+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
186+
187+
var body = await response.Content.ReadAsStringAsync();
188+
_output.WriteLine($"Body: {body}");
189+
Assert.Contains("Cookies set", body);
190+
191+
// Verify Set-Cookie headers are present
192+
Assert.True(response.Headers.Contains("Set-Cookie"), "Set-Cookie header should be present");
193+
var cookies = response.Headers.GetValues("Set-Cookie").ToList();
194+
_output.WriteLine($"Cookies: {string.Join("; ", cookies)}");
195+
Assert.True(cookies.Any(c => c.Contains("session=abc123")), "session cookie should be present");
196+
Assert.True(cookies.Any(c => c.Contains("theme=dark")), "theme cookie should be present");
197+
}
198+
199+
[Fact]
200+
public async Task PostWithBody_EchoesRequestBody()
201+
{
202+
var apiUrl = await _fixture.GetApiUrlAsync();
203+
using var httpClient = new HttpClient();
204+
205+
var content = new StringContent("Hello from integration test", Encoding.UTF8, "text/plain");
206+
var response = await httpClient.PostWithRetryAsync($"{apiUrl}echo-body", content);
207+
208+
_output.WriteLine($"Status: {response.StatusCode}");
209+
var body = await response.Content.ReadAsStringAsync();
210+
_output.WriteLine($"Body: {body}");
211+
212+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
213+
Assert.Contains("Echo: Hello from integration test", body);
214+
}
130215
}
131216

132217
internal static class HttpClientExtension
@@ -151,6 +236,27 @@ public static async Task<HttpResponseMessage> GetWithRetryAsync(this HttpClient
151236
}
152237
throw new Exception($"Failed to get expected status code {expectedCode} from {url} after {maxRetries} attempts");
153238
}
239+
240+
public static async Task<HttpResponseMessage> PostWithRetryAsync(this HttpClient httpClient, string url, HttpContent content, HttpStatusCode expectedCode = HttpStatusCode.OK, int maxRetries = 5, int delaySeconds = 5)
241+
{
242+
for (var i = 0; i < maxRetries; i++)
243+
{
244+
try
245+
{
246+
var response = await httpClient.PostAsync(url, content);
247+
if (response.StatusCode == expectedCode)
248+
{
249+
return response;
250+
}
251+
}
252+
catch
253+
{
254+
// Ignore and retry
255+
}
256+
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
257+
}
258+
throw new Exception($"Failed to get expected status code {expectedCode} from {url} after {maxRetries} attempts");
259+
}
154260
}
155261

156262
/// <summary>

Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/AspNetCoreStreamingApiGatewayTest/Program.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,73 @@
5353
return Results.Json(new { message = "Hello from streaming Lambda", timestamp = DateTime.UtcNow.ToString("o") });
5454
});
5555

56+
app.MapGet("/oncompleted-test", async (HttpContext context) =>
57+
{
58+
// Register an OnCompleted callback that writes a marker to a response header.
59+
// Since headers are sent in the prelude before the body, we use a different approach:
60+
// write a marker into the body from the OnCompleted callback via a shared flag.
61+
var completedMarker = new CompletedMarker();
62+
context.Response.RegisterForDispose(completedMarker);
63+
64+
context.Response.OnCompleted(async (state) =>
65+
{
66+
var marker = (CompletedMarker)state;
67+
marker.WasExecuted = true;
68+
// Write to a static so the next request can verify it ran
69+
CompletedMarkerStore.LastMarkerExecuted = true;
70+
}, completedMarker);
71+
72+
context.Response.ContentType = "text/plain";
73+
context.Response.StatusCode = 200;
74+
75+
var stream = context.Response.BodyWriter.AsStream();
76+
using var writer = new StreamWriter(stream, leaveOpen: true);
77+
await writer.WriteAsync("OnCompleted callback registered");
78+
await writer.FlushAsync();
79+
});
80+
81+
app.MapGet("/oncompleted-verify", (HttpContext context) =>
82+
{
83+
// Returns whether the OnCompleted callback from the previous request was executed
84+
return Results.Json(new { onCompletedExecuted = CompletedMarkerStore.LastMarkerExecuted });
85+
});
86+
87+
app.MapGet("/custom-headers", (HttpContext context) =>
88+
{
89+
context.Response.StatusCode = 201;
90+
context.Response.ContentType = "text/plain";
91+
context.Response.Headers["X-Custom-Header"] = "custom-value";
92+
context.Response.Headers["X-Another-Header"] = "another-value";
93+
return Results.Text("Custom headers response", "text/plain", statusCode: 201);
94+
});
95+
96+
app.MapGet("/set-cookie", (HttpContext context) =>
97+
{
98+
context.Response.Cookies.Append("session", "abc123", new CookieOptions
99+
{
100+
Path = "/",
101+
HttpOnly = true
102+
});
103+
context.Response.Cookies.Append("theme", "dark");
104+
return Results.Text("Cookies set");
105+
});
106+
107+
app.MapPost("/echo-body", async (HttpContext context) =>
108+
{
109+
using var reader = new StreamReader(context.Request.Body);
110+
var body = await reader.ReadToEndAsync();
111+
return Results.Text($"Echo: {body}");
112+
});
113+
56114
app.Run();
115+
116+
class CompletedMarker : IDisposable
117+
{
118+
public bool WasExecuted { get; set; }
119+
public void Dispose() { }
120+
}
121+
122+
static class CompletedMarkerStore
123+
{
124+
public static bool LastMarkerExecuted { get; set; }
125+
}

0 commit comments

Comments
 (0)