1
2
3
4 package kio_test
5
6 import (
7 "bytes"
8 "strings"
9 "testing"
10
11 "github.com/stretchr/testify/assert"
12 . "sigs.k8s.io/kustomize/kyaml/kio"
13 "sigs.k8s.io/kustomize/kyaml/yaml"
14 )
15
16 func TestByteWriter(t *testing.T) {
17 type testCase struct {
18 name string
19 err string
20 items []string
21 functionConfig string
22 results string
23 expectedOutput string
24 instance ByteWriter
25 }
26
27 testCases := []testCase{
28
29
30
31 {
32 name: "wrap_resource_list",
33 instance: ByteWriter{
34 Sort: true,
35 WrappingKind: ResourceListKind,
36 WrappingAPIVersion: ResourceListAPIVersion,
37 },
38 items: []string{
39 `a: b #first`,
40 `c: d # second`,
41 },
42 functionConfig: `
43 e: f
44 g:
45 h:
46 - i # has a list
47 - j`,
48 expectedOutput: `apiVersion: config.kubernetes.io/v1
49 kind: ResourceList
50 items:
51 - a: b #first
52 - c: d # second
53 functionConfig:
54 e: f
55 g:
56 h:
57 - i # has a list
58 - j
59 `,
60 },
61
62
63
64
65 {
66 name: "multiple_items",
67 items: []string{
68 `c: d # second`,
69 `e: f
70 g:
71 h:
72 # has a list
73 - i : [i1, i2] # line comment
74 # has a list 2
75 - j : j1
76 `,
77 `a: b #first`,
78 },
79 expectedOutput: `
80 c: d # second
81 ---
82 e: f
83 g:
84 h:
85 # has a list
86 - i: [i1, i2] # line comment
87 # has a list 2
88 - j: j1
89 ---
90 a: b #first
91 `,
92 },
93
94
95
96
97 {
98 name: "handle_comments",
99 items: []string{
100 `# comment 0
101 apiVersion: apps/v1
102 kind: Deployment
103 metadata:
104 name: my-nginx
105 namespace: my-space
106 labels:
107 env: dev
108 foo: bar
109 spec:
110 # comment 1
111 replicas: 3
112 selector:
113 # comment 2
114 matchLabels: # comment 3
115 # comment 4
116 app: nginx # comment 5
117 template:
118 metadata:
119 labels:
120 app: nginx
121 spec:
122 # comment 6
123 containers:
124 # comment 7
125 - name: nginx
126 image: nginx:1.14.2 # comment 8
127 ports:
128 # comment 9
129 - containerPort: 80 # comment 10
130 `,
131 `apiVersion: v1
132 kind: Service
133 metadata:
134 name: my-service
135 spec:
136 ports:
137 # comment 1
138 - name: etcd-server-ssl
139 port: 2380
140 # comment 2
141 - name: etcd-client-ssl
142 port: 2379
143 `,
144 `apiVersion: constraints.gatekeeper.sh/v1beta1
145 kind: EnforceFoo
146 metadata:
147 name: enforce-foo
148 spec:
149 parameters:
150 naming_rules:
151 - kind: Folder
152 patterns:
153 # comment 1
154 - ^(dev|prod|staging|qa|shared)$
155 `,
156 },
157 expectedOutput: `# comment 0
158 apiVersion: apps/v1
159 kind: Deployment
160 metadata:
161 name: my-nginx
162 namespace: my-space
163 labels:
164 env: dev
165 foo: bar
166 spec:
167 # comment 1
168 replicas: 3
169 selector:
170 # comment 2
171 matchLabels: # comment 3
172 # comment 4
173 app: nginx # comment 5
174 template:
175 metadata:
176 labels:
177 app: nginx
178 spec:
179 # comment 6
180 containers:
181 # comment 7
182 - name: nginx
183 image: nginx:1.14.2 # comment 8
184 ports:
185 # comment 9
186 - containerPort: 80 # comment 10
187 ---
188 apiVersion: v1
189 kind: Service
190 metadata:
191 name: my-service
192 spec:
193 ports:
194 # comment 1
195 - name: etcd-server-ssl
196 port: 2380
197 # comment 2
198 - name: etcd-client-ssl
199 port: 2379
200 ---
201 apiVersion: constraints.gatekeeper.sh/v1beta1
202 kind: EnforceFoo
203 metadata:
204 name: enforce-foo
205 spec:
206 parameters:
207 naming_rules:
208 - kind: Folder
209 patterns:
210 # comment 1
211 - ^(dev|prod|staging|qa|shared)$
212 `,
213 },
214
215
216
217
218 {
219 name: "sort_keep_annotation",
220 instance: ByteWriter{Sort: true, KeepReaderAnnotations: true},
221 items: []string{
222 `a: b #first
223 metadata:
224 annotations:
225 internal.config.kubernetes.io/index: 0
226 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
227 `,
228 `e: f
229 g:
230 h:
231 - i # has a list
232 - j
233 metadata:
234 annotations:
235 internal.config.kubernetes.io/index: 0
236 internal.config.kubernetes.io/path: "a/b/b_test.yaml"
237 `,
238 `c: d # second
239 metadata:
240 annotations:
241 internal.config.kubernetes.io/index: 1
242 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
243 `,
244 },
245
246 expectedOutput: `a: b #first
247 metadata:
248 annotations:
249 internal.config.kubernetes.io/index: 0
250 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
251 config.kubernetes.io/path: 'a/b/a_test.yaml'
252 config.kubernetes.io/index: '0'
253 ---
254 c: d # second
255 metadata:
256 annotations:
257 internal.config.kubernetes.io/index: 1
258 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
259 config.kubernetes.io/path: 'a/b/a_test.yaml'
260 config.kubernetes.io/index: '1'
261 ---
262 e: f
263 g:
264 h:
265 - i # has a list
266 - j
267 metadata:
268 annotations:
269 internal.config.kubernetes.io/index: 0
270 internal.config.kubernetes.io/path: "a/b/b_test.yaml"
271 config.kubernetes.io/path: 'a/b/b_test.yaml'
272 config.kubernetes.io/index: '0'
273 `,
274 },
275
276
277
278
279 {
280 name: "sort_partial_annotations",
281 instance: ByteWriter{Sort: true},
282 items: []string{
283 `a: b #first
284 metadata:
285 annotations:
286 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
287 `,
288 `c: d # second
289 metadata:
290 annotations:
291 internal.config.kubernetes.io/index: 1
292 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
293 `,
294 `e: f
295 g:
296 h:
297 - i # has a list
298 - j
299 `,
300 },
301
302 expectedOutput: `e: f
303 g:
304 h:
305 - i # has a list
306 - j
307 ---
308 a: b #first
309 metadata:
310 annotations:
311 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
312 config.kubernetes.io/path: 'a/b/a_test.yaml'
313 ---
314 c: d # second
315 metadata:
316 annotations:
317 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
318 config.kubernetes.io/path: 'a/b/a_test.yaml'
319 `,
320 },
321
322
323
324
325 {
326 name: "keep_annotation_seqindent",
327 instance: ByteWriter{KeepReaderAnnotations: true},
328 items: []string{
329 `a: b #first
330 metadata:
331 annotations:
332 internal.config.kubernetes.io/index: 0
333 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
334 internal.config.kubernetes.io/index: "compact"
335 `,
336 `e: f
337 g:
338 h:
339 - i # has a list
340 - j
341 metadata:
342 annotations:
343 internal.config.kubernetes.io/index: 0
344 internal.config.kubernetes.io/path: "a/b/b_test.yaml"
345 internal.config.kubernetes.io/seqindent: "wide"
346 `,
347 `c: d # second
348 metadata:
349 annotations:
350 internal.config.kubernetes.io/index: 1
351 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
352 internal.config.kubernetes.io/seqindent: "compact"
353 `,
354 },
355
356 expectedOutput: `a: b #first
357 metadata:
358 annotations:
359 internal.config.kubernetes.io/index: 0
360 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
361 internal.config.kubernetes.io/index: "compact"
362 ---
363 e: f
364 g:
365 h:
366 - i # has a list
367 - j
368 metadata:
369 annotations:
370 internal.config.kubernetes.io/index: 0
371 internal.config.kubernetes.io/path: "a/b/b_test.yaml"
372 internal.config.kubernetes.io/seqindent: "wide"
373 ---
374 c: d # second
375 metadata:
376 annotations:
377 internal.config.kubernetes.io/index: 1
378 internal.config.kubernetes.io/path: "a/b/a_test.yaml"
379 internal.config.kubernetes.io/seqindent: "compact"
380 `,
381 },
382
383
384
385
386 {
387 name: "encode_valid_json",
388 items: []string{
389 `{
390 "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123",
391 metadata: {
392 annotations: {
393 internal.config.kubernetes.io/path: test.json
394 }
395 }
396 }`,
397 },
398
399 expectedOutput: `{
400 "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123",
401 "metadata": {
402 "annotations": {
403 "internal.config.kubernetes.io/path": "test.json"
404 }
405 }
406 }`,
407 },
408
409
410
411
412 {
413 name: "encode_valid_json_remove_seqindent_annotation",
414 items: []string{
415 `{
416 "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123",
417 metadata: {
418 annotations: {
419 "internal.config.kubernetes.io/seqindent": "compact",
420 "internal.config.kubernetes.io/index": "0",
421 "internal.config.kubernetes.io/path": "test.json"
422 }
423 }
424 }`,
425 },
426
427 expectedOutput: `{
428 "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123",
429 "metadata": {
430 "annotations": {
431 "internal.config.kubernetes.io/path": "test.json"
432 }
433 }
434 }`,
435 },
436
437
438
439
440 {
441 name: "encode_unformatted_valid_json",
442 items: []string{
443 `{ "a": "b", metadata: { annotations: { internal.config.kubernetes.io/path: test.json } } }`,
444 },
445
446 expectedOutput: `{
447 "a": "b",
448 "metadata": {
449 "annotations": {
450 "internal.config.kubernetes.io/path": "test.json"
451 }
452 }
453 }`,
454 },
455
456
457
458
459 {
460 name: "encode_wrapped_json_as_yaml",
461 instance: ByteWriter{
462 Sort: true,
463 WrappingKind: ResourceListKind,
464 WrappingAPIVersion: ResourceListAPIVersion,
465 },
466 items: []string{
467 `{
468 "a": "b",
469 "metadata": {
470 "annotations": {
471 "internal.config.kubernetes.io/path": "test.json"
472 }
473 }
474 }`,
475 },
476
477 expectedOutput: `apiVersion: config.kubernetes.io/v1
478 kind: ResourceList
479 items:
480 - {"a": "b", "metadata": {"annotations": {"internal.config.kubernetes.io/path": "test.json"}}}
481 `,
482 },
483
484
485
486
487 {
488 name: "encode_multi_doc_json_as_yaml",
489 items: []string{
490 `{
491 "a": "b",
492 "metadata": {
493 "annotations": {
494 "internal.config.kubernetes.io/path": "test-1.json"
495 }
496 }
497 }`,
498 `{
499 "c": "d",
500 "metadata": {
501 "annotations": {
502 "internal.config.kubernetes.io/path": "test-2.json"
503 }
504 }
505 }`,
506 },
507
508 expectedOutput: `
509 {"a": "b", "metadata": {"annotations": {"internal.config.kubernetes.io/path": "test-1.json"}}}
510 ---
511 {"c": "d", "metadata": {"annotations": {"internal.config.kubernetes.io/path": "test-2.json"}}}
512 `,
513 },
514 }
515
516 for i := range testCases {
517 tc := testCases[i]
518 t.Run(tc.name, func(t *testing.T) {
519 actual := &bytes.Buffer{}
520 w := tc.instance
521 w.Writer = actual
522
523 if tc.functionConfig != "" {
524 w.FunctionConfig = yaml.MustParse(tc.functionConfig)
525 }
526
527 if tc.results != "" {
528 w.Results = yaml.MustParse(tc.results)
529 }
530
531 var items []*yaml.RNode
532 for i := range tc.items {
533 items = append(items, yaml.MustParse(tc.items[i]))
534 }
535 err := w.Write(items)
536
537 if tc.err != "" {
538 if !assert.EqualError(t, err, tc.err) {
539 t.FailNow()
540 }
541 return
542 }
543
544 if !assert.NoError(t, err) {
545 t.FailNow()
546 }
547 if !assert.Equal(t,
548 strings.TrimSpace(tc.expectedOutput), strings.TrimSpace(actual.String())) {
549 t.FailNow()
550 }
551 })
552 }
553 }
554
View as plain text