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