github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/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  
    11  	"github.com/cloudfoundry/bosh-cli/director/template"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  )
    15  
    16  var _ = Describe("ManifestParser", func() {
    17  	var parser ManifestParser
    18  
    19  	Describe("InterpolateAndParse", func() {
    20  		var (
    21  			pathToManifest   string
    22  			pathsToVarsFiles []string
    23  			vars             []template.VarKV
    24  
    25  			executeErr     error
    26  			parsedManifest Manifest
    27  
    28  			rawManifest []byte
    29  		)
    30  
    31  		BeforeEach(func() {
    32  			tempFile, err := ioutil.TempFile("", "manifest-test-")
    33  			Expect(err).ToNot(HaveOccurred())
    34  			Expect(tempFile.Close()).ToNot(HaveOccurred())
    35  			pathToManifest = tempFile.Name()
    36  			vars = nil
    37  
    38  			pathsToVarsFiles = nil
    39  		})
    40  
    41  		AfterEach(func() {
    42  			Expect(os.RemoveAll(pathToManifest)).ToNot(HaveOccurred())
    43  			for _, path := range pathsToVarsFiles {
    44  				Expect(os.RemoveAll(path)).ToNot(HaveOccurred())
    45  			}
    46  		})
    47  
    48  		JustBeforeEach(func() {
    49  			parsedManifest, executeErr = parser.InterpolateAndParse(pathToManifest, pathsToVarsFiles, vars)
    50  		})
    51  
    52  		When("the manifest does *not* need interpolation", func() {
    53  			BeforeEach(func() {
    54  				rawManifest = []byte(`---
    55  applications:
    56  - name: spark
    57  - name: flame
    58  `)
    59  				err := ioutil.WriteFile(pathToManifest, rawManifest, 0666)
    60  				Expect(err).ToNot(HaveOccurred())
    61  			})
    62  
    63  			It("parses the manifest properly", func() {
    64  				Expect(executeErr).ToNot(HaveOccurred())
    65  
    66  				Expect(parsedManifest).To(Equal(Manifest{
    67  					PathToManifest: pathToManifest,
    68  					Applications: []Application{
    69  						{Name: "spark", RemainingManifestFields: map[string]interface{}{}},
    70  						{Name: "flame", RemainingManifestFields: map[string]interface{}{}},
    71  					},
    72  				}))
    73  			})
    74  		})
    75  
    76  		When("the manifest contains variables that need interpolation", func() {
    77  			BeforeEach(func() {
    78  				rawManifest = []byte(`---
    79  applications:
    80  - name: ((var1))
    81  - name: ((var2))
    82  `)
    83  				err := ioutil.WriteFile(pathToManifest, rawManifest, 0666)
    84  				Expect(err).ToNot(HaveOccurred())
    85  			})
    86  
    87  			When("only vars files are provided", func() {
    88  				var (
    89  					varsDir string
    90  				)
    91  
    92  				BeforeEach(func() {
    93  					var err error
    94  					varsDir, err = ioutil.TempDir("", "vars-test")
    95  					Expect(err).ToNot(HaveOccurred())
    96  
    97  					varsFilePath1 := filepath.Join(varsDir, "vars-1")
    98  					err = ioutil.WriteFile(varsFilePath1, []byte("var1: spark"), 0666)
    99  					Expect(err).ToNot(HaveOccurred())
   100  
   101  					varsFilePath2 := filepath.Join(varsDir, "vars-2")
   102  					err = ioutil.WriteFile(varsFilePath2, []byte("var2: flame"), 0666)
   103  					Expect(err).ToNot(HaveOccurred())
   104  
   105  					pathsToVarsFiles = append(pathsToVarsFiles, varsFilePath1, varsFilePath2)
   106  				})
   107  
   108  				AfterEach(func() {
   109  					Expect(os.RemoveAll(varsDir)).ToNot(HaveOccurred())
   110  				})
   111  
   112  				When("multiple values for the same variable(s) are provided", func() {
   113  					BeforeEach(func() {
   114  						varsFilePath1 := filepath.Join(varsDir, "vars-1")
   115  						err := ioutil.WriteFile(varsFilePath1, []byte("var1: garbageapp\nvar1: spark\nvar2: doesn't matter"), 0666)
   116  						Expect(err).ToNot(HaveOccurred())
   117  
   118  						varsFilePath2 := filepath.Join(varsDir, "vars-2")
   119  						err = ioutil.WriteFile(varsFilePath2, []byte("var2: flame"), 0666)
   120  						Expect(err).ToNot(HaveOccurred())
   121  
   122  						pathsToVarsFiles = append(pathsToVarsFiles, varsFilePath1, varsFilePath2)
   123  					})
   124  
   125  					It("interpolates the placeholder values", func() {
   126  						Expect(executeErr).ToNot(HaveOccurred())
   127  						Expect(parsedManifest.AppNames()).To(ConsistOf("spark", "flame"))
   128  					})
   129  				})
   130  
   131  				When("the provided files exists and contain valid yaml", func() {
   132  					It("interpolates the placeholder values", func() {
   133  						Expect(executeErr).ToNot(HaveOccurred())
   134  						Expect(parsedManifest.AppNames()).To(ConsistOf("spark", "flame"))
   135  					})
   136  				})
   137  
   138  				When("a variable in the manifest is not provided in the vars file", func() {
   139  					BeforeEach(func() {
   140  						varsFilePath := filepath.Join(varsDir, "vars-1")
   141  						err := ioutil.WriteFile(varsFilePath, []byte("notvar: foo"), 0666)
   142  						Expect(err).ToNot(HaveOccurred())
   143  
   144  						pathsToVarsFiles = []string{varsFilePath}
   145  					})
   146  
   147  					It("returns an error", func() {
   148  						Expect(executeErr.Error()).To(Equal("Expected to find variables: var1, var2"))
   149  					})
   150  				})
   151  
   152  				When("the provided file path does not exist", func() {
   153  					BeforeEach(func() {
   154  						pathsToVarsFiles = []string{"garbagepath"}
   155  					})
   156  
   157  					It("returns an error", func() {
   158  						Expect(executeErr).To(HaveOccurred())
   159  						Expect(os.IsNotExist(executeErr)).To(BeTrue())
   160  					})
   161  				})
   162  
   163  				When("the provided file is not a valid yaml file", func() {
   164  					BeforeEach(func() {
   165  						varsFilePath := filepath.Join(varsDir, "vars-1")
   166  						err := ioutil.WriteFile(varsFilePath, []byte(": bad"), 0666)
   167  						Expect(err).ToNot(HaveOccurred())
   168  
   169  						pathsToVarsFiles = []string{varsFilePath}
   170  					})
   171  
   172  					It("returns an error", func() {
   173  						Expect(executeErr).To(HaveOccurred())
   174  						Expect(executeErr).To(MatchError(InvalidYAMLError{
   175  							Err: errors.New("yaml: did not find expected key"),
   176  						}))
   177  					})
   178  				})
   179  			})
   180  
   181  			When("only vars are provided", func() {
   182  				BeforeEach(func() {
   183  					vars = []template.VarKV{
   184  						{Name: "var1", Value: "spark"},
   185  						{Name: "var2", Value: "flame"},
   186  					}
   187  				})
   188  
   189  				It("interpolates the placeholder values", func() {
   190  					Expect(executeErr).ToNot(HaveOccurred())
   191  					Expect(parsedManifest.AppNames()).To(ConsistOf("spark", "flame"))
   192  				})
   193  			})
   194  
   195  			When("vars and vars files are provided", func() {
   196  				var varsFilePath string
   197  				BeforeEach(func() {
   198  					tmp, err := ioutil.TempFile("", "util-manifest-varsilfe")
   199  					Expect(err).NotTo(HaveOccurred())
   200  					Expect(tmp.Close()).NotTo(HaveOccurred())
   201  
   202  					varsFilePath = tmp.Name()
   203  					err = ioutil.WriteFile(varsFilePath, []byte("var1: spark\nvar2: 12345"), 0666)
   204  					Expect(err).ToNot(HaveOccurred())
   205  
   206  					pathsToVarsFiles = []string{varsFilePath}
   207  					vars = []template.VarKV{
   208  						{Name: "var2", Value: "flame"},
   209  					}
   210  				})
   211  
   212  				AfterEach(func() {
   213  					Expect(os.RemoveAll(varsFilePath)).ToNot(HaveOccurred())
   214  				})
   215  
   216  				It("interpolates the placeholder values, prioritizing the vars flag", func() {
   217  					Expect(executeErr).ToNot(HaveOccurred())
   218  					Expect(parsedManifest.AppNames()).To(ConsistOf("spark", "flame"))
   219  				})
   220  			})
   221  		})
   222  
   223  		When("invalid yaml is passed", func() {
   224  			BeforeEach(func() {
   225  				rawManifest = []byte("\t\t")
   226  				err := ioutil.WriteFile(pathToManifest, rawManifest, 0666)
   227  				Expect(err).ToNot(HaveOccurred())
   228  			})
   229  
   230  			It("parses the manifest properly", func() {
   231  				Expect(executeErr).To(HaveOccurred())
   232  			})
   233  		})
   234  	})
   235  
   236  	Describe("MarshalManifest", func() {
   237  		It("marshals the manifest", func() {
   238  			manifest := Manifest{
   239  				Applications: []Application{
   240  					{
   241  						Name: "app-1",
   242  						Processes: []Process{
   243  							{
   244  								Type:                    "web",
   245  								RemainingManifestFields: map[string]interface{}{"unknown-process-key": 2},
   246  							},
   247  						},
   248  						RemainingManifestFields: map[string]interface{}{"unknown-key": 1},
   249  					},
   250  				},
   251  			}
   252  
   253  			yaml, err := parser.MarshalManifest(manifest)
   254  
   255  			Expect(err).NotTo(HaveOccurred())
   256  			Expect(yaml).To(MatchYAML(`applications:
   257  - name: app-1
   258    unknown-key: 1
   259    processes:
   260    - type: web
   261      unknown-process-key: 2
   262  `))
   263  		})
   264  	})
   265  })