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