Skip to content

Commit 4870ff1

Browse files
committed
Ensure fixed order in multi-line error returned by crdupgradesafety change validator
Signed-off-by: Artur Zych <[email protected]>
1 parent 00589a4 commit 4870ff1

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

pkg/kapp/crdupgradesafety/change_validator.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77
"bytes"
88
"errors"
99
"fmt"
10+
"maps"
1011
"reflect"
12+
"slices"
1113

1214
"github.com/openshift/crd-schema-checker/pkg/manifestcomparators"
1315
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@@ -449,7 +451,10 @@ func (cv *ChangeValidator) Validate(old, new v1.CustomResourceDefinition) error
449451
continue
450452
}
451453

452-
for field, diff := range diffs {
454+
// ensure order of the potentially multi-line final error
455+
for _, field := range slices.Sorted(maps.Keys(diffs)) {
456+
diff := diffs[field]
457+
453458
handled := false
454459
for _, validation := range cv.Validations {
455460
ok, err := validation(diff)

pkg/kapp/crdupgradesafety/change_validator_test.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package crdupgradesafety_test
55

66
import (
77
"errors"
8+
"fmt"
89
"testing"
910

1011
"carvel.dev/kapp/pkg/kapp/crdupgradesafety"
@@ -235,12 +236,15 @@ func TestFlattenSchema(t *testing.T) {
235236
}
236237

237238
func TestChangeValidator(t *testing.T) {
239+
validationErr1 := errors.New(`version "v1alpha1", field "^" has unknown change, refusing to determine that change is safe`)
240+
validationErr2 := errors.New(`version "v1alpha1", field "^": fail`)
241+
238242
for _, tc := range []struct {
239243
name string
240244
changeValidator *crdupgradesafety.ChangeValidator
241245
old v1.CustomResourceDefinition
242246
new v1.CustomResourceDefinition
243-
shouldError bool
247+
expectedError error
244248
}{
245249
{
246250
name: "no changes, no error",
@@ -347,7 +351,7 @@ func TestChangeValidator(t *testing.T) {
347351
},
348352
},
349353
},
350-
shouldError: true,
354+
expectedError: validationErr1,
351355
},
352356
{
353357
name: "changes, validation failed, change fully handled, error",
@@ -384,15 +388,18 @@ func TestChangeValidator(t *testing.T) {
384388
},
385389
},
386390
},
387-
shouldError: true,
391+
expectedError: validationErr2,
388392
},
389393
{
390-
name: "changes, validation failed, change not fully handled, error",
394+
name: "changes, validation failed, change not fully handled, ordered error",
391395
changeValidator: &crdupgradesafety.ChangeValidator{
392396
Validations: []crdupgradesafety.ChangeValidation{
393397
func(_ crdupgradesafety.FieldDiff) (bool, error) {
394398
return false, errors.New("fail")
395399
},
400+
func(_ crdupgradesafety.FieldDiff) (bool, error) {
401+
return false, errors.New("error")
402+
},
396403
},
397404
},
398405
old: v1.CustomResourceDefinition{
@@ -421,12 +428,16 @@ func TestChangeValidator(t *testing.T) {
421428
},
422429
},
423430
},
424-
shouldError: true,
431+
expectedError: fmt.Errorf("%w\n%s\n%w", validationErr2, `version "v1alpha1", field "^": error`, validationErr1),
425432
},
426433
} {
427434
t.Run(tc.name, func(t *testing.T) {
428435
err := tc.changeValidator.Validate(tc.old, tc.new)
429-
assert.Equal(t, tc.shouldError, err != nil, "should error? - %v", tc.shouldError)
436+
if tc.expectedError != nil {
437+
assert.EqualError(t, err, tc.expectedError.Error())
438+
} else {
439+
assert.NoError(t, err)
440+
}
430441
})
431442
}
432443
}

0 commit comments

Comments
 (0)