github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/util/manifestparser/parser_test.go (about) 1 package manifestparser_test 2 3 import ( 4 "errors" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 9 . "code.cloudfoundry.org/cli/util/manifestparser" 10 "github.com/cloudfoundry/bosh-cli/director/template" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 "gopkg.in/yaml.v2" 14 ) 15 16 var _ = Describe("ManifestParser", func() { 17 var parser ManifestParser 18 19 Describe("InterpolateManifest", func() { 20 var ( 21 givenManifest []byte 22 pathToManifest string 23 pathsToVarsFiles []string 24 vars []template.VarKV 25 26 interpolatedManifest []byte 27 executeErr error 28 ) 29 30 BeforeEach(func() { 31 tempFile, err := ioutil.TempFile("", "manifest-test-") 32 Expect(err).ToNot(HaveOccurred()) 33 Expect(tempFile.Close()).ToNot(HaveOccurred()) 34 pathToManifest = tempFile.Name() 35 vars = nil 36 37 pathsToVarsFiles = nil 38 }) 39 40 AfterEach(func() { 41 Expect(os.RemoveAll(pathToManifest)).ToNot(HaveOccurred()) 42 for _, path := range pathsToVarsFiles { 43 Expect(os.RemoveAll(path)).ToNot(HaveOccurred()) 44 } 45 }) 46 47 JustBeforeEach(func() { 48 interpolatedManifest, executeErr = parser.InterpolateManifest(pathToManifest, pathsToVarsFiles, vars) 49 }) 50 51 When("the manifest does *not* need interpolation", func() { 52 BeforeEach(func() { 53 givenManifest = []byte(`--- 54 applications: 55 - name: spark 56 - name: flame 57 `) 58 err := ioutil.WriteFile(pathToManifest, givenManifest, 0666) 59 Expect(err).ToNot(HaveOccurred()) 60 }) 61 62 It("parses the manifest properly", func() { 63 Expect(executeErr).ToNot(HaveOccurred()) 64 65 Expect(string(interpolatedManifest)).To(Equal(`applications: 66 - name: spark 67 - name: flame 68 `)) 69 }) 70 }) 71 72 When("the manifest contains variables that need interpolation", func() { 73 BeforeEach(func() { 74 givenManifest = []byte(`--- 75 applications: 76 - name: ((var1)) 77 - name: ((var2)) 78 `) 79 err := ioutil.WriteFile(pathToManifest, givenManifest, 0666) 80 Expect(err).ToNot(HaveOccurred()) 81 }) 82 83 When("only vars files are provided", func() { 84 var ( 85 varsDir string 86 ) 87 88 BeforeEach(func() { 89 var err error 90 varsDir, err = ioutil.TempDir("", "vars-test") 91 Expect(err).ToNot(HaveOccurred()) 92 93 varsFilePath1 := filepath.Join(varsDir, "vars-1") 94 err = ioutil.WriteFile(varsFilePath1, []byte("var1: spark"), 0666) 95 Expect(err).ToNot(HaveOccurred()) 96 97 varsFilePath2 := filepath.Join(varsDir, "vars-2") 98 err = ioutil.WriteFile(varsFilePath2, []byte("var2: flame"), 0666) 99 Expect(err).ToNot(HaveOccurred()) 100 101 pathsToVarsFiles = append(pathsToVarsFiles, varsFilePath1, varsFilePath2) 102 }) 103 104 AfterEach(func() { 105 Expect(os.RemoveAll(varsDir)).ToNot(HaveOccurred()) 106 }) 107 108 When("multiple values for the same variable(s) are provided", func() { 109 BeforeEach(func() { 110 varsFilePath1 := filepath.Join(varsDir, "vars-1") 111 err := ioutil.WriteFile(varsFilePath1, []byte("var1: garbageapp\nvar1: spark\nvar2: doesn't matter"), 0666) 112 Expect(err).ToNot(HaveOccurred()) 113 114 varsFilePath2 := filepath.Join(varsDir, "vars-2") 115 err = ioutil.WriteFile(varsFilePath2, []byte("var2: flame"), 0666) 116 Expect(err).ToNot(HaveOccurred()) 117 118 pathsToVarsFiles = append(pathsToVarsFiles, varsFilePath1, varsFilePath2) 119 }) 120 121 It("interpolates the placeholder values", func() { 122 Expect(executeErr).ToNot(HaveOccurred()) 123 Expect(string(interpolatedManifest)).To(Equal(`applications: 124 - name: spark 125 - name: flame 126 `)) 127 }) 128 }) 129 130 When("the provided files exists and contain valid yaml", func() { 131 It("interpolates the placeholder values", func() { 132 Expect(executeErr).ToNot(HaveOccurred()) 133 Expect(string(interpolatedManifest)).To(Equal(`applications: 134 - name: spark 135 - name: flame 136 `)) 137 }) 138 }) 139 140 When("a variable in the manifest is not provided in the vars file", func() { 141 BeforeEach(func() { 142 varsFilePath := filepath.Join(varsDir, "vars-1") 143 err := ioutil.WriteFile(varsFilePath, []byte("notvar: foo"), 0666) 144 Expect(err).ToNot(HaveOccurred()) 145 146 pathsToVarsFiles = []string{varsFilePath} 147 }) 148 149 It("returns an error", func() { 150 Expect(executeErr.Error()).To(Equal("Expected to find variables: var1, var2")) 151 }) 152 }) 153 154 When("the provided file path does not exist", func() { 155 BeforeEach(func() { 156 pathsToVarsFiles = []string{"garbagepath"} 157 }) 158 159 It("returns an error", func() { 160 Expect(executeErr).To(HaveOccurred()) 161 Expect(os.IsNotExist(executeErr)).To(BeTrue()) 162 }) 163 }) 164 165 When("the provided file is not a valid yaml file", func() { 166 BeforeEach(func() { 167 varsFilePath := filepath.Join(varsDir, "vars-1") 168 err := ioutil.WriteFile(varsFilePath, []byte(": bad"), 0666) 169 Expect(err).ToNot(HaveOccurred()) 170 171 pathsToVarsFiles = []string{varsFilePath} 172 }) 173 174 It("returns an error", func() { 175 Expect(executeErr).To(HaveOccurred()) 176 Expect(executeErr).To(MatchError(InvalidYAMLError{ 177 Err: errors.New("yaml: did not find expected key"), 178 })) 179 }) 180 }) 181 }) 182 183 When("only vars are provided", func() { 184 BeforeEach(func() { 185 vars = []template.VarKV{ 186 {Name: "var1", Value: "spark"}, 187 {Name: "var2", Value: "flame"}, 188 } 189 }) 190 191 It("interpolates the placeholder values", func() { 192 Expect(executeErr).ToNot(HaveOccurred()) 193 Expect(string(interpolatedManifest)).To(Equal(`applications: 194 - name: spark 195 - name: flame 196 `)) 197 }) 198 }) 199 200 When("vars and vars files are provided", func() { 201 var varsFilePath string 202 BeforeEach(func() { 203 tmp, err := ioutil.TempFile("", "util-manifest-varsilfe") 204 Expect(err).NotTo(HaveOccurred()) 205 Expect(tmp.Close()).NotTo(HaveOccurred()) 206 207 varsFilePath = tmp.Name() 208 err = ioutil.WriteFile(varsFilePath, []byte("var1: spark\nvar2: 12345"), 0666) 209 Expect(err).ToNot(HaveOccurred()) 210 211 pathsToVarsFiles = []string{varsFilePath} 212 vars = []template.VarKV{ 213 {Name: "var2", Value: "flame"}, 214 } 215 }) 216 217 AfterEach(func() { 218 Expect(os.RemoveAll(varsFilePath)).ToNot(HaveOccurred()) 219 }) 220 221 It("interpolates the placeholder values, prioritizing the vars flag", func() { 222 Expect(executeErr).ToNot(HaveOccurred()) 223 Expect(string(interpolatedManifest)).To(Equal(`applications: 224 - name: spark 225 - name: flame 226 `)) 227 }) 228 }) 229 }) 230 }) 231 232 Describe("ParseManifest", func() { 233 var ( 234 pathToManifest string 235 rawManifest []byte 236 237 executeErr error 238 parsedManifest Manifest 239 ) 240 241 BeforeEach(func() { 242 pathToManifest = "/some/path/to/manifest.yml" 243 rawManifest = nil 244 }) 245 246 JustBeforeEach(func() { 247 parsedManifest, executeErr = parser.ParseManifest(pathToManifest, rawManifest) 248 }) 249 250 When("the manifest does not contain applications", func() { 251 BeforeEach(func() { 252 rawManifest = []byte(`applications: 253 `) 254 }) 255 256 It("returns an error", func() { 257 Expect(executeErr).To(HaveOccurred()) 258 Expect(executeErr).To(MatchError(errors.New("Manifest must have at least one application."))) 259 }) 260 }) 261 262 When("invalid yaml is passed", func() { 263 BeforeEach(func() { 264 rawManifest = []byte("\t\t") 265 }) 266 267 It("returns an error", func() { 268 Expect(executeErr).To(HaveOccurred()) 269 }) 270 }) 271 272 When("unmarshalling returns an error", func() { 273 BeforeEach(func() { 274 rawManifest = []byte(`--- 275 blah blah 276 `) 277 }) 278 279 It("returns an error", func() { 280 Expect(executeErr).To(HaveOccurred()) 281 Expect(executeErr).To(MatchError(&yaml.TypeError{})) 282 }) 283 }) 284 285 When("the manifest is valid", func() { 286 BeforeEach(func() { 287 rawManifest = []byte(`applications: 288 - name: one 289 - name: two 290 `) 291 }) 292 293 It("interpolates the placeholder values", func() { 294 Expect(executeErr).ToNot(HaveOccurred()) 295 Expect(parsedManifest.AppNames()).To(ConsistOf("one", "two")) 296 }) 297 }) 298 }) 299 300 Describe("MarshalManifest", func() { 301 It("marshals the manifest", func() { 302 manifest := Manifest{ 303 Applications: []Application{ 304 { 305 Name: "app-1", 306 Processes: []Process{ 307 { 308 Type: "web", 309 RemainingManifestFields: map[string]interface{}{"unknown-process-key": 2}, 310 }, 311 }, 312 RemainingManifestFields: map[string]interface{}{"unknown-key": 1}, 313 }, 314 }, 315 } 316 317 yaml, err := parser.MarshalManifest(manifest) 318 319 Expect(err).NotTo(HaveOccurred()) 320 Expect(yaml).To(MatchYAML(`applications: 321 - name: app-1 322 unknown-key: 1 323 processes: 324 - type: web 325 unknown-process-key: 2 326 `)) 327 }) 328 }) 329 })