1
16
17 package openapi3
18
19 import (
20 "fmt"
21 "reflect"
22 "testing"
23
24 "github.com/stretchr/testify/assert"
25 "github.com/stretchr/testify/require"
26 "k8s.io/apimachinery/pkg/runtime/schema"
27 "k8s.io/client-go/openapi"
28 "k8s.io/client-go/openapi/openapitest"
29 )
30
31 func TestOpenAPIV3Root_GroupVersions(t *testing.T) {
32 tests := []struct {
33 name string
34 paths map[string]openapi.GroupVersion
35 expectedGVs []schema.GroupVersion
36 forcedErr error
37 }{
38 {
39 name: "OpenAPI V3 Root: No openapi.Paths() equals no GroupVersions.",
40 expectedGVs: []schema.GroupVersion{},
41 },
42 {
43 name: "OpenAPI V3 Root: Single openapi.Path equals one GroupVersion.",
44 paths: map[string]openapi.GroupVersion{
45 "apis/apps/v1": nil,
46 },
47 expectedGVs: []schema.GroupVersion{
48 {Group: "apps", Version: "v1"},
49 },
50 },
51 {
52 name: "OpenAPI V3 Root: Multiple openapi.Paths equals multiple GroupVersions.",
53 paths: map[string]openapi.GroupVersion{
54 "apis/apps/v1": nil,
55 "api/v1": nil,
56 "apis/batch/v1beta1": nil,
57 },
58
59 expectedGVs: []schema.GroupVersion{
60 {Group: "apps", Version: "v1"},
61 {Group: "batch", Version: "v1beta1"},
62 {Group: "", Version: "v1"},
63 },
64 },
65 {
66 name: "Multiple GroupVersions, some invalid",
67 paths: map[string]openapi.GroupVersion{
68 "apis/batch/v1beta1": nil,
69 "api/v1": nil,
70 "foo/apps/v1": nil,
71 "apis/networking.k8s.io/v1alpha1": nil,
72 "api": nil,
73 "apis/apps": nil,
74 "apis/apps/v1": nil,
75 },
76
77 expectedGVs: []schema.GroupVersion{
78 {Group: "apps", Version: "v1"},
79 {Group: "batch", Version: "v1beta1"},
80 {Group: "networking.k8s.io", Version: "v1alpha1"},
81 {Group: "", Version: "v1"},
82 },
83 },
84 {
85 name: "OpenAPI V3 Root: Forced error returns error.",
86 forcedErr: fmt.Errorf("openapi client error"),
87 },
88 }
89
90 for _, test := range tests {
91 t.Run(test.name, func(t *testing.T) {
92 fakeClient := openapitest.FakeClient{
93 PathsMap: test.paths,
94 ForcedErr: test.forcedErr,
95 }
96 root := NewRoot(fakeClient)
97 actualGVs, err := root.GroupVersions()
98 if test.forcedErr != nil {
99 require.Error(t, err)
100 } else {
101 require.NoError(t, err)
102 }
103 if !reflect.DeepEqual(test.expectedGVs, actualGVs) {
104 t.Errorf("expected GroupVersions (%s), got (%s): (%s)\n",
105 test.expectedGVs, actualGVs, err)
106 }
107 })
108 }
109 }
110
111 func TestOpenAPIV3Root_GVSpec(t *testing.T) {
112 tests := []struct {
113 name string
114 gv schema.GroupVersion
115 expectedPaths []string
116 err error
117 }{
118 {
119 name: "OpenAPI V3 for apps/v1 works",
120 gv: schema.GroupVersion{Group: "apps", Version: "v1"},
121 expectedPaths: []string{
122 "/apis/apps/v1/",
123 "/apis/apps/v1/deployments",
124 "/apis/apps/v1/replicasets",
125 "/apis/apps/v1/daemonsets",
126 },
127 },
128 {
129 name: "OpenAPI V3 for networking/v1alpha1 works",
130 gv: schema.GroupVersion{Group: "networking.k8s.io", Version: "v1alpha1"},
131 expectedPaths: []string{
132 "/apis/networking.k8s.io/v1alpha1/",
133 },
134 },
135 {
136 name: "OpenAPI V3 for batch/v1 works",
137 gv: schema.GroupVersion{Group: "batch", Version: "v1"},
138 expectedPaths: []string{
139 "/apis/batch/v1/",
140 "/apis/batch/v1/jobs",
141 "/apis/batch/v1/cronjobs",
142 },
143 },
144 {
145 name: "OpenAPI V3 spec not found",
146 gv: schema.GroupVersion{Group: "not", Version: "found"},
147 err: &GroupVersionNotFoundError{gv: schema.GroupVersion{Group: "not", Version: "found"}},
148 },
149 }
150
151 for _, test := range tests {
152 t.Run(test.name, func(t *testing.T) {
153 client := openapitest.NewEmbeddedFileClient()
154 root := NewRoot(client)
155 gvSpec, err := root.GVSpec(test.gv)
156 if test.err != nil {
157 assert.True(t, reflect.DeepEqual(test.err, err))
158 return
159 }
160 require.NoError(t, err)
161 for _, path := range test.expectedPaths {
162 if _, found := gvSpec.Paths.Paths[path]; !found {
163 assert.True(t, found, "expected path not found (%s)\n", path)
164 }
165 }
166 })
167 }
168 }
169
170 func TestOpenAPIV3Root_GVSpecAsMap(t *testing.T) {
171 tests := []struct {
172 name string
173 gv schema.GroupVersion
174 expectedPaths []string
175 err error
176 }{
177 {
178 name: "OpenAPI V3 for apps/v1 works",
179 gv: schema.GroupVersion{Group: "apps", Version: "v1"},
180 expectedPaths: []string{
181 "/apis/apps/v1/",
182 "/apis/apps/v1/deployments",
183 "/apis/apps/v1/replicasets",
184 "/apis/apps/v1/daemonsets",
185 },
186 },
187 {
188 name: "OpenAPI V3 for networking/v1alpha1 works",
189 gv: schema.GroupVersion{Group: "networking.k8s.io", Version: "v1alpha1"},
190 expectedPaths: []string{
191 "/apis/networking.k8s.io/v1alpha1/",
192 },
193 },
194 {
195 name: "OpenAPI V3 for batch/v1 works",
196 gv: schema.GroupVersion{Group: "batch", Version: "v1"},
197 expectedPaths: []string{
198 "/apis/batch/v1/",
199 "/apis/batch/v1/jobs",
200 "/apis/batch/v1/cronjobs",
201 },
202 },
203 {
204 name: "OpenAPI V3 spec not found",
205 gv: schema.GroupVersion{Group: "not", Version: "found"},
206 err: &GroupVersionNotFoundError{gv: schema.GroupVersion{Group: "not", Version: "found"}},
207 },
208 }
209
210 for _, test := range tests {
211 t.Run(test.name, func(t *testing.T) {
212 root := NewRoot(openapitest.NewEmbeddedFileClient())
213 gvSpecAsMap, err := root.GVSpecAsMap(test.gv)
214 if test.err != nil {
215 assert.True(t, reflect.DeepEqual(test.err, err))
216 return
217 }
218 require.NoError(t, err)
219 for _, path := range test.expectedPaths {
220 pathsMap := gvSpecAsMap["paths"]
221 if _, found := pathsMap.(map[string]interface{})[path]; !found {
222 assert.True(t, found, "expected path not found (%s)\n", path)
223 }
224 }
225 })
226 }
227 }
228
229 func TestOpenAPIV3Root_GroupVersionToPath(t *testing.T) {
230 tests := []struct {
231 name string
232 groupVersion schema.GroupVersion
233 expectedPath string
234 }{
235 {
236 name: "OpenAPI V3 Root: Path to GroupVersion apps group",
237 groupVersion: schema.GroupVersion{
238 Group: "apps",
239 Version: "v1",
240 },
241 expectedPath: "apis/apps/v1",
242 },
243 {
244 name: "OpenAPI V3 Root: Path to GroupVersion batch group",
245 groupVersion: schema.GroupVersion{
246 Group: "batch",
247 Version: "v1beta1",
248 },
249 expectedPath: "apis/batch/v1beta1",
250 },
251 {
252 name: "OpenAPI V3 Root: Path to GroupVersion core group",
253 groupVersion: schema.GroupVersion{
254 Version: "v1",
255 },
256 expectedPath: "api/v1",
257 },
258 }
259
260 for _, test := range tests {
261 t.Run(test.name, func(t *testing.T) {
262 actualPath := gvToAPIPath(test.groupVersion)
263 assert.Equal(t, test.expectedPath, actualPath, "expected API path (%s), got (%s)",
264 test.expectedPath, actualPath)
265 })
266 }
267 }
268
269 func TestOpenAPIV3Root_PathToGroupVersion(t *testing.T) {
270 tests := []struct {
271 name string
272 path string
273 expectedGV schema.GroupVersion
274 expectedErr bool
275 }{
276 {
277 name: "OpenAPI V3 Root: Path to GroupVersion apps/v1 group",
278 path: "apis/apps/v1",
279 expectedGV: schema.GroupVersion{
280 Group: "apps",
281 Version: "v1",
282 },
283 },
284 {
285 name: "Group without Version throws error",
286 path: "apis/apps",
287 expectedErr: true,
288 },
289 {
290 name: "OpenAPI V3 Root: Path to GroupVersion batch group",
291 path: "apis/batch/v1beta1",
292 expectedGV: schema.GroupVersion{
293 Group: "batch",
294 Version: "v1beta1",
295 },
296 },
297 {
298 name: "OpenAPI V3 Root: Path to GroupVersion core group",
299 path: "api/v1",
300 expectedGV: schema.GroupVersion{
301 Version: "v1",
302 },
303 },
304 }
305
306 for _, test := range tests {
307 t.Run(test.name, func(t *testing.T) {
308 actualGV, err := pathToGroupVersion(test.path)
309 if test.expectedErr {
310 require.Error(t, err, "should have received error for path: %s", test.path)
311 } else {
312 require.NoError(t, err, "expected no error, got (%v)", err)
313 assert.Equal(t, test.expectedGV, actualGV, "expected GroupVersion (%s), got (%s)",
314 test.expectedGV, actualGV)
315 }
316 })
317 }
318 }
319
View as plain text