code.cloudfoundry.org/cli@v7.1.0+incompatible/cf/manifest/generate_manifest_test.go (about)

     1  package manifest_test
     2  
     3  import (
     4  	"gopkg.in/yaml.v2"
     5  
     6  	"bytes"
     7  
     8  	. "code.cloudfoundry.org/cli/cf/manifest"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  )
    12  
    13  var _ = Describe("generate_manifest", func() {
    14  	Describe("Save", func() {
    15  		var (
    16  			m App
    17  			f *bytes.Buffer
    18  		)
    19  
    20  		BeforeEach(func() {
    21  			m = NewGenerator()
    22  			f = &bytes.Buffer{}
    23  		})
    24  
    25  		Context("when each application in the manifest has all required attributes, and the save path has been set", func() {
    26  			BeforeEach(func() {
    27  				m.Stack("app1", "stack-name")
    28  				m.Memory("app1", 1024)
    29  				m.Instances("app1", 2)
    30  				m.DiskQuota("app1", 1024)
    31  			})
    32  
    33  			It("creates a top-level applications key", func() {
    34  				err := m.Save(f)
    35  				Expect(err).NotTo(HaveOccurred())
    36  				ymanifest := getYaml(f)
    37  				Expect(ymanifest.Applications).To(HaveLen(1))
    38  			})
    39  
    40  			It("includes required attributes", func() {
    41  				err := m.Save(f)
    42  				Expect(err).NotTo(HaveOccurred())
    43  				applications := getYaml(f).Applications
    44  
    45  				Expect(applications[0].Name).To(Equal("app1"))
    46  				Expect(applications[0].Memory).To(Equal("1024M"))
    47  				Expect(applications[0].DiskQuota).To(Equal("1024M"))
    48  				Expect(applications[0].Stack).To(Equal("stack-name"))
    49  				Expect(applications[0].Instances).To(Equal(2))
    50  			})
    51  
    52  			It("creates entries under the given app name", func() {
    53  				m.Stack("app2", "stack-name")
    54  				m.Memory("app2", 2048)
    55  				m.Instances("app2", 3)
    56  				m.DiskQuota("app2", 2048)
    57  				m.HealthCheckType("app2", "some-health-check-type")
    58  				m.HealthCheckHTTPEndpoint("app2", "/some-endpoint")
    59  				m.Save(f)
    60  
    61  				applications := getYaml(f).Applications
    62  
    63  				Expect(applications[1].Name).To(Equal("app2"))
    64  				Expect(applications[1].Memory).To(Equal("2048M"))
    65  				Expect(applications[1].DiskQuota).To(Equal("2048M"))
    66  				Expect(applications[1].Stack).To(Equal("stack-name"))
    67  				Expect(applications[1].Instances).To(Equal(3))
    68  				Expect(applications[1].HealthCheckType).To(Equal("some-health-check-type"))
    69  				Expect(applications[1].HealthCheckHTTPEndpoint).To(Equal("/some-endpoint"))
    70  			})
    71  
    72  			Context("when an application has services", func() {
    73  				BeforeEach(func() {
    74  					m.Service("app1", "service1")
    75  					m.Service("app1", "service2")
    76  					m.Service("app1", "service3")
    77  				})
    78  
    79  				It("includes services for that app", func() {
    80  					err := m.Save(f)
    81  					Expect(err).NotTo(HaveOccurred())
    82  					contents := getYaml(f)
    83  					application := contents.Applications[0]
    84  					Expect(application.Services).To(ContainElement("service1"))
    85  					Expect(application.Services).To(ContainElement("service2"))
    86  					Expect(application.Services).To(ContainElement("service3"))
    87  				})
    88  			})
    89  
    90  			Context("when an application has a buildpack", func() {
    91  				BeforeEach(func() {
    92  					m.BuildpackURL("app1", "buildpack")
    93  				})
    94  
    95  				It("includes the buildpack url for that app", func() {
    96  					m.Save(f)
    97  					contents := getYaml(f)
    98  					application := contents.Applications[0]
    99  					Expect(application.Buildpack).To(Equal("buildpack"))
   100  				})
   101  			})
   102  
   103  			Context("when an application has a non-zero health check timeout", func() {
   104  				BeforeEach(func() {
   105  					m.HealthCheckTimeout("app1", 5)
   106  				})
   107  
   108  				It("includes the healthcheck timeout for that app", func() {
   109  					err := m.Save(f)
   110  					Expect(err).NotTo(HaveOccurred())
   111  					contents := getYaml(f)
   112  					application := contents.Applications[0]
   113  					Expect(application.Timeout).To(Equal(5))
   114  				})
   115  			})
   116  
   117  			Context("when an application has a start command", func() {
   118  				BeforeEach(func() {
   119  					m.StartCommand("app1", "start-command")
   120  				})
   121  
   122  				It("includes the start command for that app", func() {
   123  					m.Save(f)
   124  					contents := getYaml(f)
   125  					application := contents.Applications[0]
   126  					Expect(application.Command).To(Equal("start-command"))
   127  				})
   128  			})
   129  
   130  			It("includes no-route when the application has no routes", func() {
   131  				m.Save(f)
   132  				contents := getYaml(f)
   133  				application := contents.Applications[0]
   134  				Expect(application.NoRoute).To(BeTrue())
   135  			})
   136  
   137  			Context("when an application has one route with both hostname, domain path", func() {
   138  				BeforeEach(func() {
   139  					m.Route("app1", "host-name", "domain-name", "/path", 0)
   140  				})
   141  
   142  				It("includes the route", func() {
   143  					err := m.Save(f)
   144  					Expect(err).NotTo(HaveOccurred())
   145  					contents := getYaml(f)
   146  					application := contents.Applications[0]
   147  					Expect(application.Routes[0]["route"]).To(Equal("host-name.domain-name/path"))
   148  				})
   149  
   150  			})
   151  
   152  			Context("when an application has one route without a hostname", func() {
   153  				BeforeEach(func() {
   154  					m.Route("app1", "", "domain-name", "", 0)
   155  				})
   156  
   157  				It("includes the domain", func() {
   158  					err := m.Save(f)
   159  					Expect(err).NotTo(HaveOccurred())
   160  					contents := getYaml(f)
   161  					application := contents.Applications[0]
   162  					Expect(application.Routes[0]["route"]).To(Equal("domain-name"))
   163  				})
   164  
   165  			})
   166  
   167  			Context("when an application has one tcp route", func() {
   168  				BeforeEach(func() {
   169  					m.Route("app1", "", "domain-name", "", 123)
   170  				})
   171  
   172  				It("includes the route", func() {
   173  					err := m.Save(f)
   174  					Expect(err).NotTo(HaveOccurred())
   175  					contents := getYaml(f)
   176  					application := contents.Applications[0]
   177  					Expect(application.Routes[0]["route"]).To(Equal("domain-name:123"))
   178  				})
   179  
   180  			})
   181  
   182  			Context("when an application has multiple routes", func() {
   183  				BeforeEach(func() {
   184  					m.Route("app1", "", "http-domain", "", 0)
   185  					m.Route("app1", "host", "http-domain", "", 0)
   186  					m.Route("app1", "host", "http-domain", "/path", 0)
   187  					m.Route("app1", "", "tcp-domain", "", 123)
   188  				})
   189  
   190  				It("includes the route", func() {
   191  					err := m.Save(f)
   192  					Expect(err).NotTo(HaveOccurred())
   193  					contents := getYaml(f)
   194  					application := contents.Applications[0]
   195  					Expect(application.Routes[0]["route"]).To(Equal("http-domain"))
   196  					Expect(application.Routes[1]["route"]).To(Equal("host.http-domain"))
   197  					Expect(application.Routes[2]["route"]).To(Equal("host.http-domain/path"))
   198  					Expect(application.Routes[3]["route"]).To(Equal("tcp-domain:123"))
   199  				})
   200  
   201  			})
   202  
   203  			Context("when multiple applications have multiple routes", func() {
   204  				BeforeEach(func() {
   205  					m.Stack("app2", "stack-name")
   206  					m.Memory("app2", 1024)
   207  					m.Instances("app2", 2)
   208  					m.DiskQuota("app2", 1024)
   209  
   210  					m.Route("app1", "", "http-domain", "", 0)
   211  					m.Route("app1", "host", "http-domain", "", 0)
   212  					m.Route("app1", "host", "http-domain", "/path", 0)
   213  					m.Route("app1", "", "tcp-domain", "", 123)
   214  					m.Route("app2", "", "http-domain", "", 0)
   215  					m.Route("app2", "host", "http-domain", "", 0)
   216  					m.Route("app2", "host", "http-domain", "/path", 0)
   217  					m.Route("app2", "", "tcp-domain", "", 123)
   218  				})
   219  
   220  				It("includes the route", func() {
   221  					err := m.Save(f)
   222  					Expect(err).NotTo(HaveOccurred())
   223  					contents := getYaml(f)
   224  					application := contents.Applications[0]
   225  					Expect(application.Routes[0]["route"]).To(Equal("http-domain"))
   226  					Expect(application.Routes[1]["route"]).To(Equal("host.http-domain"))
   227  					Expect(application.Routes[2]["route"]).To(Equal("host.http-domain/path"))
   228  					Expect(application.Routes[3]["route"]).To(Equal("tcp-domain:123"))
   229  
   230  					application = contents.Applications[1]
   231  					Expect(application.Routes[0]["route"]).To(Equal("http-domain"))
   232  					Expect(application.Routes[1]["route"]).To(Equal("host.http-domain"))
   233  					Expect(application.Routes[2]["route"]).To(Equal("host.http-domain/path"))
   234  					Expect(application.Routes[3]["route"]).To(Equal("tcp-domain:123"))
   235  				})
   236  
   237  			})
   238  			Context("when the application contains environment vars", func() {
   239  				BeforeEach(func() {
   240  					m.EnvironmentVars("app1", "foo", "foo-value")
   241  					m.EnvironmentVars("app1", "bar", "bar-value")
   242  				})
   243  
   244  				It("stores each environment var", func() {
   245  					err := m.Save(f)
   246  					Expect(err).NotTo(HaveOccurred())
   247  					application := getYaml(f).Applications[0]
   248  
   249  					Expect(application.Env).To(Equal(map[string]interface{}{
   250  						"foo": "foo-value",
   251  						"bar": "bar-value",
   252  					}))
   253  				})
   254  			})
   255  		})
   256  
   257  		It("returns an error when stack has not been set", func() {
   258  			m.Memory("app1", 1024)
   259  			m.Instances("app1", 2)
   260  			m.DiskQuota("app1", 1024)
   261  
   262  			err := m.Save(f)
   263  			Expect(err).To(HaveOccurred())
   264  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'stack' missing"))
   265  		})
   266  
   267  		It("returns an error when memory has not been set", func() {
   268  			m.Instances("app1", 2)
   269  			m.DiskQuota("app1", 1024)
   270  			m.Stack("app1", "stack")
   271  
   272  			err := m.Save(f)
   273  			Expect(err).To(HaveOccurred())
   274  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'memory' missing"))
   275  		})
   276  
   277  		It("returns an error when disk quota has not been set", func() {
   278  			m.Instances("app1", 2)
   279  			m.Memory("app1", 1024)
   280  			m.Stack("app1", "stack")
   281  
   282  			err := m.Save(f)
   283  			Expect(err).To(HaveOccurred())
   284  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'disk_quota' missing"))
   285  		})
   286  
   287  		It("returns an error when instances have not been set", func() {
   288  			m.DiskQuota("app1", 1024)
   289  			m.Memory("app1", 1024)
   290  			m.Stack("app1", "stack")
   291  
   292  			err := m.Save(f)
   293  			Expect(err).To(HaveOccurred())
   294  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'instances' missing"))
   295  		})
   296  	})
   297  })
   298  
   299  type YManifest struct {
   300  	Applications []YApplication `yaml:"applications"`
   301  }
   302  
   303  type YApplication struct {
   304  	Name                    string                 `yaml:"name"`
   305  	Services                []string               `yaml:"services"`
   306  	Buildpack               string                 `yaml:"buildpack"`
   307  	Memory                  string                 `yaml:"memory"`
   308  	Command                 string                 `yaml:"command"`
   309  	Env                     map[string]interface{} `yaml:"env"`
   310  	Timeout                 int                    `yaml:"timeout"`
   311  	Instances               int                    `yaml:"instances"`
   312  	Routes                  []map[string]string    `yaml:"routes"`
   313  	NoRoute                 bool                   `yaml:"no-route"`
   314  	DiskQuota               string                 `yaml:"disk_quota"`
   315  	Stack                   string                 `yaml:"stack"`
   316  	HealthCheckType         string                 `yaml:"health-check-type"`
   317  	HealthCheckHTTPEndpoint string                 `yaml:"health-check-http-endpoint"`
   318  }
   319  
   320  func getYaml(f *bytes.Buffer) YManifest {
   321  	var document YManifest
   322  
   323  	err := yaml.Unmarshal([]byte(f.String()), &document)
   324  	Expect(err).NotTo(HaveOccurred())
   325  
   326  	return document
   327  }