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