1
16
17 package schema
18
19 import (
20 "reflect"
21 "testing"
22
23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24
25 fuzz "github.com/google/gofuzz"
26 )
27
28 func TestValidateStructuralMetadataInvariants(t *testing.T) {
29 fuzzer := fuzz.New()
30 fuzzer.Funcs(
31 func(s *JSON, c fuzz.Continue) {
32 if c.RandBool() {
33 s.Object = float64(42.0)
34 }
35 },
36 func(s **StructuralOrBool, c fuzz.Continue) {
37 if c.RandBool() {
38 *s = &StructuralOrBool{}
39 }
40 },
41 func(s **Structural, c fuzz.Continue) {
42 if c.RandBool() {
43 *s = &Structural{}
44 }
45 },
46 func(s *Structural, c fuzz.Continue) {
47 if c.RandBool() {
48 *s = Structural{}
49 }
50 },
51 func(vv **NestedValueValidation, c fuzz.Continue) {
52 if c.RandBool() {
53 *vv = &NestedValueValidation{}
54 }
55 },
56 func(vv *NestedValueValidation, c fuzz.Continue) {
57 if c.RandBool() {
58 *vv = NestedValueValidation{}
59 }
60 },
61 )
62 fuzzer.NilChance(0)
63
64
65 typeNames := []string{"object", "array", "number", "integer", "boolean", "string"}
66 for _, typeName := range typeNames {
67 s := Structural{
68 Generic: Generic{
69 Type: typeName,
70 },
71 }
72
73 errs := validateStructuralMetadataInvariants(&s, true, rootLevel, nil)
74 if len(errs) != 0 {
75 t.Logf("errors returned: %v", errs)
76 }
77 if len(errs) != 0 && typeName == "object" {
78 t.Errorf("unexpected forbidden field validation errors for: %#v", s)
79 }
80 if len(errs) == 0 && typeName != "object" {
81 t.Errorf("expected forbidden field validation errors for: %#v", s)
82 }
83 }
84
85
86 tt := reflect.TypeOf(metav1.ObjectMeta{})
87 for i := 0; i < tt.NumField(); i++ {
88 property := tt.Field(i).Name
89 s := &Structural{
90 Generic: Generic{
91 Type: "object",
92 },
93 Properties: map[string]Structural{
94 property: {},
95 },
96 }
97
98 errs := validateStructuralMetadataInvariants(s, true, rootLevel, nil)
99 if len(errs) != 0 {
100 t.Logf("errors returned: %v", errs)
101 }
102 if len(errs) != 0 && (property == "name" || property == "generateName") {
103 t.Errorf("unexpected forbidden field validation errors for: %#v", s)
104 }
105 if len(errs) == 0 && property != "name" && property != "generateName" {
106 t.Errorf("expected forbidden field validation errors for: %#v", s)
107 }
108 }
109
110
111 tt = reflect.TypeOf(Structural{})
112 for i := 0; i < tt.NumField(); i++ {
113 s := Structural{}
114 x := reflect.ValueOf(&s).Elem()
115 fuzzer.Fuzz(x.Field(i).Addr().Interface())
116 s.Type = "object"
117 s.Properties = map[string]Structural{
118 "name": {},
119 "generateName": {},
120 }
121 s.Default.Object = nil
122
123 valid := reflect.DeepEqual(s, Structural{
124 Generic: Generic{
125 Type: "object",
126 Default: JSON{
127 Object: nil,
128 },
129 },
130 Properties: map[string]Structural{
131 "name": {},
132 "generateName": {},
133 },
134 })
135
136 errs := validateStructuralMetadataInvariants(s.DeepCopy(), true, rootLevel, nil)
137 if len(errs) != 0 {
138 t.Logf("errors returned: %v", errs)
139 }
140 if len(errs) != 0 && valid {
141 t.Errorf("unexpected forbidden field validation errors for: %#v", s)
142 }
143 if len(errs) == 0 && !valid {
144 t.Errorf("expected forbidden field validation errors for: %#v", s)
145 }
146 }
147 }
148
149 func TestValidateNestedValueValidationComplete(t *testing.T) {
150 fuzzer := fuzz.New()
151 fuzzer.Funcs(
152 func(s *JSON, c fuzz.Continue) {
153 if c.RandBool() {
154 s.Object = float64(42.0)
155 }
156 },
157 func(s **StructuralOrBool, c fuzz.Continue) {
158 if c.RandBool() {
159 *s = &StructuralOrBool{}
160 }
161 },
162 )
163 fuzzer.NilChance(0)
164
165
166 tt := reflect.TypeOf(Generic{})
167 for i := 0; i < tt.NumField(); i++ {
168 vv := &NestedValueValidation{}
169 x := reflect.ValueOf(&vv.ForbiddenGenerics).Elem()
170 fuzzer.Fuzz(x.Field(i).Addr().Interface())
171
172 errs := validateNestedValueValidation(vv, false, false, fieldLevel, nil)
173 if len(errs) == 0 && !reflect.DeepEqual(vv.ForbiddenGenerics, Generic{}) {
174 t.Errorf("expected ForbiddenGenerics validation errors for: %#v", vv)
175 }
176 }
177
178
179 tt = reflect.TypeOf(Extensions{})
180 for i := 0; i < tt.NumField(); i++ {
181 vv := &NestedValueValidation{}
182 x := reflect.ValueOf(&vv.ForbiddenExtensions).Elem()
183 fuzzer.Fuzz(x.Field(i).Addr().Interface())
184
185 errs := validateNestedValueValidation(vv, false, false, fieldLevel, nil)
186 if len(errs) == 0 && !reflect.DeepEqual(vv.ForbiddenExtensions, Extensions{}) {
187 t.Errorf("expected ForbiddenExtensions validation errors for: %#v", vv)
188 }
189 }
190 }
191
View as plain text