github.com/arunkumar7540/cli@v6.45.0+incompatible/integration/v6/push/buildpack_test.go (about) 1 package push 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "math/rand" 7 "os" 8 "path/filepath" 9 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccversion" 11 "code.cloudfoundry.org/cli/integration/helpers" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 . "github.com/onsi/gomega/gbytes" 15 . "github.com/onsi/gomega/gexec" 16 ) 17 18 var _ = Describe("push with different buildpack values", func() { 19 var ( 20 appName string 21 ) 22 23 BeforeEach(func() { 24 appName = helpers.NewAppName() 25 }) 26 27 When("the buildpack flag is provided", func() { 28 When("only one buildpack is provided", func() { 29 BeforeEach(func() { 30 helpers.WithHelloWorldApp(func(dir string) { 31 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 32 PushCommandName, appName, 33 "-b", "binary_buildpack", 34 "--no-start", 35 ) 36 37 Eventually(session).Should(Say(`(?m)\s+buildpacks:\s+\+\s+binary_buildpack`)) 38 Eventually(session).Should(Exit(0)) 39 }) 40 }) 41 42 It("pushing a staticfile app with a null buildpack sets buildpack to auto-detected (staticfile)", func() { 43 helpers.WithHelloWorldApp(func(dir string) { 44 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 45 PushCommandName, appName, 46 "-b", "null", 47 ) 48 Eventually(session).Should(Say(`(?m)\s+buildpacks:\s+-\s+binary_buildpack`)) 49 Eventually(session).Should(Say(`buildpacks?:\s+staticfile`)) 50 Eventually(session).Should(Exit(0)) 51 }) 52 }) 53 54 It("pushing a staticfile app with a default buildpack sets buildpack to auto-detected (staticfile)", func() { 55 helpers.WithHelloWorldApp(func(dir string) { 56 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 57 PushCommandName, appName, 58 "-b", "default", 59 ) 60 Eventually(session).Should(Say(`(?m)\s+buildpacks:\s+-\s+binary_buildpack`)) 61 Eventually(session).Should(Say(`buildpacks?:\s+staticfile`)) 62 Eventually(session).Should(Exit(0)) 63 }) 64 }) 65 }) 66 67 When("multiple instances of buildpack are provided", func() { 68 When("the buildpacks do not use the default stack", func() { 69 var ( 70 buildpacks []string 71 nonDefaultStack string 72 ) 73 74 BeforeEach(func() { 75 helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2) 76 nonDefaultStack = helpers.CreateStack() 77 buildpacks = []string{helpers.NewBuildpackName(), helpers.NewBuildpackName()} 78 for _, buildpack := range buildpacks { 79 helpers.SetupBuildpackWithStack(buildpack, nonDefaultStack) 80 } 81 }) 82 83 When("a stack is provided", func() { 84 It("pushes the app successfully with multiple buildpacks using the stack specified", func() { 85 helpers.WithProcfileApp(func(dir string) { 86 tempfile := filepath.Join(dir, "index.html") 87 err := ioutil.WriteFile(tempfile, []byte(fmt.Sprintf("hello world %d", rand.Int())), 0666) 88 Expect(err).ToNot(HaveOccurred()) 89 90 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 91 PushCommandName, appName, 92 "-b", buildpacks[0], "-b", buildpacks[1], "-s", nonDefaultStack, "--no-start", 93 ) 94 Eventually(session).Should(Exit(0)) 95 }) 96 97 session := helpers.CF("curl", fmt.Sprintf("v3/apps/%s", helpers.AppGUID(appName))) 98 99 Eventually(session).Should(Say(`\s+"buildpacks":\s+`)) 100 Eventually(session).Should(Say(`\s+"%s"`, buildpacks[0])) 101 Eventually(session).Should(Say(`\s+"%s"`, buildpacks[1])) 102 Eventually(session).Should(Say(`"stack":\s+"%s"`, nonDefaultStack)) 103 Eventually(session).Should(Exit(0)) 104 }) 105 }) 106 }) 107 108 When("the app does NOT have existing buildpack configurations", func() { 109 It("pushes the app successfully with multiple buildpacks", func() { 110 helpers.WithProcfileApp(func(dir string) { 111 tempfile := filepath.Join(dir, "index.html") 112 err := ioutil.WriteFile(tempfile, []byte(fmt.Sprintf("hello world %d", rand.Int())), 0666) 113 Expect(err).ToNot(HaveOccurred()) 114 115 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 116 PushCommandName, appName, 117 "-b", "staticfile_buildpack", "-b", "ruby_buildpack", "--no-start", 118 ) 119 Eventually(session).Should(Exit(0)) 120 }) 121 122 session := helpers.CF("curl", fmt.Sprintf("v3/apps/%s", helpers.AppGUID(appName))) 123 124 Eventually(session).Should(Say(`\s+"buildpacks":\s+`)) 125 Eventually(session).Should(Say(`\s+"staticfile_buildpack"`)) 126 Eventually(session).Should(Say(`\s+"ruby_buildpack"`)) 127 Eventually(session).Should(Exit(0)) 128 }) 129 }) 130 131 When("the app has existing buildpacks", func() { 132 It("pushes the app successfully and overrides the existing buildpacks", func() { 133 helpers.WithHelloWorldApp(func(dir string) { 134 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 135 "applications": []map[string]interface{}{ 136 { 137 "name": appName, 138 "buildpacks": []string{ 139 "ruby_buildpack", 140 "staticfile_buildpack", 141 }, 142 }, 143 }, 144 }) 145 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 146 PushCommandName, appName, 147 "-b", "php_buildpack", "-b", "go_buildpack", "--no-start", 148 ) 149 Eventually(session).Should(Exit(0)) 150 }) 151 152 session := helpers.CF("curl", fmt.Sprintf("v3/apps/%s", helpers.AppGUID(appName))) 153 154 Eventually(session).Should(Say(`\s+"buildpacks":\s+`)) 155 Eventually(session).Should(Say(`php_buildpack`)) 156 Eventually(session).Should(Say(`go_buildpack`)) 157 Eventually(session).Should(Exit(0)) 158 }) 159 }) 160 161 When("the app has existing `buildpack`", func() { 162 It("pushes the app successfully and overrides the existing buildpacks", func() { 163 helpers.WithHelloWorldApp(func(dir string) { 164 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 165 "applications": []map[string]interface{}{ 166 { 167 "name": appName, 168 "buildpack": "staticfile_buildpack", 169 }, 170 }, 171 }) 172 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 173 PushCommandName, appName, 174 "-b", "php_buildpack", "-b", "go_buildpack", "--no-start", 175 ) 176 Eventually(session).Should(Exit(0)) 177 }) 178 179 session := helpers.CF("curl", fmt.Sprintf("v3/apps/%s", helpers.AppGUID(appName))) 180 181 Eventually(session).Should(Say(`\s+"buildpacks":\s+`)) 182 Eventually(session).Should(Say(`php_buildpack`)) 183 Eventually(session).Should(Say(`go_buildpack`)) 184 Eventually(session).Should(Exit(0)) 185 }) 186 }) 187 188 When("one of the buildpacks provided is null or default", func() { 189 It("fails and prints an error", func() { 190 helpers.WithProcfileApp(func(dir string) { 191 tempfile := filepath.Join(dir, "index.html") 192 err := ioutil.WriteFile(tempfile, []byte(fmt.Sprintf("hello world %d", rand.Int())), 0666) 193 Expect(err).ToNot(HaveOccurred()) 194 195 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 196 PushCommandName, appName, 197 "-b", "staticfile_buildpack", "-b", "null", "--no-start", 198 ) 199 Eventually(session).Should(Exit(1)) 200 Eventually(session.Err).Should(Say("Multiple buildpacks flags cannot have null/default option.")) 201 }) 202 }) 203 }) 204 }) 205 }) 206 207 When("buildpack is provided via manifest", func() { 208 It("sets buildpack and returns a warning", func() { 209 helpers.WithHelloWorldApp(func(dir string) { 210 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 211 "applications": []map[string]interface{}{ 212 { 213 "name": appName, 214 "buildpack": "staticfile_buildpack", 215 }, 216 }, 217 }) 218 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName, "no-start") 219 Eventually(session).Should(Say(`(?m)\s+buildpacks:\s+\+\s+staticfile_buildpack`)) 220 Eventually(session.Err).Should(Say(`Deprecation warning: Use of 'buildpack'`)) 221 Eventually(session).Should(Exit(0)) 222 }) 223 }) 224 }) 225 226 When("buildpacks (plural) is provided via manifest", func() { 227 When("mutiple buildpacks are specified", func() { 228 It("sets all buildpacks correctly for the pushed app", func() { 229 helpers.WithHelloWorldApp(func(dir string) { 230 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 231 "applications": []map[string]interface{}{ 232 { 233 "name": appName, 234 "buildpacks": []string{ 235 "https://github.com/cloudfoundry/ruby-buildpack", 236 "https://github.com/cloudfoundry/staticfile-buildpack", 237 }, 238 }, 239 }, 240 }) 241 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName) 242 Eventually(session).Should(Exit(0)) 243 }) 244 245 session := helpers.CF("curl", fmt.Sprintf("v3/apps/%s", helpers.AppGUID(appName))) 246 247 Eventually(session).Should(Say(`https://github.com/cloudfoundry/ruby-buildpack"`)) 248 Eventually(session).Should(Say(`https://github.com/cloudfoundry/staticfile-buildpack"`)) 249 Eventually(session).Should(Exit(0)) 250 }) 251 }) 252 253 When("only one buildpack is specified", func() { 254 It("sets only one buildpack for the pushed app", func() { 255 helpers.WithHelloWorldApp(func(dir string) { 256 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 257 "applications": []map[string]interface{}{ 258 { 259 "name": appName, 260 "buildpacks": []string{ 261 "https://github.com/cloudfoundry/staticfile-buildpack", 262 }, 263 }, 264 }, 265 }) 266 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName) 267 Eventually(session).Should(Exit(0)) 268 }) 269 270 session := helpers.CF("curl", fmt.Sprintf("v3/apps/%s", helpers.AppGUID(appName))) 271 272 // TODO: fix during app command rework to actually test that the second buildpack does not exist 273 Eventually(session).Should(Say(`https://github.com/cloudfoundry/staticfile-buildpack"`)) 274 Eventually(session).Should(Exit(0)) 275 }) 276 }) 277 278 When("empty list of buildpacks is specified", func() { 279 It("autodetects the buildpack", func() { 280 helpers.WithHelloWorldApp(func(dir string) { 281 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName, "-b", "staticfile_buildpack", "--no-start") 282 Eventually(session).Should(Exit(0)) 283 284 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 285 "applications": []map[string]interface{}{ 286 { 287 "name": appName, 288 "buildpacks": []string{}, 289 }, 290 }, 291 }) 292 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName) 293 Eventually(session).Should(Exit(0)) 294 }) 295 296 By("displaying an empty buildpacks field") 297 session := helpers.CF("curl", fmt.Sprintf("v3/apps/%s", helpers.AppGUID(appName))) 298 299 Eventually(session).Should(Say(`"buildpacks": \[\]`)) 300 Eventually(session).Should(Exit(0)) 301 }) 302 }) 303 304 When("an empty string is specified", func() { 305 It("rasises an error", func() { 306 helpers.WithHelloWorldApp(func(dir string) { 307 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 308 "applications": []map[string]interface{}{ 309 { 310 "name": appName, 311 "buildpacks": nil, 312 }, 313 }, 314 }) 315 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName) 316 Eventually(session).Should(Exit(1)) 317 Eventually(session.Err).Should(Say("Buildpacks property cannot be an empty string.")) 318 }) 319 }) 320 }) 321 }) 322 323 When("both buildpack and buildpacks are provided via manifest", func() { 324 It("returns an error", func() { 325 helpers.WithHelloWorldApp(func(dir string) { 326 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 327 "applications": []map[string]interface{}{ 328 { 329 "name": appName, 330 "buildpack": "ruby_buildpack", 331 "buildpacks": []string{ 332 "https://github.com/cloudfoundry/staticfile-buildpack", 333 }, 334 }, 335 }, 336 }) 337 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName) 338 339 Eventually(session).Should(Exit(1)) 340 Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: buildpack, buildpacks", appName)) 341 }) 342 }) 343 }) 344 345 When("both buildpacks and docker are provided via manfest", func() { 346 It("returns an error", func() { 347 helpers.WithHelloWorldApp(func(dir string) { 348 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 349 "applications": []map[string]interface{}{ 350 { 351 "name": appName, 352 "docker": map[string]interface{}{ 353 "image": PublicDockerImage, 354 }, 355 "buildpacks": []string{ 356 "https://github.com/cloudfoundry/staticfile-buildpack", 357 }, 358 }, 359 }, 360 }) 361 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName) 362 363 Eventually(session).Should(Exit(1)) 364 Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: docker, buildpacks", appName)) 365 }) 366 }) 367 }) 368 369 When("both buildpacks and docker are provided via flags", func() { 370 It("returns an error", func() { 371 helpers.WithHelloWorldApp(func(dir string) { 372 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 373 PushCommandName, appName, "-o", PublicDockerImage, "-b", "ruby_buildpack", "-b", "staticfile_buildpack", 374 ) 375 376 Eventually(session).Should(Exit(1)) 377 Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: -b, --docker-image, -o")) 378 }) 379 }) 380 }) 381 382 When("buildpack is provided via manifest and droplet is provided via flags", func() { 383 var tempDroplet string 384 385 BeforeEach(func() { 386 f, err := ioutil.TempFile("", "INT-push-buildpack-droplet-") 387 Expect(err).ToNot(HaveOccurred()) 388 Expect(f.Close()).ToNot(HaveOccurred()) 389 390 tempDroplet = f.Name() 391 }) 392 393 AfterEach(func() { 394 Expect(os.RemoveAll(tempDroplet)).ToNot(HaveOccurred()) 395 }) 396 397 It("returns an error", func() { 398 helpers.WithHelloWorldApp(func(dir string) { 399 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 400 "applications": []map[string]interface{}{ 401 { 402 "name": appName, 403 "buildpack": "https://github.com/cloudfoundry/staticfile-buildpack", 404 }, 405 }, 406 }) 407 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName, "--droplet", tempDroplet) 408 409 Eventually(session).Should(Exit(1)) 410 Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: droplet, buildpack", appName)) 411 }) 412 }) 413 }) 414 415 When("buildpacks is provided via manifest and droplet is provided via flags", func() { 416 var tempDroplet string 417 418 BeforeEach(func() { 419 f, err := ioutil.TempFile("", "INT-push-buildpack-droplet-") 420 Expect(err).ToNot(HaveOccurred()) 421 Expect(f.Close()).ToNot(HaveOccurred()) 422 423 tempDroplet = f.Name() 424 }) 425 426 AfterEach(func() { 427 Expect(os.RemoveAll(tempDroplet)).ToNot(HaveOccurred()) 428 }) 429 430 It("returns an error", func() { 431 helpers.WithHelloWorldApp(func(dir string) { 432 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 433 "applications": []map[string]interface{}{ 434 { 435 "name": appName, 436 "buildpacks": []string{ 437 "https://github.com/cloudfoundry/staticfile-buildpack", 438 }, 439 }, 440 }, 441 }) 442 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName, "--droplet", tempDroplet) 443 444 Eventually(session).Should(Exit(1)) 445 Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: droplet, buildpacks", appName)) 446 }) 447 }) 448 }) 449 450 When("both buildpack and droplet are provided via flags", func() { 451 var tempDroplet string 452 453 BeforeEach(func() { 454 f, err := ioutil.TempFile("", "INT-push-buildpack-droplet-") 455 Expect(err).ToNot(HaveOccurred()) 456 Expect(f.Close()).ToNot(HaveOccurred()) 457 458 tempDroplet = f.Name() 459 }) 460 461 AfterEach(func() { 462 Expect(os.RemoveAll(tempDroplet)).ToNot(HaveOccurred()) 463 }) 464 465 It("returns an error", func() { 466 helpers.WithHelloWorldApp(func(dir string) { 467 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 468 PushCommandName, appName, "--droplet", tempDroplet, "-b", "staticfile_buildpack", 469 ) 470 471 Eventually(session).Should(Exit(1)) 472 Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: droplet, buildpack", appName)) 473 }) 474 }) 475 }) 476 477 When("both buildpacks and droplet are provided via flags", func() { 478 var tempDroplet string 479 480 BeforeEach(func() { 481 f, err := ioutil.TempFile("", "INT-push-buildpack-droplet-") 482 Expect(err).ToNot(HaveOccurred()) 483 Expect(f.Close()).ToNot(HaveOccurred()) 484 485 tempDroplet = f.Name() 486 }) 487 488 AfterEach(func() { 489 Expect(os.RemoveAll(tempDroplet)).ToNot(HaveOccurred()) 490 }) 491 492 It("returns an error", func() { 493 helpers.WithHelloWorldApp(func(dir string) { 494 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, 495 PushCommandName, appName, "--droplet", tempDroplet, "-b", "ruby_buildpack", "-b", "staticfile_buildpack", 496 ) 497 498 Eventually(session).Should(Exit(1)) 499 Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: droplet, buildpacks", appName)) 500 }) 501 }) 502 }) 503 })