Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion internal/testing/require/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,25 @@ import (
// StatusError returns the [metav1.Status] within err's tree.
// It calls t.Fatal when err is nil or there is no status.
func StatusError(t testing.TB, err error) metav1.Status {
status, ok := err.(apierrors.APIStatus)
t.Helper()

status, ok := err.(apierrors.APIStatus)
assert.Assert(t, ok || errors.As(err, &status),
"%T does not implement %T", err, status)

return status.Status()
}

// StatusErrorDetails returns the details of [metav1.Status] within err's tree.
// It calls t.Fatal when err is nil, there is no status, or its Details field is nil.
func StatusErrorDetails(t testing.TB, err error) metav1.StatusDetails {
t.Helper()

status := StatusError(t, err)
assert.Assert(t, status.Details != nil)
return *status.Details
}

// Value returns v or panics when err is not nil.
func Value[T any](v T, err error) T {
if err != nil {
Expand Down
48 changes: 21 additions & 27 deletions internal/testing/validation/pgadmin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,14 @@ func TestPGAdminDataVolume(t *testing.T) {
assert.ErrorContains(t, err, "dataVolumeClaimSpec")
assert.ErrorContains(t, err, "Required")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 2))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 2))

assert.Equal(t, status.Details.Causes[0].Field, "spec.dataVolumeClaimSpec")
assert.Assert(t, cmp.Contains(status.Details.Causes[0].Message, "Required"))
assert.Equal(t, details.Causes[0].Field, "spec.dataVolumeClaimSpec")
assert.Assert(t, cmp.Contains(details.Causes[0].Message, "Required"))

assert.Equal(t, string(status.Details.Causes[1].Type), "FieldValueInvalid")
assert.Assert(t, cmp.Contains(status.Details.Causes[1].Message, "rules were not checked"))
assert.Equal(t, string(details.Causes[1].Type), "FieldValueInvalid")
assert.Assert(t, cmp.Contains(details.Causes[1].Message, "rules were not checked"))
})

t.Run("AccessModes", func(t *testing.T) {
Expand Down Expand Up @@ -150,11 +149,10 @@ func TestPGAdminInstrumentation(t *testing.T) {
assert.ErrorContains(t, err, "minRecords")
assert.ErrorContains(t, err, "maxDelay")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 1))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 1))

for _, cause := range status.Details.Causes {
for _, cause := range details.Causes {
assert.Equal(t, cause.Field, "spec.instrumentation.logs.batches")
assert.Assert(t, cmp.Contains(cause.Message, "disable batching"))
assert.Assert(t, cmp.Contains(cause.Message, "minRecords and maxDelay must be zero"))
Expand All @@ -176,11 +174,10 @@ func TestPGAdminInstrumentation(t *testing.T) {
assert.ErrorContains(t, err, "maxDelay")
assert.ErrorContains(t, err, "5m")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 1))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 1))

for _, cause := range status.Details.Causes {
for _, cause := range details.Causes {
assert.Equal(t, cause.Field, "spec.instrumentation.logs.batches.maxDelay")
}
})
Expand All @@ -200,11 +197,10 @@ func TestPGAdminInstrumentation(t *testing.T) {
assert.ErrorContains(t, err, "maxRecords")
assert.ErrorContains(t, err, "greater than or equal to 1")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 2))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 2))

for _, cause := range status.Details.Causes {
for _, cause := range details.Causes {
switch cause.Field {
case "spec.instrumentation.logs.batches.maxRecords":
assert.Assert(t, cmp.Contains(cause.Message, "0"))
Expand Down Expand Up @@ -233,11 +229,10 @@ func TestPGAdminInstrumentation(t *testing.T) {
assert.ErrorContains(t, err, "minRecords")
assert.ErrorContains(t, err, "maxRecords")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 1))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 1))

for _, cause := range status.Details.Causes {
for _, cause := range details.Causes {
assert.Equal(t, cause.Field, "spec.instrumentation.logs.batches")
assert.Assert(t, cmp.Contains(cause.Message, "minRecords cannot be larger than maxRecords"))
}
Expand All @@ -260,11 +255,10 @@ func TestPGAdminInstrumentation(t *testing.T) {
assert.ErrorContains(t, err, "hour|day|week")
assert.ErrorContains(t, err, "one hour")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 2))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 2))

for _, cause := range status.Details.Causes {
for _, cause := range details.Causes {
assert.Equal(t, cause.Field, "spec.instrumentation.logs.retentionPeriod")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,10 @@ func testPostgresAuthenticationCommon(t *testing.T, cc client.Client, base unstr
err := cc.Create(ctx, cluster, client.DryRunAll)
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 2))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 2))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.authentication.rules[%d]", i))
assert.Assert(t, cmp.Contains(cause.Message, "cannot be combined"))
}
Expand All @@ -122,11 +121,10 @@ func testPostgresAuthenticationCommon(t *testing.T, cc client.Client, base unstr
err := cc.Create(ctx, cluster, client.DryRunAll)
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 3))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 3))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.authentication.rules[%d].hba", i))
assert.Assert(t, cmp.Contains(cause.Message, "cannot include"))
}
Expand All @@ -145,11 +143,10 @@ func testPostgresAuthenticationCommon(t *testing.T, cc client.Client, base unstr
err := cc.Create(ctx, cluster, client.DryRunAll)
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 3))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 3))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.authentication.rules[%d].method", i))
assert.Assert(t, cmp.Contains(cause.Message, "unsafe"))
}
Expand All @@ -169,11 +166,10 @@ func testPostgresAuthenticationCommon(t *testing.T, cc client.Client, base unstr
err := cc.Create(ctx, cluster, client.DryRunAll)
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 3))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 3))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.authentication.rules[%d]", i), "%#v", cause)
assert.Assert(t, cmp.Contains(cause.Message, `"ldap" method requires`))
}
Expand Down Expand Up @@ -205,11 +201,10 @@ func testPostgresAuthenticationCommon(t *testing.T, cc client.Client, base unstr
err := cc.Create(ctx, cluster, client.DryRunAll)
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 2))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 2))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.authentication.rules[%d]", i), "%#v", cause)
assert.Assert(t, cmp.Regexp(`cannot use .+? options with .+? options`, cause.Message))
}
Expand Down Expand Up @@ -246,11 +241,10 @@ func testPostgresAuthenticationCommon(t *testing.T, cc client.Client, base unstr
err := cc.Create(ctx, cluster, client.DryRunAll)
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 5))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 5))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.authentication.rules[%d]", i), "%#v", cause)
assert.Assert(t, cmp.Contains(cause.Message, `"radius" method requires`))
}
Expand Down
29 changes: 13 additions & 16 deletions internal/testing/validation/postgrescluster/postgres_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,12 @@ func testPostgresConfigParametersCommon(t *testing.T, cc client.Client, base uns
err := cc.Create(ctx, cluster, client.DryRunAll)
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 1))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 1))

// TODO(k8s-1.30) TODO(validation): Move the parameter name from the message to the field path.
assert.Equal(t, status.Details.Causes[0].Field, "spec.config.parameters")
assert.Assert(t, cmp.Contains(status.Details.Causes[0].Message, tt.key))
assert.Equal(t, details.Causes[0].Field, "spec.config.parameters")
assert.Assert(t, cmp.Contains(details.Causes[0].Message, tt.key))
})
}
})
Expand Down Expand Up @@ -180,14 +179,13 @@ func testPostgresConfigParametersCommon(t *testing.T, cc client.Client, base uns
} else {
assert.Assert(t, apierrors.IsInvalid(err))

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 1))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 1))

// TODO(k8s-1.30) TODO(validation): Move the parameter name from the message to the field path.
assert.Equal(t, status.Details.Causes[0].Field, "spec.config.parameters")
assert.Assert(t, cmp.Contains(status.Details.Causes[0].Message, tt.key))
assert.Assert(t, cmp.Contains(status.Details.Causes[0].Message, tt.message))
assert.Equal(t, details.Causes[0].Field, "spec.config.parameters")
assert.Assert(t, cmp.Contains(details.Causes[0].Message, tt.key))
assert.Assert(t, cmp.Contains(details.Causes[0].Message, tt.message))
}
})
}
Expand Down Expand Up @@ -256,11 +254,10 @@ func testPostgresConfigParametersCommon(t *testing.T, cc client.Client, base uns
assert.Assert(t, apierrors.IsInvalid(err))
assert.ErrorContains(t, err, `"replica" or higher`)

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 1))
assert.Equal(t, status.Details.Causes[0].Field, "spec.config.parameters")
assert.Assert(t, cmp.Contains(status.Details.Causes[0].Message, "wal_level"))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 1))
assert.Equal(t, details.Causes[0].Field, "spec.config.parameters")
assert.Assert(t, cmp.Contains(details.Causes[0].Message, "wal_level"))
})
})

Expand Down
21 changes: 9 additions & 12 deletions internal/testing/validation/postgrescluster/postgres_users_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,10 @@ func testPostgresUserOptionsCommon(t *testing.T, cc client.Client, base unstruct
assert.Assert(t, apierrors.IsInvalid(err))
assert.ErrorContains(t, err, "cannot contain comments")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 3))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 3))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.users[%d].options", i))
assert.Assert(t, cmp.Contains(cause.Message, "cannot contain comments"))
}
Expand All @@ -126,11 +125,10 @@ func testPostgresUserOptionsCommon(t *testing.T, cc client.Client, base unstruct
assert.Assert(t, apierrors.IsInvalid(err))
assert.ErrorContains(t, err, "cannot assign password")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 2))
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 2))

for i, cause := range status.Details.Causes {
for i, cause := range details.Causes {
assert.Equal(t, cause.Field, fmt.Sprintf("spec.users[%d].options", i))
assert.Assert(t, cmp.Contains(cause.Message, "cannot assign password"))
}
Expand All @@ -148,10 +146,9 @@ func testPostgresUserOptionsCommon(t *testing.T, cc client.Client, base unstruct
assert.Assert(t, apierrors.IsInvalid(err))
assert.ErrorContains(t, err, "should match")

status := require.StatusError(t, err)
assert.Assert(t, status.Details != nil)
assert.Assert(t, cmp.Len(status.Details.Causes, 1))
assert.Equal(t, status.Details.Causes[0].Field, "spec.users[0].options")
details := require.StatusErrorDetails(t, err)
assert.Assert(t, cmp.Len(details.Causes, 1))
assert.Equal(t, details.Causes[0].Field, "spec.users[0].options")
})

t.Run("Valid", func(t *testing.T) {
Expand Down
Loading