diff --git a/docs/testing.md b/docs/testing.md index 832eeb6..1a056f1 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -205,11 +205,11 @@ password rotation last. Each subtest pins one AWS seam: discovery → `dbconn` connect → PG-major assertion → DDL smoke; - **control-plane error contract** — unknown identifiers and duplicate creations surface as the AWS SDK's typed RDS faults, matched with - `errors.As`. One documented emulator divergence: Ministack emits the - duplicate-instance wire code with a `Fault` suffix real AWS omits, so - the SDK leaves it a generic API error. The test pins the divergent code - exactly — it fails the day the emulator is fixed, forcing the - workaround's removal in favor of the typed match production code uses; + `errors.As` — exactly the match production code uses. (An earlier + emulator divergence — a `Fault` suffix on the duplicate-instance wire + code that real AWS omits — was fixed upstream in Ministack v1.4.14 at + pg-sprite's request; the pinned image carries the fix, so no divergence + workaround remains); - **password rotation** — what a rotation does to a running schema change (see below), plus pg-sprite's contract that the resulting auth failure is terminal, not retryable. diff --git a/internal/testutil/ministack.go b/internal/testutil/ministack.go index e020c13..1a076cf 100644 --- a/internal/testutil/ministack.go +++ b/internal/testutil/ministack.go @@ -88,30 +88,33 @@ func ministackImage() string { if img := os.Getenv("MINISTACK_IMAGE"); img != "" { return img } - return "ministackorg/ministack:1.4.13-full" + return "ministackorg/ministack:1.4.15-full" } // auroraEngineVersion returns a real aurora-postgresql engine version for -// the requested major. Real RDS requires a full version string ("16.6"), -// not a bare major — Ministack is lenient, but this tier exists to -// rehearse calls the way the real control plane requires, so the request -// is constructed as AWS would accept it. The exact minor is immaterial: -// Ministack derives the sibling database image from the major, and the -// test asserts the running server's major independently. +// the requested major. Real RDS requires a full version string ("16.14"), +// not a bare major, and Ministack validates the version against its +// creatable catalog at create time — an unknown version fails with the +// AWS-exact InvalidParameterCombination, so each entry here must be a +// version the pinned image advertises via DescribeDBEngineVersions. The +// exact minor is immaterial beyond that: Ministack derives the sibling +// database image from the major, and the test asserts the running +// server's major independently. func auroraEngineVersion(major int) string { versions := map[int]string{ - 14: "14.15", - 15: "15.10", - 16: "16.6", - 17: "17.4", - 18: "18.3", + 14: "14.23", + 15: "15.18", + 16: "16.14", + 17: "17.10", + 18: "18.4", } if v, ok := versions[major]; ok { return v } - // A major newer than this map: fall back to ".1" so the call - // still carries a full version string. - return fmt.Sprintf("%d.1", major) + // A major newer than this map: fall back to the bare major, which the + // emulator's validator accepts as a dot-boundary prefix of any + // catalog entry for that major. + return strconv.Itoa(major) } // AuroraCluster is a provisioned Ministack aurora-postgresql cluster and diff --git a/internal/testutil/ministack_integration_test.go b/internal/testutil/ministack_integration_test.go index c2196b9..ecaa883 100644 --- a/internal/testutil/ministack_integration_test.go +++ b/internal/testutil/ministack_integration_test.go @@ -10,7 +10,6 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go-v2/service/rds/types" - "github.com/aws/smithy-go" "github.com/jackc/pgx/v5/pgconn" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -98,18 +97,9 @@ func errorContract(t *testing.T, cluster *testutil.AuroraCluster) { Engine: aws.String("aurora-postgresql"), DBInstanceClass: aws.String("db.t3.medium"), }) - // Real AWS emits wire code "DBInstanceAlreadyExists", which the SDK - // maps to types.DBInstanceAlreadyExistsFault — production code must - // match that typed fault with errors.As, exactly like the two cases - // above. Ministack diverges: it emits "DBInstanceAlreadyExistsFault", - // which the SDK leaves as a generic API error. Pin the divergent code - // exactly so this assertion fails the day the emulator is fixed, and - // this workaround is replaced by the typed errors.As match. - var apiErr smithy.APIError - require.ErrorAs(t, err, &apiErr, - "creating a duplicate instance must surface an RDS API error") - require.Equal(t, "DBInstanceAlreadyExistsFault", apiErr.ErrorCode(), - "emulator no longer emits its divergent duplicate-instance code — assert types.DBInstanceAlreadyExistsFault with errors.As instead of this pin") + var instanceExists *types.DBInstanceAlreadyExistsFault + require.ErrorAs(t, err, &instanceExists, + "creating a duplicate instance must surface the typed already-exists fault") } // passwordRotation proves what a master-password rotation does to a