github.com/minio/controller-tools@v0.4.7/pkg/crd/parser_integration_test.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package crd_test 18 19 import ( 20 "io/ioutil" 21 "os" 22 23 "github.com/google/go-cmp/cmp" 24 . "github.com/onsi/ginkgo" 25 . "github.com/onsi/gomega" 26 "golang.org/x/tools/go/packages" 27 apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 28 "k8s.io/apimachinery/pkg/runtime/schema" 29 "sigs.k8s.io/yaml" 30 31 "github.com/minio/controller-tools/pkg/crd" 32 crdmarkers "github.com/minio/controller-tools/pkg/crd/markers" 33 "github.com/minio/controller-tools/pkg/loader" 34 "github.com/minio/controller-tools/pkg/markers" 35 ) 36 37 func packageErrors(pkg *loader.Package, filterKinds ...packages.ErrorKind) error { 38 toSkip := make(map[packages.ErrorKind]struct{}) 39 for _, errKind := range filterKinds { 40 toSkip[errKind] = struct{}{} 41 } 42 var outErr error 43 packages.Visit([]*packages.Package{pkg.Package}, nil, func(pkgRaw *packages.Package) { 44 for _, err := range pkgRaw.Errors { 45 if _, skip := toSkip[err.Kind]; skip { 46 continue 47 } 48 outErr = err 49 } 50 }) 51 return outErr 52 } 53 54 var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func() { 55 It("should properly generate and flatten the rewritten CronJob schema", func() { 56 // TODO(directxman12): test generation across multiple versions (right 57 // now, we're trusting k/k's conversion code, though, which is probably 58 // fine for the time being) 59 By("switching into testdata to appease go modules") 60 cwd, err := os.Getwd() 61 Expect(err).NotTo(HaveOccurred()) 62 Expect(os.Chdir("./testdata")).To(Succeed()) // go modules are directory-sensitive 63 defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }() 64 65 By("loading the roots") 66 pkgs, err := loader.LoadRoots(".") 67 Expect(err).NotTo(HaveOccurred()) 68 Expect(pkgs).To(HaveLen(1)) 69 cronJobPkg := pkgs[0] 70 71 By("setting up the parser") 72 reg := &markers.Registry{} 73 Expect(crdmarkers.Register(reg)).To(Succeed()) 74 parser := &crd.Parser{ 75 Collector: &markers.Collector{Registry: reg}, 76 Checker: &loader.TypeChecker{}, 77 } 78 crd.AddKnownTypes(parser) 79 80 By("requesting that the package be parsed") 81 parser.NeedPackage(cronJobPkg) 82 83 By("requesting that the CRD be generated") 84 groupKind := schema.GroupKind{Kind: "CronJob", Group: "testdata.kubebuilder.io"} 85 parser.NeedCRDFor(groupKind, nil) 86 87 By("fixing top level ObjectMeta on the CRD") 88 crd.FixTopLevelMetadata(parser.CustomResourceDefinitions[groupKind]) 89 90 By("checking that no errors occurred along the way (expect for type errors)") 91 Expect(packageErrors(cronJobPkg, packages.TypeError)).NotTo(HaveOccurred()) 92 93 By("checking that the CRD is present") 94 Expect(parser.CustomResourceDefinitions).To(HaveKey(groupKind)) 95 96 By("loading the desired YAML") 97 expectedFile, err := ioutil.ReadFile("testdata.kubebuilder.io_cronjobs.yaml") 98 Expect(err).NotTo(HaveOccurred()) 99 100 By("parsing the desired YAML") 101 var crd apiext.CustomResourceDefinition 102 Expect(yaml.Unmarshal(expectedFile, &crd)).To(Succeed()) 103 // clear the annotations -- we don't care about the attribution annotation 104 crd.Annotations = nil 105 106 By("comparing the two") 107 Expect(parser.CustomResourceDefinitions[groupKind]).To(Equal(crd), "type not as expected, check pkg/crd/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(parser.CustomResourceDefinitions[groupKind], crd)) 108 }) 109 110 It("should generate plural words for Kind correctly", func() { 111 By("switching into testdata to appease go modules") 112 cwd, err := os.Getwd() 113 Expect(err).NotTo(HaveOccurred()) 114 Expect(os.Chdir("./testdata/plural")).To(Succeed()) 115 defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }() 116 117 By("loading the roots") 118 pkgs, err := loader.LoadRoots(".") 119 Expect(err).NotTo(HaveOccurred()) 120 Expect(pkgs).To(HaveLen(1)) 121 pkg := pkgs[0] 122 123 By("setting up the parser") 124 reg := &markers.Registry{} 125 Expect(crdmarkers.Register(reg)).To(Succeed()) 126 parser := &crd.Parser{ 127 Collector: &markers.Collector{Registry: reg}, 128 Checker: &loader.TypeChecker{}, 129 } 130 crd.AddKnownTypes(parser) 131 132 By("requesting that the package be parsed") 133 parser.NeedPackage(pkg) 134 135 By("requesting that the CRD be generated") 136 groupKind := schema.GroupKind{Kind: "TestQuota", Group: "plural.example.com"} 137 parser.NeedCRDFor(groupKind, nil) 138 139 By("fixing top level ObjectMeta on the CRD") 140 crd.FixTopLevelMetadata(parser.CustomResourceDefinitions[groupKind]) 141 142 By("loading the desired YAML") 143 expectedFile, err := ioutil.ReadFile("plural.example.com_testquotas.yaml") 144 Expect(err).NotTo(HaveOccurred()) 145 146 By("parsing the desired YAML") 147 var crd apiext.CustomResourceDefinition 148 Expect(yaml.Unmarshal(expectedFile, &crd)).To(Succeed()) 149 // clear the annotations -- we don't care about the attribution annotation 150 crd.Annotations = nil 151 152 By("comparing the two") 153 Expect(parser.CustomResourceDefinitions[groupKind]).To(Equal(crd), "type not as expected, check pkg/crd/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(parser.CustomResourceDefinitions[groupKind], crd)) 154 }) 155 156 It("should skip api internal package", func() { 157 By("switching into testdata to appease go modules") 158 cwd, err := os.Getwd() 159 Expect(err).NotTo(HaveOccurred()) 160 Expect(os.Chdir("./testdata/internal_version")).To(Succeed()) // go modules are directory-sensitive 161 defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }() 162 163 By("loading the roots") 164 pkgs, err := loader.LoadRoots(".") 165 Expect(err).NotTo(HaveOccurred()) 166 Expect(pkgs).To(HaveLen(1)) 167 cronJobPkg := pkgs[0] 168 169 By("setting up the parser") 170 reg := &markers.Registry{} 171 Expect(crdmarkers.Register(reg)).To(Succeed()) 172 parser := &crd.Parser{ 173 Collector: &markers.Collector{Registry: reg}, 174 Checker: &loader.TypeChecker{}, 175 } 176 crd.AddKnownTypes(parser) 177 178 By("requesting that the package be parsed") 179 parser.NeedPackage(cronJobPkg) 180 181 By("checking that there is no GroupVersion") 182 Expect(parser.GroupVersions).To(BeEmpty()) 183 184 By("checking that there are no Types") 185 Expect(parser.Types).To(BeEmpty()) 186 187 By("checking that no errors occurred along the way (expect for type errors)") 188 Expect(packageErrors(cronJobPkg, packages.TypeError)).NotTo(HaveOccurred()) 189 190 }) 191 })