github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/actor/v2action/manifest_test.go (about) 1 package v2action_test 2 3 import ( 4 "errors" 5 "io/ioutil" 6 "os" 7 8 . "code.cloudfoundry.org/cli/actor/v2action" 9 "code.cloudfoundry.org/cli/actor/v2action/v2actionfakes" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 12 "code.cloudfoundry.org/cli/types" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Manifest Actions", func() { 18 var ( 19 actor *Actor 20 fakeCloudControllerClient *v2actionfakes.FakeCloudControllerClient 21 manifestFilePath string 22 ) 23 24 BeforeEach(func() { 25 fakeCloudControllerClient = new(v2actionfakes.FakeCloudControllerClient) 26 actor = NewActor(fakeCloudControllerClient, nil, nil) 27 }) 28 29 Describe("CreateApplicationManifestByNameAndSpace", func() { 30 var ( 31 createWarnings Warnings 32 createErr error 33 ) 34 35 JustBeforeEach(func() { 36 createWarnings, createErr = actor.CreateApplicationManifestByNameAndSpace("some-app", "some-space-guid", manifestFilePath) 37 }) 38 39 Context("when getting the application summary errors", func() { 40 BeforeEach(func() { 41 fakeCloudControllerClient.GetApplicationsReturns([]ccv2.Application{}, ccv2.Warnings{"some-app-warning"}, errors.New("some-app-error")) 42 }) 43 44 It("returns the error and all warnings", func() { 45 Expect(createErr).To(MatchError("some-app-error")) 46 Expect(createWarnings).To(ConsistOf("some-app-warning")) 47 }) 48 }) 49 50 Context("when getting the application summary succeeds", func() { 51 var app ccv2.Application 52 53 BeforeEach(func() { 54 app = ccv2.Application{ 55 GUID: "some-app-guid", 56 Name: "some-app", 57 Buildpack: types.FilteredString{ 58 IsSet: true, 59 Value: "some-buildpack", 60 }, 61 DetectedBuildpack: types.FilteredString{ 62 IsSet: true, 63 Value: "some-detected-buildpack", 64 }, 65 DiskQuota: types.NullByteSizeInMb{IsSet: true, Value: 1024}, 66 DockerImage: "some-docker-image", 67 DockerCredentials: ccv2.DockerCredentials{ 68 Username: "some-docker-username", 69 Password: "some-docker-password", // CC currently always returns an empty string 70 }, 71 Command: types.FilteredString{ 72 IsSet: true, 73 Value: "some-command", 74 }, 75 DetectedStartCommand: types.FilteredString{ 76 IsSet: true, 77 Value: "some-detected-command", 78 }, 79 EnvironmentVariables: map[string]string{ 80 "env_1": "foo", 81 "env_2": "182837403930483038", 82 "env_3": "true", 83 "env_4": "1.00001", 84 }, 85 HealthCheckTimeout: 120, 86 HealthCheckHTTPEndpoint: "\\some-endpoint", 87 HealthCheckType: "http", 88 Instances: types.NullInt{ 89 Value: 10, 90 IsSet: true, 91 }, 92 Memory: types.NullByteSizeInMb{IsSet: true, Value: 200}, 93 StackGUID: "some-stack-guid", 94 } 95 96 fakeCloudControllerClient.GetApplicationsReturns( 97 []ccv2.Application{app}, 98 ccv2.Warnings{"some-app-warning"}, 99 nil) 100 101 fakeCloudControllerClient.GetApplicationRoutesReturns( 102 []ccv2.Route{ 103 { 104 GUID: "some-route-1-guid", 105 Host: "host-1", 106 DomainGUID: "some-domain-guid", 107 }, 108 { 109 GUID: "some-route-2-guid", 110 Host: "host-2", 111 DomainGUID: "some-domain-guid", 112 }, 113 }, 114 ccv2.Warnings{"some-routes-warning"}, 115 nil) 116 117 fakeCloudControllerClient.GetSharedDomainReturns( 118 ccv2.Domain{GUID: "some-domain-guid", Name: "some-domain"}, 119 ccv2.Warnings{"some-domain-warning"}, 120 nil) 121 122 fakeCloudControllerClient.GetStackReturns( 123 ccv2.Stack{Name: "some-stack"}, 124 ccv2.Warnings{"some-stack-warning"}, 125 nil) 126 }) 127 128 Context("when getting services fails", func() { 129 BeforeEach(func() { 130 fakeCloudControllerClient.GetServiceBindingsReturns( 131 []ccv2.ServiceBinding{}, 132 ccv2.Warnings{"some-service-warning"}, 133 errors.New("some-service-error"), 134 ) 135 }) 136 137 It("returns the error and all warnings", func() { 138 Expect(createErr).To(MatchError("some-service-error")) 139 Expect(createWarnings).To(ConsistOf("some-app-warning", "some-routes-warning", "some-domain-warning", "some-stack-warning", "some-service-warning")) 140 }) 141 }) 142 143 Context("when getting services succeeds", func() { 144 BeforeEach(func() { 145 fakeCloudControllerClient.GetServiceBindingsReturns( 146 []ccv2.ServiceBinding{ 147 {ServiceInstanceGUID: "service-1-guid"}, 148 {ServiceInstanceGUID: "service-2-guid"}, 149 }, 150 ccv2.Warnings{"some-service-warning"}, 151 nil, 152 ) 153 fakeCloudControllerClient.GetServiceInstanceStub = func(serviceInstanceGUID string) (ccv2.ServiceInstance, ccv2.Warnings, error) { 154 switch serviceInstanceGUID { 155 case "service-1-guid": 156 return ccv2.ServiceInstance{Name: "service-1"}, ccv2.Warnings{"some-service-1-warning"}, nil 157 case "service-2-guid": 158 return ccv2.ServiceInstance{Name: "service-2"}, ccv2.Warnings{"some-service-2-warning"}, nil 159 default: 160 panic("unknown service instance") 161 } 162 } 163 }) 164 165 Context("when writing manifest succeeds", func() { 166 BeforeEach(func() { 167 manifestFile, err := ioutil.TempFile("", "manifest-test-") 168 Expect(err).NotTo(HaveOccurred()) 169 Expect(manifestFile.Close()).To(Succeed()) 170 manifestFilePath = manifestFile.Name() 171 }) 172 173 AfterEach(func() { 174 Expect(os.Remove(manifestFilePath)).To(Succeed()) 175 }) 176 177 It("writes the manifest to the specified path", func() { 178 manifestBytes, err := ioutil.ReadFile(manifestFilePath) 179 Expect(err).NotTo(HaveOccurred()) 180 Expect(createWarnings).To(ConsistOf("some-app-warning", "some-routes-warning", "some-domain-warning", "some-stack-warning", "some-service-warning", "some-service-1-warning", "some-service-2-warning")) 181 Expect(string(manifestBytes)).To(Equal(`applications: 182 - name: some-app 183 buildpack: some-buildpack 184 command: some-command 185 disk_quota: 1G 186 docker: 187 image: some-docker-image 188 username: some-docker-username 189 env: 190 env_1: foo 191 env_2: "182837403930483038" 192 env_3: "true" 193 env_4: "1.00001" 194 health-check-http-endpoint: \some-endpoint 195 health-check-type: http 196 instances: 10 197 memory: 200M 198 routes: 199 - route: host-1.some-domain 200 - route: host-2.some-domain 201 services: 202 - service-1 203 - service-2 204 stack: some-stack 205 timeout: 120 206 `)) 207 }) 208 209 Context("when there are no routes", func() { 210 BeforeEach(func() { 211 fakeCloudControllerClient.GetApplicationRoutesReturns(nil, nil, nil) 212 }) 213 214 It("writes the manifest with no-route set to true", func() { 215 manifestBytes, err := ioutil.ReadFile(manifestFilePath) 216 Expect(err).NotTo(HaveOccurred()) 217 Expect(createWarnings).To(ConsistOf("some-app-warning", "some-stack-warning", "some-service-warning", "some-service-1-warning", "some-service-2-warning")) 218 Expect(string(manifestBytes)).To(Equal(`applications: 219 - name: some-app 220 buildpack: some-buildpack 221 command: some-command 222 disk_quota: 1G 223 docker: 224 image: some-docker-image 225 username: some-docker-username 226 env: 227 env_1: foo 228 env_2: "182837403930483038" 229 env_3: "true" 230 env_4: "1.00001" 231 health-check-http-endpoint: \some-endpoint 232 health-check-type: http 233 instances: 10 234 memory: 200M 235 no-route: true 236 services: 237 - service-1 238 - service-2 239 stack: some-stack 240 timeout: 120 241 `)) 242 }) 243 }) 244 245 Context("when docker image and username are not provided", func() { 246 BeforeEach(func() { 247 app.DockerImage = "" 248 app.DockerCredentials = ccv2.DockerCredentials{} 249 fakeCloudControllerClient.GetApplicationsReturns( 250 []ccv2.Application{app}, 251 ccv2.Warnings{"some-app-warning"}, 252 nil) 253 }) 254 255 It("does not include it in manifest", func() { 256 manifestBytes, err := ioutil.ReadFile(manifestFilePath) 257 Expect(err).NotTo(HaveOccurred()) 258 Expect(string(manifestBytes)).To(Equal(`applications: 259 - name: some-app 260 buildpack: some-buildpack 261 command: some-command 262 disk_quota: 1G 263 env: 264 env_1: foo 265 env_2: "182837403930483038" 266 env_3: "true" 267 env_4: "1.00001" 268 health-check-http-endpoint: \some-endpoint 269 health-check-type: http 270 instances: 10 271 memory: 200M 272 routes: 273 - route: host-1.some-domain 274 - route: host-2.some-domain 275 services: 276 - service-1 277 - service-2 278 stack: some-stack 279 timeout: 120 280 `)) 281 }) 282 }) 283 284 Describe("default CC values", func() { 285 // We ommitting default CC values from manifest 286 // so that it won't get too big 287 288 Context("when the health check type is port", func() { 289 BeforeEach(func() { 290 app.HealthCheckType = constant.ApplicationHealthCheckPort 291 fakeCloudControllerClient.GetApplicationsReturns( 292 []ccv2.Application{app}, 293 ccv2.Warnings{"some-app-warning"}, 294 nil) 295 }) 296 297 It("does not include health check type and endpoint", func() { 298 manifestBytes, err := ioutil.ReadFile(manifestFilePath) 299 Expect(err).NotTo(HaveOccurred()) 300 Expect(string(manifestBytes)).To(Equal(`applications: 301 - name: some-app 302 buildpack: some-buildpack 303 command: some-command 304 disk_quota: 1G 305 docker: 306 image: some-docker-image 307 username: some-docker-username 308 env: 309 env_1: foo 310 env_2: "182837403930483038" 311 env_3: "true" 312 env_4: "1.00001" 313 instances: 10 314 memory: 200M 315 routes: 316 - route: host-1.some-domain 317 - route: host-2.some-domain 318 services: 319 - service-1 320 - service-2 321 stack: some-stack 322 timeout: 120 323 `)) 324 }) 325 }) 326 327 Context("when the health check type is http", func() { 328 Context("when the health check endpoint path is '/'", func() { 329 BeforeEach(func() { 330 app.HealthCheckType = constant.ApplicationHealthCheckHTTP 331 app.HealthCheckHTTPEndpoint = "/" 332 fakeCloudControllerClient.GetApplicationsReturns( 333 []ccv2.Application{app}, 334 ccv2.Warnings{"some-app-warning"}, 335 nil) 336 }) 337 338 It("does not include health check endpoint in manifest", func() { 339 manifestBytes, err := ioutil.ReadFile(manifestFilePath) 340 Expect(err).NotTo(HaveOccurred()) 341 Expect(string(manifestBytes)).To(Equal(`applications: 342 - name: some-app 343 buildpack: some-buildpack 344 command: some-command 345 disk_quota: 1G 346 docker: 347 image: some-docker-image 348 username: some-docker-username 349 env: 350 env_1: foo 351 env_2: "182837403930483038" 352 env_3: "true" 353 env_4: "1.00001" 354 health-check-type: http 355 instances: 10 356 memory: 200M 357 routes: 358 - route: host-1.some-domain 359 - route: host-2.some-domain 360 services: 361 - service-1 362 - service-2 363 stack: some-stack 364 timeout: 120 365 `)) 366 }) 367 }) 368 369 Context("when the health check type is process", func() { 370 BeforeEach(func() { 371 app.HealthCheckType = constant.ApplicationHealthCheckProcess 372 fakeCloudControllerClient.GetApplicationsReturns( 373 []ccv2.Application{app}, 374 ccv2.Warnings{"some-app-warning"}, 375 nil) 376 }) 377 378 It("does not include health check endpoint in manifest", func() { 379 manifestBytes, err := ioutil.ReadFile(manifestFilePath) 380 Expect(err).NotTo(HaveOccurred()) 381 Expect(string(manifestBytes)).To(Equal(`applications: 382 - name: some-app 383 buildpack: some-buildpack 384 command: some-command 385 disk_quota: 1G 386 docker: 387 image: some-docker-image 388 username: some-docker-username 389 env: 390 env_1: foo 391 env_2: "182837403930483038" 392 env_3: "true" 393 env_4: "1.00001" 394 health-check-type: process 395 instances: 10 396 memory: 200M 397 routes: 398 - route: host-1.some-domain 399 - route: host-2.some-domain 400 services: 401 - service-1 402 - service-2 403 stack: some-stack 404 timeout: 120 405 `)) 406 }) 407 }) 408 }) 409 }) 410 }) 411 412 Context("when writing the manifest fails", func() { 413 BeforeEach(func() { 414 var err error 415 manifestFilePath, err = ioutil.TempDir("", "manifest-test-") 416 Expect(err).NotTo(HaveOccurred()) 417 }) 418 419 AfterEach(func() { 420 Expect(os.RemoveAll(manifestFilePath)).To(Succeed()) 421 }) 422 423 It("returns an ManifestCreationError", func() { 424 Expect(createErr).To(HaveOccurred()) 425 Expect(createErr.Error()).To(ContainSubstring("Error creating manifest file:")) 426 Expect(createWarnings).To(ConsistOf("some-app-warning", "some-routes-warning", "some-domain-warning", "some-stack-warning", "some-service-warning", "some-service-1-warning", "some-service-2-warning")) 427 }) 428 }) 429 }) 430 }) 431 }) 432 })