@@ -17,19 +17,25 @@ limitations under the License.
17
17
package runtime_test
18
18
19
19
import (
20
+ "context"
20
21
"fmt"
21
22
"reflect"
22
23
"strings"
23
24
"testing"
24
25
25
26
"github.com/google/go-cmp/cmp"
27
+
28
+ "k8s.io/apimachinery/pkg/api/operation"
26
29
"k8s.io/apimachinery/pkg/conversion"
27
30
"k8s.io/apimachinery/pkg/runtime"
28
31
"k8s.io/apimachinery/pkg/runtime/schema"
29
32
"k8s.io/apimachinery/pkg/runtime/serializer"
30
33
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
31
34
"k8s.io/apimachinery/pkg/util/diff"
32
35
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
36
+ "k8s.io/apimachinery/pkg/util/sets"
37
+ "k8s.io/apimachinery/pkg/util/validation/field"
38
+ fieldtesting "k8s.io/apimachinery/pkg/util/validation/field/testing"
33
39
)
34
40
35
41
type testConversions struct {
@@ -1009,3 +1015,101 @@ func TestMetaValuesUnregisteredConvert(t *testing.T) {
1009
1015
t .Errorf ("Expected %v, got %v" , e , a )
1010
1016
}
1011
1017
}
1018
+
1019
+ func TestRegisterValidate (t * testing.T ) {
1020
+ invalidValue := field .Invalid (field .NewPath ("testString" ), "" , "Invalid value" ).WithOrigin ("invalid-value" )
1021
+ invalidLength := field .Invalid (field .NewPath ("testString" ), "" , "Invalid length" ).WithOrigin ("invalid-length" )
1022
+ invalidStatusErr := field .Invalid (field .NewPath ("testString" ), "" , "Invalid condition" ).WithOrigin ("invalid-condition" )
1023
+ invalidIfOptionErr := field .Invalid (field .NewPath ("testString" ), "" , "Invalid when option is set" ).WithOrigin ("invalid-when-option-set" )
1024
+
1025
+ testCases := []struct {
1026
+ name string
1027
+ object runtime.Object
1028
+ oldObject runtime.Object
1029
+ subresource []string
1030
+ options sets.Set [string ]
1031
+ expected field.ErrorList
1032
+ }{
1033
+ {
1034
+ name : "single error" ,
1035
+ object : & TestType1 {},
1036
+ expected : field.ErrorList {invalidValue },
1037
+ },
1038
+ {
1039
+ name : "multiple errors" ,
1040
+ object : & TestType2 {},
1041
+ expected : field.ErrorList {invalidValue , invalidLength },
1042
+ },
1043
+ {
1044
+ name : "update error" ,
1045
+ object : & TestType2 {},
1046
+ oldObject : & TestType2 {},
1047
+ expected : field.ErrorList {invalidLength },
1048
+ },
1049
+ {
1050
+ name : "options error" ,
1051
+ object : & TestType1 {},
1052
+ options : sets .New ("option1" ),
1053
+ expected : field.ErrorList {invalidIfOptionErr },
1054
+ },
1055
+ {
1056
+ name : "subresource error" ,
1057
+ object : & TestType1 {},
1058
+ subresource : []string {"status" },
1059
+ expected : field.ErrorList {invalidStatusErr },
1060
+ },
1061
+ }
1062
+
1063
+ s := runtime .NewScheme ()
1064
+ ctx := context .Background ()
1065
+
1066
+ // register multiple types for testing to ensure registration is working as expected
1067
+ s .AddValidationFunc (& TestType1 {}, func (ctx context.Context , op operation.Operation , object , oldObject interface {}, subresources ... string ) field.ErrorList {
1068
+ if op .Options .Has ("option1" ) {
1069
+ return field.ErrorList {invalidIfOptionErr }
1070
+ }
1071
+ if len (subresources ) == 1 && subresources [0 ] == "status" {
1072
+ return field.ErrorList {invalidStatusErr }
1073
+ }
1074
+ return field.ErrorList {invalidValue }
1075
+ })
1076
+
1077
+ s .AddValidationFunc (& TestType2 {}, func (ctx context.Context , op operation.Operation , object , oldObject interface {}, subresources ... string ) field.ErrorList {
1078
+ if oldObject != nil {
1079
+ return field.ErrorList {invalidLength }
1080
+ }
1081
+ return field.ErrorList {invalidValue , invalidLength }
1082
+ })
1083
+
1084
+ for _ , tc := range testCases {
1085
+ t .Run (tc .name , func (t * testing.T ) {
1086
+ var results field.ErrorList
1087
+ if tc .oldObject == nil {
1088
+ results = s .Validate (ctx , tc .options , tc .object , tc .subresource ... )
1089
+ } else {
1090
+ results = s .ValidateUpdate (ctx , tc .options , tc .object , tc .oldObject , tc .subresource ... )
1091
+ }
1092
+ fieldtesting .MatchErrors (t , tc .expected , results , fieldtesting .Match ().ByType ().ByField ().ByOrigin ())
1093
+ })
1094
+ }
1095
+ }
1096
+
1097
+ type TestType1 struct {
1098
+ Version string `json:"apiVersion,omitempty"`
1099
+ Kind string `json:"kind,omitempty"`
1100
+ TestString string `json:"testString"`
1101
+ }
1102
+
1103
+ func (TestType1 ) GetObjectKind () schema.ObjectKind { return schema .EmptyObjectKind }
1104
+
1105
+ func (TestType1 ) DeepCopyObject () runtime.Object { return nil }
1106
+
1107
+ type TestType2 struct {
1108
+ Version string `json:"apiVersion,omitempty"`
1109
+ Kind string `json:"kind,omitempty"`
1110
+ TestString string `json:"testString"`
1111
+ }
1112
+
1113
+ func (TestType2 ) GetObjectKind () schema.ObjectKind { return schema .EmptyObjectKind }
1114
+
1115
+ func (TestType2 ) DeepCopyObject () runtime.Object { return nil }
0 commit comments