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 }