From c7f0e3451e0c15b39c38db483490019db5baa899 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Fri, 16 Oct 2026 03:40:09 +0200 Subject: [PATCH] test(cli): make engine-version error-handling tests hermetic TestQueryMajorEngineVersions_ErrorHandling and TestQueryRunningInstanceEngineVersions_ErrorHandling loaded the real AWS config and issued live API calls (34s and 9s per run), and only asserted inside `if err != nil`, so they passed whether or not credentials existed. Remove the major-versions test: profile precedence is covered by TestQueryMajorEngineVersions_ProfileSelection and engine failures by the stubbed TestQueryMajorEngineVersionsWithClient_* tests. Replace the running-instance test with TestQueryRunningInstanceEngineVersions_ProfileSelection, which uses isolateAWSEnv and nonexistent profiles so config loading fails before any AWS call, and unconditionally asserts the error names the selected profile. Region and engine failure paths already have stubbed tests (TestQueryRDSInstancesInRegions_*), so no production seam is added. Closes #1328 Co-Authored-By: Claude Opus 5.5 --- cmd/multi_service_engine_versions_test.go | 115 ++++++---------------- 1 file changed, 31 insertions(+), 84 deletions(-) diff --git a/cmd/multi_service_engine_versions_test.go b/cmd/multi_service_engine_versions_test.go index ef7fe2380..7c452fd95 100644 --- a/cmd/multi_service_engine_versions_test.go +++ b/cmd/multi_service_engine_versions_test.go @@ -11,6 +11,7 @@ import ( "github.com/LeanerCloud/cloud-commitments-go/pkg/common" rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAdjustRecommendationForExcludedVersions(t *testing.T) { @@ -775,100 +776,46 @@ func TestIsInExtendedSupport(t *testing.T) { } } -func TestQueryMajorEngineVersions_ErrorHandling(t *testing.T) { - // This test validates the error handling logic when AWS config fails - ctx := context.Background() - - tests := []struct { - name string - cfg Config - wantErr bool - }{ - { - name: "Empty profile - should use default credentials", - cfg: Config{ - Profile: "", - ValidationProfile: "", - }, - wantErr: false, // Will fail with real AWS but tests error path exists - }, - { - name: "With validation profile", - cfg: Config{ - Profile: "default", - ValidationProfile: "validation-profile", - }, - wantErr: false, - }, - { - name: "Fallback to main profile", - cfg: Config{ - Profile: "main-profile", - ValidationProfile: "", - }, - wantErr: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - // This will likely fail in test environment without real AWS credentials - // but it validates the function signature and basic logic paths - _, err := queryMajorEngineVersions(ctx, tt.cfg) - // We expect an error in test environment (no real AWS creds) - // The important thing is that the function doesn't panic - if err != nil { - assert.Regexp(t, "failed to load AWS config|major engine versions for", err.Error()) - } - }) - } -} - -func TestQueryRunningInstanceEngineVersions_ErrorHandling(t *testing.T) { - // This test validates the error handling logic - ctx := context.Background() - +// TestQueryRunningInstanceEngineVersions_ProfileSelection asserts the +// validation-profile precedence deterministically: the profiles name entries +// absent from the (redirected, empty) shared config, so config loading fails +// before any AWS call and the error names the profile actually selected. +// Engine-error and region-failure behavior is covered by the stubbed +// TestQueryMajorEngineVersionsWithClient_* and TestQueryRDSInstancesInRegions_*. +func TestQueryRunningInstanceEngineVersions_ProfileSelection(t *testing.T) { tests := []struct { - name string - cfg Config - wantErr bool + name string + profile string + validationProfile string + wantProfileInErr string }{ { - name: "Empty profile - should use default credentials", - cfg: Config{ - Profile: "", - ValidationProfile: "", - }, - wantErr: false, + name: "validation profile takes precedence", + profile: "cudly-test-main-profile-does-not-exist", + validationProfile: "cudly-test-validation-profile-does-not-exist", + wantProfileInErr: "cudly-test-validation-profile-does-not-exist", }, { - name: "With validation profile", - cfg: Config{ - Profile: "default", - ValidationProfile: "validation-profile", - }, - wantErr: false, - }, - { - name: "Fallback to main profile", - cfg: Config{ - Profile: "main-profile", - ValidationProfile: "", - }, - wantErr: false, + name: "falls back to main profile", + profile: "cudly-test-main-profile-does-not-exist", + wantProfileInErr: "cudly-test-main-profile-does-not-exist", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // This will likely fail in test environment without real AWS credentials - // but it validates the function signature and basic logic paths - _, _, err := queryRunningInstanceEngineVersions(ctx, tt.cfg) - // We expect an error in test environment (no real AWS creds) - // The important thing is that the function doesn't panic - if err != nil { - assert.Contains(t, err.Error(), "failed to") - } + isolateAWSEnv(t) + + instances, failed, err := queryRunningInstanceEngineVersions(context.Background(), Config{ + Profile: tt.profile, + ValidationProfile: tt.validationProfile, + }) + + require.Error(t, err) + assert.Nil(t, instances) + assert.Nil(t, failed) + assert.Contains(t, err.Error(), "failed to load validation AWS config") + assert.Contains(t, err.Error(), tt.wantProfileInErr, "error must name the selected profile") }) } }