github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+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 app-ports", func() {
    73  				BeforeEach(func() {
    74  					m.AppPorts("app1", []int{1111, 2222})
    75  				})
    76  
    77  				It("includes app-ports for that app", func() {
    78  					err := m.Save(f)
    79  					Expect(err).NotTo(HaveOccurred())
    80  					applications := getYaml(f).Applications
    81  
    82  					Expect(applications[0].AppPorts).To(Equal([]int{1111, 2222}))
    83  				})
    84  			})
    85  
    86  			Context("when an application has services", func() {
    87  				BeforeEach(func() {
    88  					m.Service("app1", "service1")
    89  					m.Service("app1", "service2")
    90  					m.Service("app1", "service3")
    91  				})
    92  
    93  				It("includes services for that app", func() {
    94  					err := m.Save(f)
    95  					Expect(err).NotTo(HaveOccurred())
    96  					contents := getYaml(f)
    97  					application := contents.Applications[0]
    98  					Expect(application.Services).To(ContainElement("service1"))
    99  					Expect(application.Services).To(ContainElement("service2"))
   100  					Expect(application.Services).To(ContainElement("service3"))
   101  				})
   102  			})
   103  
   104  			Context("when an application has a buildpack", func() {
   105  				BeforeEach(func() {
   106  					m.BuildpackURL("app1", "buildpack")
   107  				})
   108  
   109  				It("includes the buildpack url for that app", func() {
   110  					m.Save(f)
   111  					contents := getYaml(f)
   112  					application := contents.Applications[0]
   113  					Expect(application.Buildpack).To(Equal("buildpack"))
   114  				})
   115  			})
   116  
   117  			Context("when an application has a non-zero health check timeout", func() {
   118  				BeforeEach(func() {
   119  					m.HealthCheckTimeout("app1", 5)
   120  				})
   121  
   122  				It("includes the healthcheck timeout for that app", func() {
   123  					err := m.Save(f)
   124  					Expect(err).NotTo(HaveOccurred())
   125  					contents := getYaml(f)
   126  					application := contents.Applications[0]
   127  					Expect(application.Timeout).To(Equal(5))
   128  				})
   129  			})
   130  
   131  			Context("when an application has a start command", func() {
   132  				BeforeEach(func() {
   133  					m.StartCommand("app1", "start-command")
   134  				})
   135  
   136  				It("includes the start command for that app", func() {
   137  					m.Save(f)
   138  					contents := getYaml(f)
   139  					application := contents.Applications[0]
   140  					Expect(application.Command).To(Equal("start-command"))
   141  				})
   142  			})
   143  
   144  			It("includes no-route when the application has no routes", func() {
   145  				m.Save(f)
   146  				contents := getYaml(f)
   147  				application := contents.Applications[0]
   148  				Expect(application.NoRoute).To(BeTrue())
   149  			})
   150  
   151  			Context("when an application has one route with both hostname, domain path", func() {
   152  				BeforeEach(func() {
   153  					m.Route("app1", "host-name", "domain-name", "/path", 0)
   154  				})
   155  
   156  				It("includes the route", func() {
   157  					err := m.Save(f)
   158  					Expect(err).NotTo(HaveOccurred())
   159  					contents := getYaml(f)
   160  					application := contents.Applications[0]
   161  					Expect(application.Routes[0]["route"]).To(Equal("host-name.domain-name/path"))
   162  				})
   163  
   164  			})
   165  
   166  			Context("when an application has one route without a hostname", func() {
   167  				BeforeEach(func() {
   168  					m.Route("app1", "", "domain-name", "", 0)
   169  				})
   170  
   171  				It("includes the domain", func() {
   172  					err := m.Save(f)
   173  					Expect(err).NotTo(HaveOccurred())
   174  					contents := getYaml(f)
   175  					application := contents.Applications[0]
   176  					Expect(application.Routes[0]["route"]).To(Equal("domain-name"))
   177  				})
   178  
   179  			})
   180  
   181  			Context("when an application has one tcp route", func() {
   182  				BeforeEach(func() {
   183  					m.Route("app1", "", "domain-name", "", 123)
   184  				})
   185  
   186  				It("includes the route", func() {
   187  					err := m.Save(f)
   188  					Expect(err).NotTo(HaveOccurred())
   189  					contents := getYaml(f)
   190  					application := contents.Applications[0]
   191  					Expect(application.Routes[0]["route"]).To(Equal("domain-name:123"))
   192  				})
   193  
   194  			})
   195  
   196  			Context("when an application has multiple routes", func() {
   197  				BeforeEach(func() {
   198  					m.Route("app1", "", "http-domain", "", 0)
   199  					m.Route("app1", "host", "http-domain", "", 0)
   200  					m.Route("app1", "host", "http-domain", "/path", 0)
   201  					m.Route("app1", "", "tcp-domain", "", 123)
   202  				})
   203  
   204  				It("includes the route", func() {
   205  					err := m.Save(f)
   206  					Expect(err).NotTo(HaveOccurred())
   207  					contents := getYaml(f)
   208  					application := contents.Applications[0]
   209  					Expect(application.Routes[0]["route"]).To(Equal("http-domain"))
   210  					Expect(application.Routes[1]["route"]).To(Equal("host.http-domain"))
   211  					Expect(application.Routes[2]["route"]).To(Equal("host.http-domain/path"))
   212  					Expect(application.Routes[3]["route"]).To(Equal("tcp-domain:123"))
   213  				})
   214  
   215  			})
   216  
   217  			Context("when multiple applications have multiple routes", func() {
   218  				BeforeEach(func() {
   219  					m.Stack("app2", "stack-name")
   220  					m.Memory("app2", 1024)
   221  					m.Instances("app2", 2)
   222  					m.DiskQuota("app2", 1024)
   223  
   224  					m.Route("app1", "", "http-domain", "", 0)
   225  					m.Route("app1", "host", "http-domain", "", 0)
   226  					m.Route("app1", "host", "http-domain", "/path", 0)
   227  					m.Route("app1", "", "tcp-domain", "", 123)
   228  					m.Route("app2", "", "http-domain", "", 0)
   229  					m.Route("app2", "host", "http-domain", "", 0)
   230  					m.Route("app2", "host", "http-domain", "/path", 0)
   231  					m.Route("app2", "", "tcp-domain", "", 123)
   232  				})
   233  
   234  				It("includes the route", func() {
   235  					err := m.Save(f)
   236  					Expect(err).NotTo(HaveOccurred())
   237  					contents := getYaml(f)
   238  					application := contents.Applications[0]
   239  					Expect(application.Routes[0]["route"]).To(Equal("http-domain"))
   240  					Expect(application.Routes[1]["route"]).To(Equal("host.http-domain"))
   241  					Expect(application.Routes[2]["route"]).To(Equal("host.http-domain/path"))
   242  					Expect(application.Routes[3]["route"]).To(Equal("tcp-domain:123"))
   243  
   244  					application = contents.Applications[1]
   245  					Expect(application.Routes[0]["route"]).To(Equal("http-domain"))
   246  					Expect(application.Routes[1]["route"]).To(Equal("host.http-domain"))
   247  					Expect(application.Routes[2]["route"]).To(Equal("host.http-domain/path"))
   248  					Expect(application.Routes[3]["route"]).To(Equal("tcp-domain:123"))
   249  				})
   250  
   251  			})
   252  			Context("when the application contains environment vars", func() {
   253  				BeforeEach(func() {
   254  					m.EnvironmentVars("app1", "foo", "foo-value")
   255  					m.EnvironmentVars("app1", "bar", "bar-value")
   256  				})
   257  
   258  				It("stores each environment var", func() {
   259  					err := m.Save(f)
   260  					Expect(err).NotTo(HaveOccurred())
   261  					application := getYaml(f).Applications[0]
   262  
   263  					Expect(application.Env).To(Equal(map[string]interface{}{
   264  						"foo": "foo-value",
   265  						"bar": "bar-value",
   266  					}))
   267  				})
   268  			})
   269  		})
   270  
   271  		It("returns an error when stack has not been set", func() {
   272  			m.Memory("app1", 1024)
   273  			m.Instances("app1", 2)
   274  			m.DiskQuota("app1", 1024)
   275  
   276  			err := m.Save(f)
   277  			Expect(err).To(HaveOccurred())
   278  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'stack' missing"))
   279  		})
   280  
   281  		It("returns an error when memory has not been set", func() {
   282  			m.Instances("app1", 2)
   283  			m.DiskQuota("app1", 1024)
   284  			m.Stack("app1", "stack")
   285  
   286  			err := m.Save(f)
   287  			Expect(err).To(HaveOccurred())
   288  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'memory' missing"))
   289  		})
   290  
   291  		It("returns an error when disk quota has not been set", func() {
   292  			m.Instances("app1", 2)
   293  			m.Memory("app1", 1024)
   294  			m.Stack("app1", "stack")
   295  
   296  			err := m.Save(f)
   297  			Expect(err).To(HaveOccurred())
   298  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'disk_quota' missing"))
   299  		})
   300  
   301  		It("returns an error when instances have not been set", func() {
   302  			m.DiskQuota("app1", 1024)
   303  			m.Memory("app1", 1024)
   304  			m.Stack("app1", "stack")
   305  
   306  			err := m.Save(f)
   307  			Expect(err).To(HaveOccurred())
   308  			Expect(err.Error()).To(Equal("Error saving manifest: required attribute 'instances' missing"))
   309  		})
   310  	})
   311  })
   312  
   313  type YManifest struct {
   314  	Applications []YApplication `yaml:"applications"`
   315  }
   316  
   317  type YApplication struct {
   318  	Name                    string                 `yaml:"name"`
   319  	Services                []string               `yaml:"services"`
   320  	Buildpack               string                 `yaml:"buildpack"`
   321  	Memory                  string                 `yaml:"memory"`
   322  	Command                 string                 `yaml:"command"`
   323  	Env                     map[string]interface{} `yaml:"env"`
   324  	Timeout                 int                    `yaml:"timeout"`
   325  	Instances               int                    `yaml:"instances"`
   326  	Routes                  []map[string]string    `yaml:"routes"`
   327  	NoRoute                 bool                   `yaml:"no-route"`
   328  	DiskQuota               string                 `yaml:"disk_quota"`
   329  	Stack                   string                 `yaml:"stack"`
   330  	AppPorts                []int                  `yaml:"app-ports"`
   331  	HealthCheckType         string                 `yaml:"health-check-type"`
   332  	HealthCheckHTTPEndpoint string                 `yaml:"health-check-http-endpoint"`
   333  }
   334  
   335  func getYaml(f *bytes.Buffer) YManifest {
   336  	var document YManifest
   337  
   338  	err := yaml.Unmarshal([]byte(f.String()), &document)
   339  	Expect(err).NotTo(HaveOccurred())
   340  
   341  	return document
   342  }