1
16
17 package resource
18
19 import (
20 "strings"
21 "testing"
22
23 "k8s.io/apimachinery/pkg/runtime/schema"
24 "k8s.io/client-go/openapi/cached"
25 "k8s.io/client-go/openapi/openapitest"
26 "k8s.io/client-go/openapi3"
27 "k8s.io/kube-openapi/pkg/spec3"
28 )
29
30 func TestV3SupportsQueryParamBatchV1(t *testing.T) {
31 tests := map[string]struct {
32 crds []schema.GroupKind
33 gvk schema.GroupVersionKind
34 queryParam VerifiableQueryParam
35 expectedSupports bool
36 }{
37 "Field validation query param is supported for batch/v1/Job": {
38 crds: []schema.GroupKind{},
39 gvk: schema.GroupVersionKind{
40 Group: "batch",
41 Version: "v1",
42 Kind: "Job",
43 },
44 queryParam: QueryParamFieldValidation,
45 expectedSupports: true,
46 },
47 "Field validation query param supported for core/v1/Namespace": {
48 crds: []schema.GroupKind{},
49 gvk: schema.GroupVersionKind{
50 Group: "",
51 Version: "v1",
52 Kind: "Namespace",
53 },
54 queryParam: QueryParamFieldValidation,
55 expectedSupports: true,
56 },
57 "Field validation unsupported for unknown GVK": {
58 crds: []schema.GroupKind{},
59 gvk: schema.GroupVersionKind{
60 Group: "bad",
61 Version: "v1",
62 Kind: "Uknown",
63 },
64 queryParam: QueryParamFieldValidation,
65 expectedSupports: false,
66 },
67 "Unknown query param unsupported (for all GVK's)": {
68 crds: []schema.GroupKind{},
69 gvk: schema.GroupVersionKind{
70 Group: "apps",
71 Version: "v1",
72 Kind: "Deployment",
73 },
74 queryParam: "UnknownQueryParam",
75 expectedSupports: false,
76 },
77 "Field validation query param supported for found CRD": {
78 crds: []schema.GroupKind{
79 {
80 Group: "example.com",
81 Kind: "ExampleCRD",
82 },
83 },
84
85 gvk: schema.GroupVersionKind{
86 Group: "example.com",
87 Version: "v1",
88 Kind: "ExampleCRD",
89 },
90 queryParam: QueryParamFieldValidation,
91 expectedSupports: true,
92 },
93 "Field validation query param unsupported for missing CRD": {
94 crds: []schema.GroupKind{
95 {
96 Group: "different.com",
97 Kind: "DifferentCRD",
98 },
99 },
100
101 gvk: schema.GroupVersionKind{
102 Group: "example.com",
103 Version: "v1",
104 Kind: "ExampleCRD",
105 },
106 queryParam: QueryParamFieldValidation,
107 expectedSupports: false,
108 },
109 "List GVK is specifically unsupported": {
110 crds: []schema.GroupKind{},
111 gvk: schema.GroupVersionKind{
112 Group: "",
113 Version: "v1",
114 Kind: "List",
115 },
116 queryParam: QueryParamFieldValidation,
117 expectedSupports: false,
118 },
119 }
120
121 root := openapi3.NewRoot(cached.NewClient(openapitest.NewEmbeddedFileClient()))
122 for tn, tc := range tests {
123 t.Run(tn, func(t *testing.T) {
124 verifier := &queryParamVerifierV3{
125 finder: NewCRDFinder(func() ([]schema.GroupKind, error) {
126 return tc.crds, nil
127 }),
128 root: root,
129 queryParam: tc.queryParam,
130 }
131 err := verifier.HasSupport(tc.gvk)
132 if tc.expectedSupports && err != nil {
133 t.Errorf("Expected supports, but returned err for GVK (%s)", tc.gvk)
134 } else if !tc.expectedSupports && err == nil {
135 t.Errorf("Expected not supports, but returned no err for GVK (%s)", tc.gvk)
136 }
137 })
138 }
139 }
140
141 func TestInvalidOpenAPIV3Document(t *testing.T) {
142 tests := map[string]struct {
143 spec *spec3.OpenAPI
144 err string
145 }{
146 "nil document returns error": {
147 spec: nil,
148 err: "Invalid OpenAPI V3 document",
149 },
150 "empty document returns error": {
151 spec: &spec3.OpenAPI{},
152 err: "Invalid OpenAPI V3 document",
153 },
154 "minimal document returns error": {
155 spec: &spec3.OpenAPI{
156 Version: "openapi 3.0.0",
157 Paths: nil,
158 },
159 err: "Invalid OpenAPI V3 document",
160 },
161 "empty Paths returns error": {
162 spec: &spec3.OpenAPI{
163 Version: "openapi 3.0.0",
164 Paths: &spec3.Paths{},
165 },
166 err: "Path not found for GVK",
167 },
168 "nil Path returns error": {
169 spec: &spec3.OpenAPI{
170 Version: "openapi 3.0.0",
171 Paths: &spec3.Paths{Paths: map[string]*spec3.Path{"/version": nil}},
172 },
173 err: "Path not found for GVK",
174 },
175 "empty Path returns error": {
176 spec: &spec3.OpenAPI{
177 Version: "openapi 3.0.0",
178 Paths: &spec3.Paths{Paths: map[string]*spec3.Path{"/version": {}}},
179 },
180 err: "Path not found for GVK",
181 },
182 }
183
184 gvk := schema.GroupVersionKind{
185 Group: "batch",
186 Version: "v1",
187 Kind: "Job",
188 }
189 for tn, tc := range tests {
190 t.Run(tn, func(t *testing.T) {
191
192 verifier := &queryParamVerifierV3{
193 finder: NewCRDFinder(func() ([]schema.GroupKind, error) {
194 return []schema.GroupKind{}, nil
195 }),
196 root: &fakeRoot{tc.spec},
197 queryParam: QueryParamFieldValidation,
198 }
199 err := verifier.HasSupport(gvk)
200 if !strings.Contains(err.Error(), tc.err) {
201 t.Errorf("Expected error (%s), but received (%s)", tc.err, err.Error())
202 }
203 })
204 }
205 }
206
207
208 type fakeRoot struct {
209 spec *spec3.OpenAPI
210 }
211
212 func (f *fakeRoot) GroupVersions() ([]schema.GroupVersion, error) {
213
214 return nil, nil
215 }
216
217
218 func (f *fakeRoot) GVSpec(gv schema.GroupVersion) (*spec3.OpenAPI, error) {
219 return f.spec, nil
220 }
221
222 func (f *fakeRoot) GVSpecAsMap(gv schema.GroupVersion) (map[string]interface{}, error) {
223
224 return nil, nil
225 }
226
View as plain text