feat(testing): add MinimalLambda.Testing package#233
Merged
Conversation
- Added a new project `AwsLambda.Host.Testing` to support unit testing for AwsLambda.Host. - Configured multi-targeting for .NET 8.0, 9.0, and 10.0 with preview language features. - Included necessary metadata for NuGet packaging, including README file support. - Updated solution file to include the new project.
- Introduced new example project to demonstrate testing with AwsLambda.Host. - Configured the project to target .NET 10.0 with appropriate properties and metadata. - Added basic Lambda handler implementation with a `name` parameter. - Included `appsettings.json` for logging configuration. - Configured `launchSettings.json` for local testing with mock runtime. - Updated solution to include the new example project.
…ing setup - Added `LambdaHostTest` class with a sample test for validating Lambda host functionality. - Configured necessary testing dependencies like xUnit, NSubstitute, and coverlet.collector. - Included `appsettings.json` with `PreserveNewest` copy directive for output directory.
- Introduced `DeferredHostBuilder` to enable deferred execution of IHostBuilder configuration. - Added support for capturing and replaying configuration calls with `ConfigureHostBuilder`. - Implemented `DeferredHost` to manage deferred host startup and ensure proper disposal. - Linked implementation with MIT-licensed parts from aspnetcore, providing proper attribution.
- Introduced `LambdaApplicationFactory` for managing and testing Lambda application lifecycle. - Implemented proper disposal handling with `Dispose` and `DisposeAsync` methods. - Ensured compatibility with `IHost` for seamless integration and teardown.
- Added detailed examples for AWS Lambda local invocation happy and error paths. - Included formatted HTTP request and response content for better understanding. - Documented the error handling flow, including stack traces and error serialization.
- Added attribution to aspnetcore's `WebApplicationFactory.cs` under the MIT license. - Included reference to the source repository and license file for transparency. - Updated header comments in `LambdaApplicationFactory.cs` for proper acknowledgment.
- Introduced `LoggingHttpHandler` for detailed HTTP request and response logging. - Updated `Program.cs` to configure `BootstrapHttpClient` using `LoggingHttpHandler`. - Enabled `ClearLambdaOutputFormatting` for better Lambda output readability.
- Changed version extraction from `<VersionPrefix>` to `<Version>` in `Directory.Build.props`. - Updated error message to reflect the new version tag.
- Added `HostFactoryResolver`, copied and adapted from .NET runtime's implementation. - Enables dynamic resolution and creation of `IHost` and `IServiceProvider` for testing scenarios. - Included proper licensing attribution in the file header. - Ensures compatibility with diagnostic event-based host building patterns.
- Updated copyright notices to include ".NET Foundation and Contributors" in relevant files. - Added new entry for the .NET runtime license to THIRD-PARTY-LICENSES.txt. - Ensured consistency in licensing attribution across files for proper acknowledgment.
- Added `.csharpierignore` to exclude specific files from formatting checks. - Updated `.editorconfig` to disable formatting for `HostFactoryResolver.cs`. - Included `.csharpierignore` and `.editorconfig` in the solution file (`AwsLambda.Host.sln`).
…stingHttpHandler - Introduced `LambdaApplicationFactoryClientOptions` for customizing test client configurations. - Added `LambdaTestingHttpHandler` for handling HTTP-specific test scenarios. - Extended `LambdaApplicationFactory` to improve support for Lambda app testing workflows.
- Replaced IWebHostBuilder with IHostBuilder across LambdaApplicationFactory. - Updated documentation to reflect the use of IHostBuilder methods and patterns. - Simplified host configuration by deprecating IWebHostBuilder-specific logic.
- Added `Microsoft.AspNetCore.Routing` as a package reference in the Testing project. - Updated `Directory.Packages.props` to include `Microsoft.AspNetCore.Routing` version 2.3.0.
…data - Introduced `ErrorResponse` model for consistent error representation in testing scenarios. - Added nested `ErrorCause` class to handle detailed error information with potential nested causes. - Included JSON serialization attributes for seamless JSON handling.
…ementation
- Introduced `LambdaRuntimeRouteManager` and `ILambdaRuntimeRouteManager` for route matching logic.
- Implemented support for matching HTTP requests to specific Lambda runtime routes.
- Defined route templates for `/invocation/next`, `/invocation/{requestId}/response`, and `/invocation/{requestId}/error`.
- Utilized `TemplateMatcher` for parsing and matching route templates.
…fication - Introduced `RequestType` enum with values: `GetNextInvocation`, `PostResponse`, and `PostError`. - Enables clear categorization of Lambda runtime request types in testing scenarios.
- Introduced `InvocationResponse<TResponse>` for modeling Lambda invocation outcomes. - Added `WasSuccess`, `Response`, and `Error` properties for detailed testing scenarios.
- Introduced `LambdaBootstrapRequest` model to encapsulate Lambda runtime request data. - Added `RequestType`, `RequestMessage`, and `RouteValue` properties as required fields. - Implemented `RequestId` property using `RouteValueDictionary` for request identification.
- Introduced `LambdaClient` to handle Lambda runtime requests in testing scenarios. - Implemented `WaitForBootstrapAsync` to process bootstrap-specific requests. - Added `WaitForRequestAsync` with support for route matching using `ILambdaRuntimeRouteManager`. - Included `Invoke<TEvent, TResponse>` method for serializing events and initiating invocation responses.
… channel support - Added constructor to `LambdaTestingHttpHandler` accepting request and response channels. - Implemented `SendAsync` to pass requests to `requestChannel` and receive responses from `responseChannel`.
- Replaced hardcoded "2018-06-01" route version with a dynamic "{version}" placeholder.
- Updated route templates for `GetNextInvocation`, `PostResponse`, and `PostError` requests.
- Improved flexibility and compatibility for handling versioned Lambda runtime paths.
…e handling - Introduced `LambdaClientOptions` to configure response headers for Lambda invocations. - Added `LambdaInvocationHeaders` to customize attributes like date, chunked transfer, and AWS metadata. - Enhanced `Invoke` method to return a mocked `HttpResponseMessage` with serialized invocation data.
- Added `LambdaClientOptions` as a configurable option for `LambdaClient`. - Implemented `ConfigureOptions` method to allow runtime customization of `LambdaClientOptions`. - Ensured null-check for `configureOptions` to prevent potential null reference exceptions.
…` method in `LambdaClient` - Moved request creation code from `Invoke<TEvent, TResponse>` to a new private method `CreateRequest<TEvent>`. - Simplified `Invoke` by reusing the `CreateRequest` method. - Improved maintainability and readability by centralizing HTTP response setup logic. - Updated to use values from `LambdaClientOptions.InvocationHeaders` for response headers.
…and client configuration - Introduced `LambdaInvocationHeaderOptions` to define additional headers, metadata, and timeouts. - Added `LambdaClientOptions` to encapsulate and configure invocation header options.
…ient options - Reorganized `LambdaClientOptions` within `LambdaClient` for clarity and proper initialization. - Refactored response header setup to use `InvocationHeaderOptions` for better flexibility. - Added support for calculating dynamic `DeadlineMs` header based on function timeout. - Enabled adding custom additional headers via `InvocationHeaderOptions.AdditionalHeaders`.
…in LambdaClient - Replaced `RequestId` with `InvocationCounter` to generate zero-padded 12-digit request IDs. - Incremented `InvocationCounter` after each invocation to ensure unique request IDs. - Renamed `Invoke` to `InvokeAsync` for consistency with asynchronous method naming conventions.
- Renamed `WaitForBootstrapAsync` to `WaitForNextRequestAsync` for improved clarity. - Refactored `Invoke` response logic to handle success and error scenarios more robustly. - Added support for serializing invocation responses including success status and error details. - Simplified the invocation flow to improve readability and maintainability.
- Introduced `SimpleLambda_WorksWhenInvokeCalledMultipleTimes_WithoutStart` unit test. - Validated concurrent invocations with expected responses in order. - Ensured successful execution without requiring initial `Start`.
- Replaced hardcoded exception messages with interpolated strings using `nameof(LambdaTestServer)`. - Enhanced clarity by including current and expected server states in specific exceptions. - Ensured consistency and maintainability of error messages throughout the code.
…' into feature/#185-add-testing-package
- Introduced `InitAlreadyCompleted` to `InitStatus` for improved state representation. - Updated `StartAsync` to return `InitAlreadyCompleted` when already initialized. - Modified state checks to handle `InitAlreadyCompleted` in initialization flow. - Adjusted error handling logic for enhanced clarity and accurate status reporting.
Collaborator
Author
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Introduced new extension methods for `LambdaTestServer` to simplify invocation patterns. - `InvokeAsync<TEvent, TResponse>`: Simplifies invoking Lambda with an event and expecting a response. - `InvokeNoEventAsync<TResponse>`: Allows invocation without providing an event. - `InvokeNoResponseAsync<TEvent>`: Enables invocation with event but no response expectation. - Added comprehensive XML documentation to assist with usage and clarify behavior. - Improved usability by wrapping `LambdaTestServer.InvokeAsync` for common scenarios.
- Extracted `InvocationResponse<TResponse>` from `InvocationResponse` to enable typed responses. - Updated `InvocationResponse` to serve as the non-generic base class. - Added XML documentation for improved clarity of usage and behavior. - Marked all mutable properties on `InvocationResponse` classes with `init` for immutability.
- Replaced switch-case disposal logic with direct calls to `StopAsync` and `Dispose`. - Improved code clarity by replacing null check with `is not null`. - Ensured consistent async disposal flow for `_host` and `_server`.
…licationFactory` - Updated LINQ query to use discard (`_`) for unused `projects` variable. - Improved code readability and reduced unnecessary variable declaration.
…unit tests - Replaced all instances of `WithCancelationToken` with `WithCancellationToken`. - Ensured consistency in method naming throughout unit test implementations. - Updated XML documentation in `LambdaApplicationFactory` to reflect the corrected method name.
….WithHostBuilder`
- Updated XML documentation to reference `LambdaApplicationFactory{TEntryPoint}.WithHostBuilder`.
- Removed redundant `<see>` reference for `CreateHostBuilder` in the remarks section.
- Enhanced documentation clarity by aligning with standardized conventions.
… unused instance reference - Updated `LambdaRuntimeRouteManager` class to be static. - Removed unused `_routeManager` instance from `LambdaTestServer`. - Refactored code to use `LambdaRuntimeRouteManager.TryMatch` as a static method.
… `ErrorResponse` - Added `Causes` property to represent underlying causes in errors. - Updated `ErrorType` property with `required` modifier for stricter validation. - Included XML documentation for the new `Causes` property to enhance clarity.
…xtensionsTest` - Replaced explicit type declaration with target-typed `new()` for `_dictionary`. - Improved code readability and adhered to modern C# conventions.
- Added `_pendingInvocations.TryRemove` call to ensure request ID is removed after processing. - Prevents potential memory leaks and ensures proper cleanup of pending invocations.
…`StartAsync` - Added a check to ensure `_startSemaphore.Release` is only called if the semaphore was acquired. - Prevents potential release errors when the semaphore was not successfully acquired.
ncipollina
reviewed
Dec 13, 2025
- Moved `StopAsync` call in `LambdaTestServer.DisposeAsync` to align with proper server state handling. - Replaced `StartAsync` with synchronous `_host.Start` to prevent unnecessary token usage. - Updated `WhenAll` call in `StopAsync` to handle null `_processingTask` safely. - Simplified host disposal in `LambdaApplicationFactory` by removing redundant `StopAsync`.
… inline - Removed `_server` instance and replaced with inline factory instance in `SimpleLambdaTests`. - Improved resource management by using `await using` for factory disposal. - Enhanced code maintainability by avoiding explicit constructor setup for factory.
…ests` - Replaced `_server` field with inline `LambdaApplicationFactory` instances. - Improved resource management using `await using` for factory disposal. - Simplified test setup by avoiding a constructor-based factory initialization.
…d `NoEventLambdaTests` - Replaced `_server` field with inline `LambdaApplicationFactory` instances. - Enhanced resource management by utilizing `await using` for factory disposal. - Simplified test setup by removing constructor-based factory initialization.
- Replaced `_host.Start()` with `await _host.StartAsync(cts.Token)` for asynchronous operation. - Ensures proper task handling and respects cancellation tokens during host startup.
…stApplicationLifetime` - Ensures `IHostApplicationLifetime` is resolved reliably during host startup. - Removes `AssemblyInfo.cs`, disabling test parallelization.
…explicitly - Added linked cancellation token source with timeout for `DiLambdaTests` to enhance reliability. - Updated `LambdaApplicationFactory` and `LambdaTestServer` to use `GetRequiredService` for resolving `IHostApplicationLifetime`. - Refactored `DeferredHost` to explicitly pass `IHostApplicationLifetime` and avoid redundant retrievals. - Simplified task completion logic in `DeferredHost` to ensure proper exception handling and cleanup.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



🚀 Pull Request
📋 Summary
This PR introduces the new
MinimalLambda.Testingpackage, providing a comprehensive testing infrastructure for MinimalLambda-based applications. The package enables integration testing of Lambda functions with full lifecycle simulation, dependency injection testing, and support for various Lambda handler patterns.Key Features:
LambdaApplicationFactory- Factory for creating test hosts based on ASP.NET Core testing patternsLambdaTestServer- In-memory test server that simulates the AWS Lambda Runtime APIDeferredHostBuilder- Support for deferred host configurationTesting Infrastructure:
Additional Changes:
LambdaHostedServiceDefaultLambdaJsonSerializerOptionsto abstractions✅ Checklist
🧪 Related Issues or PRs
Closes #185
💬 Notes for Reviewers
This is a substantial addition (~3,580 lines added) that establishes the foundation for testing MinimalLambda applications. The implementation is based on ASP.NET Core's
WebApplicationFactorypattern but adapted for Lambda's unique runtime model.Key areas to review:
LambdaTestServertransaction-based architecture for managing request/response cyclesHostFactoryResolvercontent root resolution logic (adapted from ASP.NET Core)The package includes comprehensive unit tests demonstrating various usage patterns and edge cases.