1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package dcl_test
16
17 import (
18 "testing"
19
20 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl"
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
22 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test"
23
24 "github.com/nasa9084/go-openapi"
25 v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 )
27
28 func TestValidateResourceIDIfSupported(t *testing.T) {
29 meta := v1.ObjectMeta{
30 Namespace: "test-ns",
31 Name: "test-resource",
32 }
33 tests := []struct {
34 name string
35 resource dcl.Resource
36 expectedSpec map[string]interface{}
37 hasError bool
38 }{
39 {
40 name: "spec.resourceID field not supported",
41 resource: dcl.Resource{
42 Resource: k8s.Resource{
43 ObjectMeta: meta,
44 },
45 Schema: &openapi.Schema{},
46 },
47 },
48 {
49 name: "non server-generated ID, spec.resourceID field set",
50 resource: dcl.Resource{
51 Resource: k8s.Resource{
52 ObjectMeta: meta,
53 Spec: map[string]interface{}{
54 "resourceID": "test-id",
55 },
56 },
57 Schema: &openapi.Schema{
58 Properties: map[string]*openapi.Schema{
59 "name": &openapi.Schema{
60 Type: "string",
61 },
62 },
63 },
64 },
65 expectedSpec: map[string]interface{}{
66 "resourceID": "test-id",
67 },
68 hasError: false,
69 },
70 {
71 name: "non server-generated ID, spec.resourceID field unset",
72 resource: dcl.Resource{
73 Resource: k8s.Resource{
74 ObjectMeta: meta,
75 },
76 Schema: &openapi.Schema{
77 Properties: map[string]*openapi.Schema{
78 "name": &openapi.Schema{
79 Type: "string",
80 },
81 },
82 },
83 },
84 hasError: false,
85 },
86 {
87 name: "non server-generated ID, spec.resourceID empty",
88 resource: dcl.Resource{
89 Resource: k8s.Resource{
90 ObjectMeta: meta,
91 Spec: map[string]interface{}{
92 "resourceID": "",
93 },
94 },
95 Schema: &openapi.Schema{
96 Properties: map[string]*openapi.Schema{
97 "name": &openapi.Schema{
98 Type: "string",
99 },
100 },
101 },
102 },
103 hasError: true,
104 },
105 {
106 name: "server-generated ID, spec.resourceID field set",
107 resource: dcl.Resource{
108 Resource: k8s.Resource{
109 ObjectMeta: meta,
110 Spec: map[string]interface{}{
111 "resourceID": "test-id",
112 },
113 },
114 Schema: &openapi.Schema{
115 Properties: map[string]*openapi.Schema{
116 "name": &openapi.Schema{
117 Type: "string",
118 Extension: map[string]interface{}{
119 "x-dcl-server-generated-parameter": true,
120 },
121 },
122 },
123 },
124 },
125 expectedSpec: map[string]interface{}{
126 "resourceID": "test-id",
127 },
128 hasError: false,
129 },
130 {
131 name: "server-generated ID, spec.resourceID field unset",
132 resource: dcl.Resource{
133 Resource: k8s.Resource{
134 ObjectMeta: meta,
135 },
136 Schema: &openapi.Schema{
137 Properties: map[string]*openapi.Schema{
138 "name": &openapi.Schema{
139 Type: "string",
140 Extension: map[string]interface{}{
141 "x-dcl-server-generated-parameter": true,
142 },
143 },
144 },
145 },
146 },
147 hasError: false,
148 },
149 }
150
151 for _, tc := range tests {
152 tc := tc
153 t.Run(tc.name, func(t *testing.T) {
154 t.Parallel()
155 err := tc.resource.ValidateResourceIDIfSupported()
156 if tc.hasError {
157 if err == nil {
158 t.Fatalf("got nil, want an error")
159 }
160 return
161 }
162 if err != nil {
163 t.Fatalf("error setting resource ID: %v", err)
164 }
165 if got, want := tc.resource.Spec, tc.expectedSpec; !test.Equals(t, got, want) {
166 t.Fatalf("got: %v, want: %v", got, want)
167 }
168 })
169 }
170 }
171
172 func TestHasServerGeneratedIDButNotConfigured(t *testing.T) {
173 tests := []struct {
174 name string
175 resource *dcl.Resource
176 result bool
177 }{
178 {
179 name: "user specified name",
180 resource: &dcl.Resource{
181 Resource: k8s.Resource{
182 Spec: map[string]interface{}{
183 "resourceID": "my-name",
184 },
185 },
186 Schema: &openapi.Schema{
187 Properties: map[string]*openapi.Schema{
188 "name": &openapi.Schema{
189 Type: "string",
190 },
191 },
192 Type: "object",
193 },
194 },
195 result: false,
196 },
197 {
198 name: "configured server-generated id",
199 resource: &dcl.Resource{
200 Resource: k8s.Resource{
201 Spec: map[string]interface{}{
202 "resourceID": "server-generated-value",
203 },
204 },
205 Schema: &openapi.Schema{
206 Properties: map[string]*openapi.Schema{
207 "name": &openapi.Schema{
208 Type: "string",
209 Extension: map[string]interface{}{
210 "x-dcl-server-generated-parameter": true,
211 },
212 },
213 },
214 Type: "object",
215 },
216 },
217 result: false,
218 },
219 {
220 name: "non-configured server-generated id",
221 resource: &dcl.Resource{
222 Resource: k8s.Resource{},
223 Schema: &openapi.Schema{
224 Properties: map[string]*openapi.Schema{
225 "name": &openapi.Schema{
226 Type: "string",
227 Extension: map[string]interface{}{
228 "x-dcl-server-generated-parameter": true,
229 },
230 },
231 },
232 Type: "object",
233 },
234 },
235 result: true,
236 },
237 }
238
239 for _, tc := range tests {
240 tc := tc
241 t.Run(tc.name, func(t *testing.T) {
242 t.Parallel()
243 actual, err := tc.resource.HasServerGeneratedIDButNotConfigured()
244 if err != nil {
245 t.Fatalf("unexpected error: %v", err)
246 }
247 if actual != tc.result {
248 t.Fatalf("got: %v, want: %v", actual, tc.result)
249 }
250 })
251 }
252 }
253
254 func TestHasServerGeneratedIDAndConfigured(t *testing.T) {
255 tests := []struct {
256 name string
257 resource *dcl.Resource
258 result bool
259 }{
260 {
261 name: "user specified name",
262 resource: &dcl.Resource{
263 Resource: k8s.Resource{
264 Spec: map[string]interface{}{
265 "resourceID": "my-name",
266 },
267 },
268 Schema: &openapi.Schema{
269 Properties: map[string]*openapi.Schema{
270 "name": &openapi.Schema{
271 Type: "string",
272 },
273 },
274 Type: "object",
275 },
276 },
277 result: false,
278 },
279 {
280 name: "configured server-generated id",
281 resource: &dcl.Resource{
282 Resource: k8s.Resource{
283 Spec: map[string]interface{}{
284 "resourceID": "server-generated-value",
285 },
286 },
287 Schema: &openapi.Schema{
288 Properties: map[string]*openapi.Schema{
289 "name": &openapi.Schema{
290 Type: "string",
291 Extension: map[string]interface{}{
292 "x-dcl-server-generated-parameter": true,
293 },
294 },
295 },
296 Type: "object",
297 },
298 },
299 result: true,
300 },
301 {
302 name: "non-configured server-generated id",
303 resource: &dcl.Resource{
304 Resource: k8s.Resource{},
305 Schema: &openapi.Schema{
306 Properties: map[string]*openapi.Schema{
307 "name": &openapi.Schema{
308 Type: "string",
309 Extension: map[string]interface{}{
310 "x-dcl-server-generated-parameter": true,
311 },
312 },
313 },
314 Type: "object",
315 },
316 },
317 result: false,
318 },
319 }
320
321 for _, tc := range tests {
322 tc := tc
323 t.Run(tc.name, func(t *testing.T) {
324 t.Parallel()
325 actual, err := tc.resource.HasServerGeneratedIDAndConfigured()
326 if err != nil {
327 t.Fatalf("unexpected error: %v", err)
328 }
329 if actual != tc.result {
330 t.Fatalf("got: %v, want: %v", actual, tc.result)
331 }
332 })
333 }
334 }
335
336 func TestHasMutableButUnreadableFields(t *testing.T) {
337 tests := []struct {
338 name string
339 resource *dcl.Resource
340 expectedResult bool
341 hasError bool
342 }{
343 {
344 name: "has mutable-but-unreadable fields",
345 resource: &dcl.Resource{
346 Resource: k8s.Resource{
347 Spec: map[string]interface{}{
348 "resourceID": "my-name",
349 },
350 },
351 Schema: &openapi.Schema{
352 Type: "object",
353 Extension: map[string]interface{}{
354 "x-dcl-uses-state-hint": true,
355 },
356 },
357 },
358 expectedResult: true,
359 },
360 {
361 name: "has no mutable-but-unreadable fields",
362 resource: &dcl.Resource{
363 Resource: k8s.Resource{
364 Spec: map[string]interface{}{
365 "resourceID": "my-name",
366 },
367 },
368 Schema: &openapi.Schema{
369 Type: "object",
370 },
371 },
372 expectedResult: false,
373 },
374 {
375 name: "error our when checking for mutable-but-unreadable fields",
376 resource: &dcl.Resource{
377 Resource: k8s.Resource{
378 Spec: map[string]interface{}{
379 "resourceID": "my-name",
380 },
381 },
382 Schema: &openapi.Schema{
383 Type: "object",
384 Extension: map[string]interface{}{
385 "x-dcl-uses-state-hint": "true",
386 },
387 },
388 },
389 hasError: true,
390 },
391 }
392
393 for _, tc := range tests {
394 tc := tc
395 t.Run(tc.name, func(t *testing.T) {
396 t.Parallel()
397 result, err := tc.resource.HasMutableButUnreadableFields()
398 if tc.hasError {
399 if err == nil {
400 t.Fatal("got no error, but want an error")
401 }
402 return
403 }
404 if err != nil {
405 t.Fatalf("unexpected error: %v", err)
406 }
407 if got, want := result, tc.expectedResult; got != want {
408 t.Fatalf("got %v, want %v", got, want)
409 }
410 })
411 }
412 }
413
View as plain text