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 }