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