...

Source file src/sigs.k8s.io/kustomize/api/internal/accumulator/refvartransformer_test.go

Documentation: sigs.k8s.io/kustomize/api/internal/accumulator

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package accumulator
     5  
     6  import (
     7  	"reflect"
     8  	"testing"
     9  
    10  	"sigs.k8s.io/kustomize/api/resmap"
    11  	resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
    12  	"sigs.k8s.io/kustomize/api/types"
    13  	"sigs.k8s.io/kustomize/kyaml/resid"
    14  )
    15  
    16  func TestRefVarTransformer(t *testing.T) {
    17  	type given struct {
    18  		varMap map[string]interface{}
    19  		fs     []types.FieldSpec
    20  		res    resmap.ResMap
    21  	}
    22  	type expected struct {
    23  		res    resmap.ResMap
    24  		unused []string
    25  	}
    26  	testCases := map[string]struct {
    27  		given      given
    28  		expected   expected
    29  		errMessage string
    30  	}{
    31  		"var replacement in map[string]": {
    32  			given: given{
    33  				varMap: map[string]interface{}{
    34  					"FOO": "replacementForFoo",
    35  					"BAR": "replacementForBar",
    36  					"BAZ": int64(5),
    37  					"BOO": true,
    38  				},
    39  				fs: []types.FieldSpec{
    40  					{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/map"},
    41  					{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/slice"},
    42  					{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/interface"},
    43  					{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/num"},
    44  				},
    45  				res: resmaptest_test.NewRmBuilderDefault(t).
    46  					Add(map[string]interface{}{
    47  						"apiVersion": "v1",
    48  						"kind":       "ConfigMap",
    49  						"metadata": map[string]interface{}{
    50  							"name": "cm1",
    51  						},
    52  						"data": map[string]interface{}{
    53  							"map": map[string]interface{}{
    54  								"item1": "$(FOO)",
    55  								"item2": "bla",
    56  								"item3": "$(BAZ)",
    57  								"item4": "$(BAZ)+$(BAZ)",
    58  								"item5": "$(BOO)",
    59  								"item6": "if $(BOO)",
    60  								"item7": int64(2019),
    61  							},
    62  							"slice": []interface{}{
    63  								"$(FOO)",
    64  								"bla",
    65  								"$(BAZ)",
    66  								"$(BAZ)+$(BAZ)",
    67  								"$(BOO)",
    68  								"if $(BOO)",
    69  							},
    70  							"interface": "$(FOO)",
    71  							"num":       int64(2019),
    72  						}}).ResMap(),
    73  			},
    74  			expected: expected{
    75  				res: resmaptest_test.NewRmBuilderDefault(t).
    76  					Add(map[string]interface{}{
    77  						"apiVersion": "v1",
    78  						"kind":       "ConfigMap",
    79  						"metadata": map[string]interface{}{
    80  							"name": "cm1",
    81  						},
    82  						"data": map[string]interface{}{
    83  							"map": map[string]interface{}{
    84  								"item1": "replacementForFoo",
    85  								"item2": "bla",
    86  								"item3": int64(5),
    87  								"item4": "5+5",
    88  								"item5": true,
    89  								"item6": "if true",
    90  								"item7": int64(2019),
    91  							},
    92  							"slice": []interface{}{
    93  								"replacementForFoo",
    94  								"bla",
    95  								int64(5),
    96  								"5+5",
    97  								true,
    98  								"if true",
    99  							},
   100  							"interface": "replacementForFoo",
   101  							"num":       int64(2019),
   102  						}}).ResMap(),
   103  				unused: []string{"BAR"},
   104  			},
   105  		},
   106  		"var replacement panic in map[string]": {
   107  			given: given{
   108  				varMap: map[string]interface{}{},
   109  				fs: []types.FieldSpec{
   110  					{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/slice"},
   111  				},
   112  				res: resmaptest_test.NewRmBuilderDefault(t).
   113  					Add(map[string]interface{}{
   114  						"apiVersion": "v1",
   115  						"kind":       "ConfigMap",
   116  						"metadata": map[string]interface{}{
   117  							"name": "cm1",
   118  						},
   119  						"data": map[string]interface{}{
   120  							"slice": []interface{}{5}, // noticeably *not* a []string
   121  						}}).ResMap(),
   122  			},
   123  			errMessage: `considering field 'data/slice' of object ConfigMap.v1.[noGrp]/cm1.[noNs]: invalid value type expect a string`,
   124  		},
   125  		"var replacement in nil": {
   126  			given: given{
   127  				varMap: map[string]interface{}{},
   128  				fs: []types.FieldSpec{
   129  					{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/nil"},
   130  				},
   131  				res: resmaptest_test.NewRmBuilderDefault(t).
   132  					Add(map[string]interface{}{
   133  						"apiVersion": "v1",
   134  						"kind":       "ConfigMap",
   135  						"metadata": map[string]interface{}{
   136  							"name": "cm1",
   137  						},
   138  						"data": map[string]interface{}{
   139  							"nil": nil, // noticeably *not* a []string
   140  						}}).ResMap(),
   141  			},
   142  			expected: expected{
   143  				res: resmaptest_test.NewRmBuilderDefault(t).
   144  					Add(map[string]interface{}{
   145  						"apiVersion": "v1",
   146  						"kind":       "ConfigMap",
   147  						"metadata": map[string]interface{}{
   148  							"name": "cm1",
   149  						},
   150  						"data": map[string]interface{}{
   151  							"nil": nil, // noticeably *not* a []string
   152  						}}).ResMap(),
   153  			},
   154  		},
   155  	}
   156  
   157  	for tn, tc := range testCases {
   158  		t.Run(tn, func(t *testing.T) {
   159  			tr := newRefVarTransformer(tc.given.varMap, tc.given.fs)
   160  			err := tr.Transform(tc.given.res)
   161  			if tc.errMessage != "" {
   162  				if err == nil {
   163  					t.Fatalf("missing expected error %v", tc.errMessage)
   164  				} else if err.Error() != tc.errMessage {
   165  					t.Fatalf(`actual error doesn't match expected error:
   166  ACTUAL: %v
   167  EXPECTED: %v`,
   168  						err.Error(), tc.errMessage)
   169  				}
   170  			} else {
   171  				if err != nil {
   172  					t.Errorf("unexpected error: %v", err)
   173  				}
   174  
   175  				a, e := tc.given.res, tc.expected.res
   176  				if !reflect.DeepEqual(a, e) {
   177  					err = e.ErrorIfNotEqualLists(a)
   178  					t.Fatalf(`actual doesn't match expected:
   179  ACTUAL:
   180  %v
   181  EXPECTED:
   182  %v
   183  ERR: %v`,
   184  						a, e, err)
   185  				}
   186  			}
   187  		})
   188  	}
   189  }
   190  

View as plain text