github.com/SamarSidharth/kpt@v0.0.0-20231122062228-c7d747ae3ace/pkg/live/rgpath_test.go (about)

     1  // Copyright 2020 The kpt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package live
    16  
    17  import (
    18  	"os"
    19  	"path/filepath"
    20  	"sort"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    25  	"k8s.io/apimachinery/pkg/runtime/schema"
    26  	cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
    27  	"k8s.io/kubectl/pkg/scheme"
    28  	"sigs.k8s.io/cli-utils/pkg/manifestreader"
    29  	"sigs.k8s.io/cli-utils/pkg/object"
    30  )
    31  
    32  func TestPathManifestReader_Read(t *testing.T) {
    33  	_ = apiextv1.AddToScheme(scheme.Scheme)
    34  	testCases := map[string]struct {
    35  		manifests      map[string]string
    36  		namespace      string
    37  		expectedObjs   object.ObjMetadataSet
    38  		expectedErrMsg string
    39  	}{
    40  		"Empty package is ok": {
    41  			manifests:    map[string]string{},
    42  			namespace:    "test-namespace",
    43  			expectedObjs: []object.ObjMetadata{},
    44  		},
    45  		"Kptfile are ignored": {
    46  			manifests: map[string]string{
    47  				"Kptfile":    kptFile,
    48  				"pod-a.yaml": podA,
    49  			},
    50  			namespace: "test-namespace",
    51  			expectedObjs: []object.ObjMetadata{
    52  				{
    53  					GroupKind: schema.GroupKind{
    54  						Kind: "Pod",
    55  					},
    56  					Name:      "pod-a",
    57  					Namespace: "test-namespace",
    58  				},
    59  			},
    60  		},
    61  		"Namespace gets set on namespaced resources": {
    62  			manifests: map[string]string{
    63  				"pod-a.yaml":      podA,
    64  				"deployment.yaml": deploymentA,
    65  			},
    66  			namespace: "test-namespace",
    67  			expectedObjs: []object.ObjMetadata{
    68  				{
    69  					GroupKind: schema.GroupKind{
    70  						Kind: "Pod",
    71  					},
    72  					Name:      "pod-a",
    73  					Namespace: "test-namespace",
    74  				},
    75  				{
    76  					GroupKind: schema.GroupKind{
    77  						Group: "apps",
    78  						Kind:  "Deployment",
    79  					},
    80  					Name:      "test-deployment",
    81  					Namespace: "test-namespace",
    82  				},
    83  			},
    84  		},
    85  		"Function config resources are not ignored": {
    86  			manifests: map[string]string{
    87  				"Kptfile":           kptFileWithPipeline,
    88  				"pod-a.yaml":        podA,
    89  				"deployment-a.yaml": deploymentA,
    90  				"cm.yaml":           configMap,
    91  			},
    92  			namespace: "test-namespace",
    93  			expectedObjs: []object.ObjMetadata{
    94  				{
    95  					GroupKind: schema.GroupKind{
    96  						Group: "",
    97  						Kind:  "ConfigMap",
    98  					},
    99  					Name:      "cm",
   100  					Namespace: "test-namespace",
   101  				},
   102  				{
   103  					GroupKind: schema.GroupKind{
   104  						Kind: "Pod",
   105  					},
   106  					Name:      "pod-a",
   107  					Namespace: "test-namespace",
   108  				},
   109  				{
   110  					GroupKind: schema.GroupKind{
   111  						Group: "apps",
   112  						Kind:  "Deployment",
   113  					},
   114  					Name:      "test-deployment",
   115  					Namespace: "test-namespace",
   116  				},
   117  			},
   118  		},
   119  		"Function config resources which are marked as not being local config remains": {
   120  			manifests: map[string]string{
   121  				"Kptfile":           kptFileWithPipeline,
   122  				"deployment-a.yaml": deploymentA,
   123  				"cm.yaml":           notLocalConfig,
   124  			},
   125  			namespace: "test-namespace",
   126  			expectedObjs: []object.ObjMetadata{
   127  				{
   128  					GroupKind: schema.GroupKind{
   129  						Group: "",
   130  						Kind:  "ConfigMap",
   131  					},
   132  					Name:      "cm",
   133  					Namespace: "test-namespace",
   134  				},
   135  				{
   136  					GroupKind: schema.GroupKind{
   137  						Group: "apps",
   138  						Kind:  "Deployment",
   139  					},
   140  					Name:      "test-deployment",
   141  					Namespace: "test-namespace",
   142  				},
   143  			},
   144  		},
   145  		"CR and CRD in the same set is ok": {
   146  			manifests: map[string]string{
   147  				"crd.yaml": crd,
   148  				"cr.yaml":  cr,
   149  			},
   150  			namespace: "test-namespace",
   151  			expectedObjs: []object.ObjMetadata{
   152  				{
   153  					GroupKind: schema.GroupKind{
   154  						Group: "custom.io",
   155  						Kind:  "Custom",
   156  					},
   157  					Name: "cr",
   158  				},
   159  				{
   160  					GroupKind: schema.GroupKind{
   161  						Group: "apiextensions.k8s.io",
   162  						Kind:  "CustomResourceDefinition",
   163  					},
   164  					Name: "custom.io",
   165  				},
   166  			},
   167  		},
   168  		"CR with unknown type is not allowed": {
   169  			manifests: map[string]string{
   170  				"cr.yaml": cr,
   171  			},
   172  			namespace:      "test-namespace",
   173  			expectedErrMsg: "unknown resource types: custom.io/v1/Custom",
   174  		},
   175  		"local-config is filtered out": {
   176  			manifests: map[string]string{
   177  				"deployment-a.yaml": deploymentA,
   178  				"lc.yaml":           localConfig,
   179  			},
   180  			namespace: "test-namespace",
   181  			expectedObjs: []object.ObjMetadata{
   182  				{
   183  					GroupKind: schema.GroupKind{
   184  						Group: "apps",
   185  						Kind:  "Deployment",
   186  					},
   187  					Name:      "test-deployment",
   188  					Namespace: "test-namespace",
   189  				},
   190  			},
   191  		},
   192  	}
   193  
   194  	for tn, tc := range testCases {
   195  		t.Run(tn, func(t *testing.T) {
   196  			tf := cmdtesting.NewTestFactory().WithNamespace("test-ns")
   197  			defer tf.Cleanup()
   198  
   199  			mapper, err := tf.ToRESTMapper()
   200  			if !assert.NoError(t, err) {
   201  				t.FailNow()
   202  			}
   203  
   204  			// Set up the yaml manifests (including Kptfile) in temp dir.
   205  			dir := t.TempDir()
   206  			for filename, content := range tc.manifests {
   207  				p := filepath.Join(dir, filename)
   208  				err := os.WriteFile(p, []byte(content), 0600)
   209  				assert.NoError(t, err)
   210  			}
   211  
   212  			// Create the ResourceGroupPathManifestReader, and Read()
   213  			// the manifests into unstructureds
   214  			rgPathReader := &ResourceGroupPathManifestReader{
   215  				PkgPath: dir,
   216  				ReaderOptions: manifestreader.ReaderOptions{
   217  					Mapper:           mapper,
   218  					Namespace:        tc.namespace,
   219  					EnforceNamespace: false,
   220  				},
   221  			}
   222  			readObjs, err := rgPathReader.Read()
   223  			if tc.expectedErrMsg != "" {
   224  				if !assert.Error(t, err) {
   225  					t.FailNow()
   226  				}
   227  				assert.Contains(t, err.Error(), tc.expectedErrMsg)
   228  				return
   229  			}
   230  			assert.NoError(t, err)
   231  
   232  			readObjMetas := object.UnstructuredSetToObjMetadataSet(readObjs)
   233  
   234  			sort.Slice(readObjMetas, func(i, j int) bool {
   235  				return readObjMetas[i].String() < readObjMetas[j].String()
   236  			})
   237  			assert.Equal(t, tc.expectedObjs, readObjMetas)
   238  		})
   239  	}
   240  }