sigs.k8s.io/kubebuilder/v3@v3.14.0/pkg/config/store/yaml/store_test.go (about) 1 /* 2 Copyright 2022 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 yaml 18 19 import ( 20 "errors" 21 "os" 22 "testing" 23 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 "github.com/spf13/afero" 27 28 "sigs.k8s.io/kubebuilder/v3/pkg/config" 29 "sigs.k8s.io/kubebuilder/v3/pkg/config/store" 30 cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2" 31 "sigs.k8s.io/kubebuilder/v3/pkg/machinery" 32 ) 33 34 func TestConfigStoreYaml(t *testing.T) { 35 RegisterFailHandler(Fail) 36 RunSpecs(t, "Config Store YAML Suite") 37 } 38 39 var _ = Describe("New", func() { 40 It("should return a new empty store", func() { 41 s := New(machinery.Filesystem{FS: afero.NewMemMapFs()}) 42 Expect(s.Config()).To(BeNil()) 43 44 ys, ok := s.(*yamlStore) 45 Expect(ok).To(BeTrue()) 46 Expect(ys.fs).NotTo(BeNil()) 47 }) 48 }) 49 50 var _ = Describe("yamlStore", func() { 51 const ( 52 v2File = `version: "2" 53 ` 54 unversionedFile = `version: 55 ` 56 nonexistentVersionFile = `version: 1-alpha 57 ` // v1-alpha never existed 58 wrongFile = `version: "2" 59 layout: "" 60 ` // layout field does not exist in v2 61 ) 62 63 var ( 64 s *yamlStore 65 66 path = DefaultPath + "2" 67 ) 68 69 BeforeEach(func() { 70 s = New(machinery.Filesystem{FS: afero.NewMemMapFs()}).(*yamlStore) 71 }) 72 73 Context("New", func() { 74 It("should initialize a new Config backend for the provided version", func() { 75 Expect(s.New(cfgv2.Version)).To(Succeed()) 76 Expect(s.fs).NotTo(BeNil()) 77 Expect(s.mustNotExist).To(BeTrue()) 78 Expect(s.Config()).NotTo(BeNil()) 79 Expect(s.Config().GetVersion().Compare(cfgv2.Version)).To(Equal(0)) 80 }) 81 82 It("should fail for an unregistered config version", func() { 83 Expect(s.New(config.Version{})).NotTo(Succeed()) 84 }) 85 }) 86 87 Context("Load", func() { 88 It("should load the Config from an existing file at the default path", func() { 89 Expect(afero.WriteFile(s.fs, DefaultPath, []byte(commentStr+v2File), os.ModePerm)).To(Succeed()) 90 91 Expect(s.Load()).To(Succeed()) 92 Expect(s.fs).NotTo(BeNil()) 93 Expect(s.mustNotExist).To(BeFalse()) 94 Expect(s.Config()).NotTo(BeNil()) 95 Expect(s.Config().GetVersion().Compare(cfgv2.Version)).To(Equal(0)) 96 }) 97 98 It("should fail if no file exists at the default path", func() { 99 err := s.Load() 100 Expect(err).To(HaveOccurred()) 101 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 102 }) 103 104 It("should fail if unable to identify the version of the file at the default path", func() { 105 Expect(afero.WriteFile(s.fs, DefaultPath, []byte(commentStr+unversionedFile), os.ModePerm)).To(Succeed()) 106 107 err := s.Load() 108 Expect(err).To(HaveOccurred()) 109 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 110 }) 111 112 It("should fail if unable to create a Config for the version of the file at the default path", func() { 113 Expect(afero.WriteFile(s.fs, DefaultPath, []byte(commentStr+nonexistentVersionFile), os.ModePerm)).To(Succeed()) 114 115 err := s.Load() 116 Expect(err).To(HaveOccurred()) 117 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 118 }) 119 120 It("should fail if unable to unmarshal the file at the default path", func() { 121 Expect(afero.WriteFile(s.fs, DefaultPath, []byte(commentStr+wrongFile), os.ModePerm)).To(Succeed()) 122 123 err := s.Load() 124 Expect(err).To(HaveOccurred()) 125 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 126 }) 127 }) 128 129 Context("LoadFrom", func() { 130 It("should load the Config from an existing file from the specified path", func() { 131 Expect(afero.WriteFile(s.fs, path, []byte(commentStr+v2File), os.ModePerm)).To(Succeed()) 132 133 Expect(s.LoadFrom(path)).To(Succeed()) 134 Expect(s.fs).NotTo(BeNil()) 135 Expect(s.mustNotExist).To(BeFalse()) 136 Expect(s.Config()).NotTo(BeNil()) 137 Expect(s.Config().GetVersion().Compare(cfgv2.Version)).To(Equal(0)) 138 }) 139 140 It("should fail if no file exists at the specified path", func() { 141 err := s.LoadFrom(path) 142 Expect(err).To(HaveOccurred()) 143 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 144 }) 145 146 It("should fail if unable to identify the version of the file at the specified path", func() { 147 Expect(afero.WriteFile(s.fs, path, []byte(commentStr+unversionedFile), os.ModePerm)).To(Succeed()) 148 149 err := s.LoadFrom(path) 150 Expect(err).To(HaveOccurred()) 151 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 152 }) 153 154 It("should fail if unable to create a Config for the version of the file at the specified path", func() { 155 Expect(afero.WriteFile(s.fs, path, []byte(commentStr+nonexistentVersionFile), os.ModePerm)).To(Succeed()) 156 157 err := s.LoadFrom(path) 158 Expect(err).To(HaveOccurred()) 159 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 160 }) 161 162 It("should fail if unable to unmarshal the file at the specified path", func() { 163 Expect(afero.WriteFile(s.fs, path, []byte(commentStr+wrongFile), os.ModePerm)).To(Succeed()) 164 165 err := s.LoadFrom(path) 166 Expect(err).To(HaveOccurred()) 167 Expect(errors.As(err, &store.LoadError{})).To(BeTrue()) 168 }) 169 }) 170 171 Context("Save", func() { 172 It("should succeed for a valid config", func() { 173 s.cfg = cfgv2.New() 174 Expect(s.Save()).To(Succeed()) 175 176 cfgBytes, err := afero.ReadFile(s.fs, DefaultPath) 177 Expect(err).NotTo(HaveOccurred()) 178 Expect(string(cfgBytes)).To(Equal(commentStr + v2File)) 179 }) 180 181 It("should succeed for a valid config that must not exist", func() { 182 s.cfg = cfgv2.New() 183 s.mustNotExist = true 184 Expect(s.Save()).To(Succeed()) 185 186 cfgBytes, err := afero.ReadFile(s.fs, DefaultPath) 187 Expect(err).NotTo(HaveOccurred()) 188 Expect(string(cfgBytes)).To(Equal(commentStr + v2File)) 189 }) 190 191 It("should fail for an empty config", func() { 192 err := s.Save() 193 Expect(err).To(HaveOccurred()) 194 Expect(errors.As(err, &store.SaveError{})).To(BeTrue()) 195 }) 196 197 It("should fail for a pre-existent file that must not exist", func() { 198 s.cfg = cfgv2.New() 199 s.mustNotExist = true 200 Expect(afero.WriteFile(s.fs, DefaultPath, []byte(v2File), os.ModePerm)).To(Succeed()) 201 202 err := s.Save() 203 Expect(err).To(HaveOccurred()) 204 Expect(errors.As(err, &store.SaveError{})).To(BeTrue()) 205 }) 206 }) 207 208 Context("SaveTo", func() { 209 It("should success for valid configs", func() { 210 s.cfg = cfgv2.New() 211 Expect(s.SaveTo(path)).To(Succeed()) 212 213 cfgBytes, err := afero.ReadFile(s.fs, path) 214 Expect(err).NotTo(HaveOccurred()) 215 Expect(string(cfgBytes)).To(Equal(commentStr + v2File)) 216 }) 217 218 It("should succeed for a valid config that must not exist", func() { 219 s.cfg = cfgv2.New() 220 s.mustNotExist = true 221 Expect(s.SaveTo(path)).To(Succeed()) 222 223 cfgBytes, err := afero.ReadFile(s.fs, path) 224 Expect(err).NotTo(HaveOccurred()) 225 Expect(string(cfgBytes)).To(Equal(commentStr + v2File)) 226 }) 227 228 It("should fail for an empty config", func() { 229 err := s.SaveTo(path) 230 Expect(err).To(HaveOccurred()) 231 Expect(errors.As(err, &store.SaveError{})).To(BeTrue()) 232 }) 233 234 It("should fail for a pre-existent file that must not exist", func() { 235 s.cfg = cfgv2.New() 236 s.mustNotExist = true 237 Expect(afero.WriteFile(s.fs, path, []byte(v2File), os.ModePerm)).To(Succeed()) 238 239 err := s.SaveTo(path) 240 Expect(err).To(HaveOccurred()) 241 Expect(errors.As(err, &store.SaveError{})).To(BeTrue()) 242 }) 243 }) 244 })