1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package krmtotf_test
16
17 import (
18 "reflect"
19 "testing"
20
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
22 . "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/krmtotf"
23 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test"
24
25 "github.com/google/go-cmp/cmp"
26 "github.com/hashicorp/terraform-provider-google-beta/google-beta"
27 )
28
29 func Test_FlattenComputeInstanceMetadata(t *testing.T) {
30 tests := []struct {
31 name string
32 input map[string]interface{}
33 expected map[string]interface{}
34 }{
35 {
36 name: "flattens structured list to simple map",
37 input: map[string]interface{}{
38 "key": "value",
39 "metadata": []interface{}{
40 map[string]interface{}{
41 "key": "foo",
42 "value": "bar",
43 },
44 map[string]interface{}{
45 "key": "bar",
46 "value": "baz",
47 },
48 },
49 },
50 expected: map[string]interface{}{
51 "key": "value",
52 "metadata": map[string]interface{}{
53 "foo": "bar",
54 "bar": "baz",
55 },
56 },
57 },
58 {
59 name: "no-op if no metadata given",
60 input: map[string]interface{}{
61 "key": "value",
62 },
63 expected: map[string]interface{}{
64 "key": "value",
65 },
66 },
67 }
68 for _, tc := range tests {
69 t.Run(tc.name, func(t *testing.T) {
70 output, err := FlattenComputeInstanceMetadata(tc.input)
71 if err != nil {
72 t.Fatalf("unexpected error: %v", err)
73 }
74 if !test.Equals(t, tc.expected, output) {
75 t.Fatalf("expected: %+v, actual: %+v", tc.expected, output)
76 }
77 })
78 }
79 }
80
81 func Test_ExpandComputeInstanceMetadata(t *testing.T) {
82 tests := []struct {
83 name string
84 input map[string]interface{}
85 prev *Resource
86 expected map[string]interface{}
87 }{
88 {
89 name: "expands simple map to structured list",
90 input: map[string]interface{}{
91 "key": "value",
92 "metadata": map[string]interface{}{
93 "foo": "bar",
94 "bar": "baz",
95 },
96 },
97 prev: &Resource{
98 Resource: k8s.Resource{
99 Spec: map[string]interface{}{},
100 },
101 },
102 expected: map[string]interface{}{
103 "key": "value",
104 "metadata": []interface{}{
105 map[string]interface{}{
106 "key": "bar",
107 "value": "baz",
108 },
109 map[string]interface{}{
110 "key": "foo",
111 "value": "bar",
112 },
113 },
114 },
115 },
116 {
117 name: "previous value is source of truth",
118 input: map[string]interface{}{
119 "key": "value",
120 "metadata": map[string]interface{}{
121 "foo": "bar",
122 "bar": "baz",
123 },
124 },
125 prev: &Resource{
126 Resource: k8s.Resource{
127 Spec: map[string]interface{}{
128 "metadata": []interface{}{
129 map[string]interface{}{
130 "key": "foo",
131 "value": "bar",
132 },
133 map[string]interface{}{
134 "key": "bar",
135 "value": "baz",
136 },
137 },
138 },
139 },
140 },
141 expected: map[string]interface{}{
142 "key": "value",
143 "metadata": []interface{}{
144 map[string]interface{}{
145 "key": "foo",
146 "value": "bar",
147 },
148 map[string]interface{}{
149 "key": "bar",
150 "value": "baz",
151 },
152 },
153 },
154 },
155 {
156 name: "previous value is source of truth 2",
157 input: map[string]interface{}{
158 "key": "value",
159 "metadata": map[string]interface{}{
160 "foo": "bar",
161 "bar": "baz",
162 "baz": "abc",
163 },
164 },
165 prev: &Resource{
166 Resource: k8s.Resource{
167 Spec: map[string]interface{}{
168 "metadata": []interface{}{
169 map[string]interface{}{
170 "key": "foo",
171 "value": "bar",
172 },
173 map[string]interface{}{
174 "key": "bar",
175 "value": "baz",
176 },
177 },
178 },
179 },
180 },
181 expected: map[string]interface{}{
182 "key": "value",
183 "metadata": []interface{}{
184 map[string]interface{}{
185 "key": "foo",
186 "value": "bar",
187 },
188 map[string]interface{}{
189 "key": "bar",
190 "value": "baz",
191 },
192 },
193 },
194 },
195 {
196 name: "no-op if no metadata given",
197 input: map[string]interface{}{
198 "key": "value",
199 },
200 prev: &Resource{
201 Resource: k8s.Resource{
202 Spec: map[string]interface{}{},
203 },
204 },
205 expected: map[string]interface{}{
206 "key": "value",
207 },
208 },
209 }
210 for _, tc := range tests {
211 t.Run(tc.name, func(t *testing.T) {
212 output := ExpandComputeInstanceMetadata(tc.input, tc.prev)
213 if !test.Equals(t, tc.expected, output) {
214 t.Fatalf("unexpected diff in output (-want +got): \n%v", cmp.Diff(tc.expected, output))
215 }
216 })
217 }
218 }
219
220 func Test_MergeClusterConfigsFromLiveState(t *testing.T) {
221 t.Parallel()
222 resourceMap := google.ResourceMap()
223 tests := []struct {
224 name string
225 config map[string]interface{}
226 liveState map[string]interface{}
227 expected map[string]interface{}
228 }{
229 {
230 name: "no changes on the existing clusters",
231 config: map[string]interface{}{
232 "cluster": []interface{}{
233 map[string]interface{}{
234 "cluster_id": "test-c1",
235 "num_nodes": float64(2),
236 "storage_type": "SSD",
237 "zone": "us-west1-b",
238 },
239 map[string]interface{}{
240 "cluster_id": "test-c2",
241 "num_nodes": float64(3),
242 "zone": "us-east1-c",
243 },
244 map[string]interface{}{
245 "cluster_id": "test-c3",
246 "num_nodes": float64(1),
247 "storage_type": "SSD",
248 "zone": "us-east1-b",
249 },
250 },
251 },
252 liveState: map[string]interface{}{
253 "cluster": []interface{}{
254 map[string]interface{}{
255 "cluster_id": "test-c3",
256 "num_nodes": float64(1),
257 "storage_type": "SSD",
258 "zone": "us-east1-b",
259 },
260 map[string]interface{}{
261 "cluster_id": "test-c1",
262 "num_nodes": float64(2),
263 "storage_type": "SSD",
264 "zone": "us-west1-b",
265 },
266 map[string]interface{}{
267 "cluster_id": "test-c2",
268 "num_nodes": float64(3),
269 "zone": "us-east1-c",
270 "storage_type": "SSD",
271 },
272 },
273 },
274 expected: map[string]interface{}{
275 "cluster": []interface{}{
276 map[string]interface{}{
277 "cluster_id": "test-c1",
278 "num_nodes": float64(2),
279 "storage_type": "SSD",
280 "zone": "us-west1-b",
281 },
282 map[string]interface{}{
283 "cluster_id": "test-c2",
284 "num_nodes": float64(3),
285 "storage_type": "SSD",
286 "zone": "us-east1-c",
287 },
288 map[string]interface{}{
289 "cluster_id": "test-c3",
290 "num_nodes": float64(1),
291 "storage_type": "SSD",
292 "zone": "us-east1-b",
293 },
294 },
295 },
296 },
297 {
298 name: "changes on the existing clusters are preserved",
299 config: map[string]interface{}{
300 "cluster": []interface{}{
301 map[string]interface{}{
302 "cluster_id": "test-c1",
303 "num_nodes": float64(3),
304 "storage_type": "SSD",
305 "zone": "us-west1-b",
306 },
307 map[string]interface{}{
308 "cluster_id": "test-c2",
309 "num_nodes": float64(3),
310 "zone": "us-east1-c",
311 },
312 map[string]interface{}{
313 "cluster_id": "test-c3",
314 "num_nodes": float64(2),
315 "storage_type": "SSD",
316 "zone": "us-east1-b",
317 },
318 },
319 },
320 liveState: map[string]interface{}{
321 "cluster": []interface{}{
322 map[string]interface{}{
323 "cluster_id": "test-c3",
324 "num_nodes": float64(1),
325 "storage_type": "SSD",
326 "zone": "us-east1-b",
327 },
328 map[string]interface{}{
329 "cluster_id": "test-c1",
330 "num_nodes": float64(2),
331 "storage_type": "SSD",
332 "zone": "us-west1-b",
333 },
334 map[string]interface{}{
335 "cluster_id": "test-c2",
336 "num_nodes": float64(3),
337 "zone": "us-east1-c",
338 "storage_type": "SSD",
339 },
340 },
341 },
342 expected: map[string]interface{}{
343 "cluster": []interface{}{
344 map[string]interface{}{
345 "cluster_id": "test-c1",
346 "num_nodes": float64(3),
347 "storage_type": "SSD",
348 "zone": "us-west1-b",
349 },
350 map[string]interface{}{
351 "cluster_id": "test-c2",
352 "num_nodes": float64(3),
353 "storage_type": "SSD",
354 "zone": "us-east1-c",
355 },
356 map[string]interface{}{
357 "cluster_id": "test-c3",
358 "num_nodes": float64(2),
359 "storage_type": "SSD",
360 "zone": "us-east1-b",
361 },
362 },
363 },
364 },
365 {
366 name: "omitted optional fields for the existing clusters are populated from live state",
367 config: map[string]interface{}{
368 "cluster": []interface{}{
369 map[string]interface{}{
370 "cluster_id": "test-c1",
371 "zone": "us-west1-b",
372 },
373 map[string]interface{}{
374 "cluster_id": "test-c2",
375 "zone": "us-east1-c",
376 },
377 map[string]interface{}{
378 "cluster_id": "test-c3",
379 "zone": "us-east1-b",
380 },
381 },
382 },
383 liveState: map[string]interface{}{
384 "cluster": []interface{}{
385 map[string]interface{}{
386 "cluster_id": "test-c3",
387 "num_nodes": float64(1),
388 "storage_type": "SSD",
389 "zone": "us-east1-b",
390 },
391 map[string]interface{}{
392 "cluster_id": "test-c1",
393 "num_nodes": float64(2),
394 "storage_type": "SSD",
395 "zone": "us-west1-b",
396 },
397 map[string]interface{}{
398 "cluster_id": "test-c2",
399 "num_nodes": float64(3),
400 "zone": "us-east1-c",
401 "storage_type": "SSD",
402 },
403 },
404 },
405 expected: map[string]interface{}{
406 "cluster": []interface{}{
407 map[string]interface{}{
408 "cluster_id": "test-c1",
409 "num_nodes": float64(2),
410 "storage_type": "SSD",
411 "zone": "us-west1-b",
412 },
413 map[string]interface{}{
414 "cluster_id": "test-c2",
415 "num_nodes": float64(3),
416 "storage_type": "SSD",
417 "zone": "us-east1-c",
418 },
419 map[string]interface{}{
420 "cluster_id": "test-c3",
421 "num_nodes": float64(1),
422 "storage_type": "SSD",
423 "zone": "us-east1-b",
424 },
425 },
426 },
427 },
428 {
429 name: "remove an old cluster, add a new cluster and change an existing cluster",
430 config: map[string]interface{}{
431 "cluster": []interface{}{
432 map[string]interface{}{
433 "cluster_id": "test-c2",
434 "zone": "us-east1-c",
435 },
436 map[string]interface{}{
437 "cluster_id": "test-c4",
438 "zone": "us-east1-b",
439 "num_nodes": float64(4),
440 },
441 map[string]interface{}{
442 "cluster_id": "test-c3",
443 "zone": "us-east1-b",
444 "num_nodes": float64(2),
445 },
446 },
447 },
448 liveState: map[string]interface{}{
449 "cluster": []interface{}{
450 map[string]interface{}{
451 "cluster_id": "test-c3",
452 "num_nodes": float64(1),
453 "storage_type": "SSD",
454 "zone": "us-east1-b",
455 },
456 map[string]interface{}{
457 "cluster_id": "test-c1",
458 "num_nodes": float64(2),
459 "storage_type": "SSD",
460 "zone": "us-west1-b",
461 },
462 map[string]interface{}{
463 "cluster_id": "test-c2",
464 "num_nodes": float64(3),
465 "zone": "us-east1-c",
466 "storage_type": "SSD",
467 },
468 },
469 },
470 expected: map[string]interface{}{
471 "cluster": []interface{}{
472 map[string]interface{}{
473 "cluster_id": "test-c2",
474 "num_nodes": float64(3),
475 "storage_type": "SSD",
476 "zone": "us-east1-c",
477 },
478 map[string]interface{}{
479 "cluster_id": "test-c4",
480 "zone": "us-east1-b",
481 "num_nodes": float64(4),
482 },
483 map[string]interface{}{
484 "cluster_id": "test-c3",
485 "num_nodes": float64(2),
486 "storage_type": "SSD",
487 "zone": "us-east1-b",
488 },
489 },
490 },
491 },
492 {
493 name: "remove all old clusters",
494 config: map[string]interface{}{
495 "cluster": []interface{}{},
496 },
497 liveState: map[string]interface{}{
498 "cluster": []interface{}{
499 map[string]interface{}{
500 "cluster_id": "test-c3",
501 "num_nodes": float64(1),
502 "storage_type": "SSD",
503 "zone": "us-east1-b",
504 },
505 map[string]interface{}{
506 "cluster_id": "test-c1",
507 "num_nodes": float64(2),
508 "storage_type": "SSD",
509 "zone": "us-west1-b",
510 },
511 map[string]interface{}{
512 "cluster_id": "test-c2",
513 "num_nodes": float64(3),
514 "zone": "us-east1-c",
515 "storage_type": "SSD",
516 },
517 },
518 },
519 expected: map[string]interface{}{
520 "cluster": []interface{}{},
521 },
522 },
523 }
524 for _, tc := range tests {
525 tc := tc
526 t.Run(tc.name, func(t *testing.T) {
527 res, err := MergeClusterConfigsFromLiveStateForBigtableInstance(tc.config, tc.liveState, resourceMap["google_bigtable_instance"])
528 if err != nil {
529 t.Fatalf("unexpected error: %v", err)
530 }
531 if !reflect.DeepEqual(res, tc.expected) {
532 diff := cmp.Diff(tc.expected, res)
533 t.Fatalf("The merged config has diff (-want, +got):\n%v", diff)
534 }
535 })
536 }
537 }
538
View as plain text