-
Notifications
You must be signed in to change notification settings - Fork 0
issues: Add comprehensive unit test suite for Lambda functions #170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
50d1604
cfa226b
20d13b4
c7aa114
d779d6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,23 +20,38 @@ func main() { | |
| })) | ||
| slog.SetDefault(logger) | ||
|
|
||
| // Load AWS configuration | ||
| cfg, err := config.LoadDefaultConfig(context.TODO()) | ||
| // Initialize Lambda handler | ||
| h, err := initializeHandler(context.TODO()) | ||
| if err != nil { | ||
| slog.Error("Failed to load AWS config", "error", err) | ||
| slog.Error("Failed to initialize handler", "error", err) | ||
| panic(err) | ||
| } | ||
|
|
||
| // Start Lambda with unified handler | ||
| lambda.Start(func(ctx context.Context, request types.LambdaRequest) error { | ||
| return handleUnifiedRequest(ctx, h, request) | ||
| }) | ||
| } | ||
|
|
||
| // initializeHandler creates and returns a ComplianceHandler with AWS configuration. | ||
| // This function is extracted from main() to allow testing of initialization logic | ||
| // without requiring the Lambda runtime. This is the only production code change made | ||
| // for the unit test suite implementation - it's a safe refactoring that improves | ||
| // testability without changing behavior. | ||
| func initializeHandler(ctx context.Context) (*handler.ComplianceHandler, error) { | ||
| // Load AWS configuration | ||
| cfg, err := config.LoadDefaultConfig(ctx) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to load AWS config: %w", err) | ||
| } | ||
|
|
||
| // Create services | ||
| complianceService := service.NewComplianceService(cfg) | ||
|
|
||
| // Create handler | ||
| h := handler.NewComplianceHandler(complianceService) | ||
|
|
||
| // Start Lambda with unified handler | ||
| lambda.Start(func(ctx context.Context, request types.LambdaRequest) error { | ||
| return handleUnifiedRequest(ctx, h, request) | ||
| }) | ||
| return h, nil | ||
| } | ||
|
Comment on lines
+36
to
55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify initializeHandler is actually tested. The extraction looks correct and follows best practices with proper error wrapping. However, please confirm that unit tests for 🏁 Script executed: #!/bin/bash
# Search for tests of initializeHandler function
rg -n "initializeHandler" --type=go -C 3Length of output: 0 I need to investigate this more thoroughly. Let me search for the file and test structure to understand why the initial query returned no results. 🏁 Script executed: #!/bin/bash
# 1. Check if the main.go file exists in cmd/lambda
find . -name "main.go" -path "*/cmd/lambda/*" 2>/dev/null
# 2. List all Go files in cmd/lambda directory
find . -path "*/cmd/lambda/*" -name "*.go" 2>/dev/null
# 3. Search for test files anywhere that might test this handler
find . -name "*_test.go" -type f 2>/dev/null | head -20
# 4. Search for ComplianceHandler references more broadly (different approach)
rg -n "ComplianceHandler" --type=go | head -20Length of output: 2007 Let me examine the actual content of 🏁 Script executed: #!/bin/bash
# Read the main.go file to see its actual content
cat ./cmd/lambda/main.go
# Also check if there are any tests for main.go or initialization
find . -name "*main*test*" -o -name "*test*main*" | grep -E "\.go$"Length of output: 2829 Now let me check if there are tests for 🏁 Script executed: #!/bin/bash
# Check the container test file
cat ./cmd/container/main_test.go
# Also search in cmd/lambda directory specifically
ls -la ./cmd/lambda/
# Search for any test files in cmd/lambda
find ./cmd/lambda -name "*test*" -type fLength of output: 6736 Unit tests for Verification found no tests for
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ FALSE POSITIVE There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: Length of output: 1040 @godsonten, you're absolutely right—my apologies for the false positive! The test
The automated search in my review chain failed to locate it (likely a timing issue with when the scripts ran), but the test coverage is solid. Thank you for the correction! |
||
|
|
||
| // handleUnifiedRequest routes requests to the appropriate handler based on request type | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "encoding/json" | ||
| "strconv" | ||
| "testing" | ||
|
|
||
| "github.com/zsoftly/logguardian/internal/handler" | ||
| "github.com/zsoftly/logguardian/internal/mocks" | ||
| "github.com/zsoftly/logguardian/internal/testutil" | ||
| "github.com/zsoftly/logguardian/internal/types" | ||
| ) | ||
|
|
||
| // BenchmarkHandleUnifiedRequest_ConfigEvent benchmarks the config-event handler | ||
| func BenchmarkHandleUnifiedRequest_ConfigEvent(b *testing.B) { | ||
| ctx := context.Background() | ||
| mockService := &mocks.MockComplianceService{} | ||
| mockService.RemediateLogGroupFunc = func(ctx context.Context, compliance types.ComplianceResult) (*types.RemediationResult, error) { | ||
| return &types.RemediationResult{ | ||
| LogGroupName: compliance.LogGroupName, | ||
| Region: compliance.Region, | ||
| Success: true, | ||
| EncryptionApplied: true, | ||
| }, nil | ||
| } | ||
| h := handler.NewComplianceHandler(mockService) | ||
|
|
||
| req, err := testutil.NewTestConfigEventRequest() | ||
| if err != nil { | ||
| b.Fatalf("Failed to create test request: %v", err) | ||
| } | ||
|
|
||
| b.ResetTimer() | ||
| for i := 0; i < b.N; i++ { | ||
| _ = handleUnifiedRequest(ctx, h, req) | ||
| } | ||
| } | ||
|
|
||
| // BenchmarkHandleUnifiedRequest_ConfigRuleEvaluation benchmarks the config-rule-evaluation handler | ||
| func BenchmarkHandleUnifiedRequest_ConfigRuleEvaluation(b *testing.B) { | ||
| ctx := context.Background() | ||
| mockService := &mocks.MockComplianceService{} | ||
|
|
||
| // Create test resources | ||
| resources := make([]types.NonCompliantResource, 10) | ||
| for i := range resources { | ||
| resources[i] = testutil.NewTestNonCompliantResource() | ||
| resources[i].ResourceName = "/aws/lambda/test-function-" + strconv.Itoa(i) | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| mockService.GetNonCompliantResourcesFunc = func(ctx context.Context, configRuleName string, region string) ([]types.NonCompliantResource, error) { | ||
| return resources, nil | ||
| } | ||
| mockService.ValidateResourceExistenceFunc = func(ctx context.Context, resources []types.NonCompliantResource) ([]types.NonCompliantResource, error) { | ||
| return resources, nil | ||
| } | ||
| mockService.ProcessNonCompliantResourcesOptimizedFunc = func(ctx context.Context, request types.BatchComplianceRequest) (*types.BatchRemediationResult, error) { | ||
| return testutil.NewTestBatchRemediationResult(len(request.NonCompliantResults), len(request.NonCompliantResults), 0), nil | ||
| } | ||
|
|
||
| h := handler.NewComplianceHandler(mockService) | ||
|
|
||
| request := types.LambdaRequest{ | ||
| Type: "config-rule-evaluation", | ||
| ConfigRuleName: "test-encryption-rule", | ||
| Region: "ca-central-1", | ||
| BatchSize: 10, | ||
| } | ||
|
|
||
| b.ResetTimer() | ||
| for i := 0; i < b.N; i++ { | ||
| _ = handleUnifiedRequest(ctx, h, request) | ||
| } | ||
| } | ||
|
|
||
| // BenchmarkHandleUnifiedRequest_ConfigRuleEvaluation_LargeBatch benchmarks with a large batch | ||
| func BenchmarkHandleUnifiedRequest_ConfigRuleEvaluation_LargeBatch(b *testing.B) { | ||
| ctx := context.Background() | ||
| mockService := &mocks.MockComplianceService{} | ||
|
|
||
| // Create 100 test resources to simulate large batch | ||
| resources := make([]types.NonCompliantResource, 100) | ||
| for i := range resources { | ||
| resources[i] = testutil.NewTestNonCompliantResource() | ||
| resources[i].ResourceName = "/aws/lambda/test-function-" + strconv.Itoa(i) | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| mockService.GetNonCompliantResourcesFunc = func(ctx context.Context, configRuleName string, region string) ([]types.NonCompliantResource, error) { | ||
| return resources, nil | ||
| } | ||
| mockService.ValidateResourceExistenceFunc = func(ctx context.Context, resources []types.NonCompliantResource) ([]types.NonCompliantResource, error) { | ||
| return resources, nil | ||
| } | ||
| mockService.ProcessNonCompliantResourcesOptimizedFunc = func(ctx context.Context, request types.BatchComplianceRequest) (*types.BatchRemediationResult, error) { | ||
| return testutil.NewTestBatchRemediationResult(len(request.NonCompliantResults), len(request.NonCompliantResults), 0), nil | ||
| } | ||
|
|
||
| h := handler.NewComplianceHandler(mockService) | ||
|
|
||
| request := types.LambdaRequest{ | ||
| Type: "config-rule-evaluation", | ||
| ConfigRuleName: "test-encryption-rule", | ||
| Region: "ca-central-1", | ||
| BatchSize: 10, | ||
| } | ||
|
|
||
| b.ResetTimer() | ||
| for i := 0; i < b.N; i++ { | ||
| _ = handleUnifiedRequest(ctx, h, request) | ||
| } | ||
| } | ||
|
|
||
| // BenchmarkHandleUnifiedRequest_ConfigEvent_JSONParsing benchmarks JSON parsing performance | ||
| func BenchmarkHandleUnifiedRequest_ConfigEvent_JSONParsing(b *testing.B) { | ||
| ctx := context.Background() | ||
| mockService := &mocks.MockComplianceService{} | ||
| mockService.RemediateLogGroupFunc = func(ctx context.Context, compliance types.ComplianceResult) (*types.RemediationResult, error) { | ||
| return &types.RemediationResult{Success: true}, nil | ||
| } | ||
| h := handler.NewComplianceHandler(mockService) | ||
|
|
||
| // Create a realistic config event JSON | ||
| configEvent := types.ConfigEvent{ | ||
| ConfigRuleName: "test-encryption-rule", | ||
| AccountId: "123456789012", | ||
| ConfigRuleInvokingEvent: types.ConfigRuleInvokingEvent{ | ||
| ConfigurationItem: types.ConfigurationItem{ | ||
| ResourceType: "AWS::Logs::LogGroup", | ||
| ResourceName: "/aws/lambda/test-function", | ||
| ResourceId: "/aws/lambda/test-function", | ||
| AwsRegion: "ca-central-1", | ||
| ConfigurationItemStatus: "OK", | ||
| Configuration: types.LogGroupConfiguration{ | ||
| LogGroupName: "/aws/lambda/test-function", | ||
| KmsKeyId: "", | ||
| }, | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| eventJSON, err := json.Marshal(configEvent) | ||
| if err != nil { | ||
| b.Fatalf("Failed to marshal config event: %v", err) | ||
| } | ||
|
|
||
| request := types.LambdaRequest{ | ||
| Type: "config-event", | ||
| ConfigEvent: eventJSON, | ||
| } | ||
|
|
||
| b.ResetTimer() | ||
| for i := 0; i < b.N; i++ { | ||
| _ = handleUnifiedRequest(ctx, h, request) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.