...

Source file src/sigs.k8s.io/kustomize/kyaml/kio/byteio_writer_test.go

Documentation: sigs.k8s.io/kustomize/kyaml/kio

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     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  		// Test Case
    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  		// Test Case
    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  		// Test Case
    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  		// Test Case
   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  		// Test Case
   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  		// Test Case
   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  		// Test Case
   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  		// Test Case
   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  		// Test Case
   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  		// Test Case
   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  		// Test Case
   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