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