github.com/arunkumar7540/cli@v6.45.0+incompatible/integration/v6/global/create_buildpack_command_test.go (about) 1 package global 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "log" 7 "net/http" 8 "os" 9 "regexp" 10 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccversion" 12 "code.cloudfoundry.org/cli/integration/helpers" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 . "github.com/onsi/gomega/gbytes" 16 . "github.com/onsi/gomega/gexec" 17 . "github.com/onsi/gomega/ghttp" 18 ) 19 20 var _ = Describe("create buildpack command", func() { 21 var ( 22 buildpackName string 23 username string 24 ) 25 26 BeforeEach(func() { 27 buildpackName = helpers.NewBuildpackName() 28 }) 29 30 Describe("help", func() { 31 When("--help flag is set", func() { 32 It("Displays command usage to output", func() { 33 session := helpers.CF("create-buildpack", "--help") 34 Eventually(session).Should(Say("NAME:")) 35 Eventually(session).Should(Say("create-buildpack - Create a buildpack")) 36 Eventually(session).Should(Say("USAGE:")) 37 Eventually(session).Should(Say(`cf create-buildpack BUILDPACK PATH POSITION \[--enable|--disable\]`)) 38 Eventually(session).Should(Say("TIP:")) 39 Eventually(session).Should(Say("Path should be a zip file, a url to a zip file, or a local directory. Position is a positive integer, sets priority, and is sorted from lowest to highest.")) 40 Eventually(session).Should(Say("OPTIONS:")) 41 Eventually(session).Should(Say(`--disable\s+Disable the buildpack from being used for staging`)) 42 Eventually(session).Should(Say(`--enable\s+Enable the buildpack to be used for staging`)) 43 Eventually(session).Should(Say("SEE ALSO:")) 44 Eventually(session).Should(Say("buildpacks, push")) 45 Eventually(session).Should(Exit(0)) 46 }) 47 }) 48 }) 49 50 When("the environment is not setup correctly", func() { 51 It("fails with the appropriate errors", func() { 52 path, err := os.Getwd() 53 Expect(err).ToNot(HaveOccurred()) 54 55 helpers.CheckEnvironmentTargetedCorrectly(false, false, ReadOnlyOrg, "create-buildpack", "fake-buildpack", path, "1") 56 }) 57 }) 58 59 When("the user is logged in", func() { 60 BeforeEach(func() { 61 helpers.LoginCF() 62 username, _ = helpers.GetCredentials() 63 }) 64 65 When("uploading from a directory", func() { 66 var buildpackDir string 67 68 AfterEach(func() { 69 err := os.RemoveAll(buildpackDir) 70 Expect(err).ToNot(HaveOccurred()) 71 }) 72 73 When("zipping the directory errors", func() { 74 BeforeEach(func() { 75 buildpackDir = "some/nonexistent/dir" 76 }) 77 78 It("returns an error", func() { 79 session := helpers.CF("create-buildpack", buildpackName, buildpackDir, "1") 80 Eventually(session.Err).Should(Say("Incorrect Usage: The specified path 'some/nonexistent/dir' does not exist.")) 81 Eventually(session).Should(Say("USAGE:")) 82 Eventually(session).Should(Exit(1)) 83 }) 84 }) 85 86 When("zipping the directory succeeds", func() { 87 BeforeEach(func() { 88 var err error 89 buildpackDir, err = ioutil.TempDir("", "buildpackdir-") 90 Expect(err).ToNot(HaveOccurred()) 91 file, err := ioutil.TempFile(buildpackDir, "myfile-") 92 defer file.Close() 93 Expect(err).ToNot(HaveOccurred()) 94 }) 95 96 It("successfully uploads a buildpack", func() { 97 session := helpers.CF("create-buildpack", buildpackName, buildpackDir, "1") 98 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 99 Eventually(session).Should(Say("OK")) 100 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 101 Eventually(session).Should(Say("Done uploading")) 102 Eventually(session).Should(Say("OK")) 103 Eventually(session).Should(Exit(0)) 104 }) 105 }) 106 107 When("the specified directory is empty", func() { 108 BeforeEach(func() { 109 var err error 110 buildpackDir, err = ioutil.TempDir("", "empty-") 111 Expect(err).ToNot(HaveOccurred()) 112 }) 113 114 It("fails and reports that the directory is empty", func() { 115 session := helpers.CF("create-buildpack", buildpackName, buildpackDir, "1") 116 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 117 Eventually(session.Err).Should(Say("The specified path '%s' cannot be an empty directory.", regexp.QuoteMeta(buildpackDir))) 118 Eventually(session).Should(Say("FAILED")) 119 Eventually(session).Should(Exit(1)) 120 }) 121 }) 122 }) 123 124 When("uploading from a zip", func() { 125 var stacks []string 126 127 BeforeEach(func() { 128 stacks = helpers.EnsureMinimumNumberOfStacks(2) 129 }) 130 131 When("specifying a valid path", func() { 132 When("the new buildpack is unique", func() { 133 When("the new buildpack has a nil stack", func() { 134 It("successfully uploads a buildpack", func() { 135 helpers.BuildpackWithoutStack(func(buildpackPath string) { 136 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 137 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 138 Eventually(session).Should(Say("OK")) 139 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 140 Eventually(session).Should(Say("Done uploading")) 141 Eventually(session).Should(Say("OK")) 142 Eventually(session).Should(Exit(0)) 143 }) 144 145 session := helpers.CF("buildpacks") 146 Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{ 147 Name: buildpackName, Position: "1"}))) 148 Eventually(session).Should(Exit(0)) 149 }) 150 }) 151 152 When("the new buildpack has a valid stack", func() { 153 BeforeEach(func() { 154 helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2) 155 }) 156 157 It("successfully uploads a buildpack", func() { 158 helpers.BuildpackWithStack(func(buildpackPath string) { 159 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 160 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 161 Eventually(session).Should(Say("OK")) 162 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 163 Eventually(session).Should(Say("Done uploading")) 164 Eventually(session).Should(Say("OK")) 165 Eventually(session).Should(Exit(0)) 166 }, stacks[0]) 167 168 session := helpers.CF("buildpacks") 169 Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{ 170 Name: buildpackName, Stack: stacks[0], Position: "1", 171 }))) 172 Eventually(session).Should(Exit(0)) 173 }) 174 }) 175 }) 176 177 When("the new buildpack has an invalid stack", func() { 178 BeforeEach(func() { 179 helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2) 180 }) 181 182 It("returns the appropriate error", func() { 183 helpers.BuildpackWithStack(func(buildpackPath string) { 184 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 185 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 186 Eventually(session).Should(Say("OK")) 187 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 188 Eventually(session.Err).Should(Say(`Uploaded buildpack stack \(fake-stack\) does not exist`)) 189 Eventually(session).Should(Exit(1)) 190 }, "fake-stack") 191 }) 192 }) 193 194 When("a buildpack with the same name exists", func() { 195 var ( 196 existingBuildpack string 197 ) 198 199 BeforeEach(func() { 200 existingBuildpack = buildpackName 201 }) 202 203 When("the new buildpack has a nil stack", func() { 204 BeforeEach(func() { 205 helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2) 206 }) 207 208 When("the existing buildpack does not have a nil stack", func() { 209 BeforeEach(func() { 210 helpers.BuildpackWithStack(func(buildpackPath string) { 211 session := helpers.CF("create-buildpack", existingBuildpack, buildpackPath, "5") 212 Eventually(session).Should(Exit(0)) 213 }, stacks[0]) 214 }) 215 216 It("successfully uploads a buildpack", func() { 217 helpers.BuildpackWithStack(func(buildpackPath string) { 218 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 219 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 220 Eventually(session).Should(Say("OK")) 221 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 222 Eventually(session).Should(Exit(0)) 223 }, stacks[0]) 224 225 session := helpers.CF("buildpacks") 226 Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{ 227 Name: buildpackName, Position: "1"}))) 228 Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{ 229 Name: existingBuildpack, Stack: stacks[0], Position: "6"}))) 230 Eventually(session).Should(Exit(0)) 231 }) 232 }) 233 234 When("the existing buildpack has a nil stack", func() { 235 BeforeEach(func() { 236 helpers.BuildpackWithoutStack(func(buildpackPath string) { 237 session := helpers.CF("create-buildpack", existingBuildpack, buildpackPath, "5") 238 Eventually(session).Should(Exit(0)) 239 }) 240 }) 241 242 It("prints a warning but exits 0", func() { 243 helpers.BuildpackWithoutStack(func(buildpackPath string) { 244 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 245 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 246 Eventually(session.Err).Should(Say("Buildpack %s already exists without a stack", buildpackName)) 247 Eventually(session).Should(Exit(0)) 248 }) 249 250 session := helpers.CF("buildpacks") 251 Eventually(session).Should(Say(`%s\s+5`, existingBuildpack)) 252 Eventually(session).Should(Exit(0)) 253 }) 254 }) 255 }) 256 257 When("the new buildpack has a non-nil stack", func() { 258 BeforeEach(func() { 259 helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2) 260 }) 261 262 When("the existing buildpack has a different non-nil stack", func() { 263 BeforeEach(func() { 264 helpers.BuildpackWithStack(func(buildpackPath string) { 265 session := helpers.CF("create-buildpack", existingBuildpack, buildpackPath, "5") 266 Eventually(session).Should(Exit(0)) 267 }, stacks[1]) 268 }) 269 270 It("successfully uploads a buildpack", func() { 271 helpers.BuildpackWithStack(func(buildpackPath string) { 272 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 273 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 274 Eventually(session).Should(Say("OK")) 275 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 276 Eventually(session).Should(Say("Done uploading")) 277 Eventually(session).Should(Say("OK")) 278 Eventually(session).Should(Exit(0)) 279 }, stacks[0]) 280 281 session := helpers.CF("buildpacks") 282 Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{ 283 Name: buildpackName, Stack: stacks[0]}))) 284 Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{ 285 Name: existingBuildpack, Stack: stacks[1]}))) 286 Eventually(session).Should(Exit(0)) 287 }) 288 }) 289 290 When("the existing buildpack has a nil stack", func() { 291 BeforeEach(func() { 292 helpers.BuildpackWithoutStack(func(buildpackPath string) { 293 session := helpers.CF("create-buildpack", existingBuildpack, buildpackPath, "5") 294 Eventually(session).Should(Exit(0)) 295 }) 296 }) 297 298 It("prints a warning and tip but exits 0", func() { 299 helpers.BuildpackWithStack(func(buildpackPath string) { 300 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 301 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 302 Eventually(session.Err).Should(Say("Buildpack %s already exists without a stack", buildpackName)) 303 Eventually(session).Should(Say("TIP: use 'cf buildpacks' and 'cf delete-buildpack' to delete buildpack %s without a stack", buildpackName)) 304 Eventually(session).Should(Exit(0)) 305 }, stacks[0]) 306 }) 307 }) 308 309 When("the existing buildpack has the same non-nil stack", func() { 310 BeforeEach(func() { 311 helpers.BuildpackWithStack(func(buildpackPath string) { 312 session := helpers.CF("create-buildpack", existingBuildpack, buildpackPath, "5") 313 Eventually(session).Should(Exit(0)) 314 }, stacks[0]) 315 }) 316 317 It("prints a warning but doesn't exit 1", func() { 318 helpers.BuildpackWithStack(func(buildpackPath string) { 319 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 320 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 321 Eventually(session.Err).Should(Say("The buildpack name %s is already in use for the stack %s", buildpackName, stacks[0])) 322 Eventually(session).Should(Say("TIP: use 'cf update-buildpack' to update this buildpack")) 323 Eventually(session).Should(Exit(0)) 324 }, stacks[0]) 325 }) 326 }) 327 }) 328 329 When("the API doesn't support stack association", func() { 330 BeforeEach(func() { 331 helpers.SkipIfVersionAtLeast(ccversion.MinVersionBuildpackStackAssociationV2) 332 333 helpers.BuildpackWithoutStack(func(buildpackPath string) { 334 session := helpers.CF("create-buildpack", existingBuildpack, buildpackPath, "5") 335 Eventually(session).Should(Exit(0)) 336 }) 337 }) 338 339 It("prints a warning but doesn't exit 1", func() { 340 helpers.BuildpackWithoutStack(func(buildpackPath string) { 341 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1") 342 Eventually(session.Err).Should(Say("Buildpack %s already exists", buildpackName)) 343 Eventually(session).Should(Say("TIP: use 'cf update-buildpack' to update this buildpack")) 344 Eventually(session).Should(Exit(0)) 345 }) 346 }) 347 }) 348 }) 349 }) 350 351 When("specifying an invalid path", func() { 352 It("returns the appropriate error", func() { 353 session := helpers.CF("create-buildpack", buildpackName, "bogus-path", "1") 354 355 Eventually(session.Err).Should(Say("Incorrect Usage: The specified path 'bogus-path' does not exist")) 356 Eventually(session).Should(Say("USAGE:")) 357 Eventually(session).Should(Exit(1)) 358 }) 359 }) 360 }) 361 362 When("uploading from a URL", func() { 363 var buildpackURL string 364 365 When("specifying a valid URL", func() { 366 BeforeEach(func() { 367 buildpackURL = "https://github.com/cloudfoundry/binary-buildpack/releases/download/v1.0.21/binary-buildpack-v1.0.21.zip" 368 }) 369 370 It("successfully uploads a buildpack", func() { 371 session := helpers.CF("create-buildpack", buildpackName, buildpackURL, "1") 372 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 373 Eventually(session).Should(Say("OK")) 374 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 375 Eventually(session).Should(Say("Done uploading")) 376 Eventually(session).Should(Say("OK")) 377 Eventually(session).Should(Exit(0)) 378 }) 379 }) 380 381 When("a 4xx or 5xx HTTP response status is encountered", func() { 382 var server *Server 383 384 BeforeEach(func() { 385 server = NewServer() 386 // Suppresses ginkgo server logs 387 server.HTTPTestServer.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0) 388 server.AppendHandlers( 389 CombineHandlers( 390 VerifyRequest(http.MethodGet, "/"), 391 RespondWith(http.StatusNotFound, nil), 392 ), 393 ) 394 }) 395 396 AfterEach(func() { 397 server.Close() 398 }) 399 400 It("displays an appropriate error", func() { 401 session := helpers.CF("create-buildpack", buildpackName, server.URL(), "10") 402 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 403 Eventually(session.Err).Should(Say("Download attempt failed; server returned 404 Not Found")) 404 Eventually(session.Err).Should(Say(`Unable to install; buildpack is not available from the given URL\.`)) 405 Eventually(session).Should(Say("FAILED")) 406 Eventually(session).Should(Exit(1)) 407 }) 408 }) 409 410 When("specifying an invalid URL", func() { 411 BeforeEach(func() { 412 buildpackURL = "http://not-a-real-url" 413 }) 414 415 It("returns the appropriate error", func() { 416 session := helpers.CF("create-buildpack", buildpackName, buildpackURL, "1") 417 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 418 Eventually(session.Err).Should(Say("Get %s: dial tcp: lookup", buildpackURL)) 419 Eventually(session).Should(Say("FAILED")) 420 Eventually(session).Should(Exit(1)) 421 }) 422 }) 423 }) 424 425 When("specifying the position flag", func() { 426 When("position is positive integer", func() { 427 It("successfully uploads buildpack in correct position", func() { 428 helpers.BuildpackWithoutStack(func(buildpackPath string) { 429 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "3") 430 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 431 Eventually(session).Should(Say("OK")) 432 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 433 Eventually(session).Should(Say("Done uploading")) 434 Eventually(session).Should(Say("OK")) 435 Eventually(session).Should(Exit(0)) 436 }) 437 438 session := helpers.CF("buildpacks") 439 Eventually(session).Should(Say(`%s\s+3`, buildpackName)) 440 Eventually(session).Should(Exit(0)) 441 }) 442 }) 443 }) 444 445 When("using the enable/disable flags", func() { 446 When("specifying disable flag", func() { 447 It("disables buildpack", func() { 448 helpers.BuildpackWithoutStack(func(buildpackPath string) { 449 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1", "--disable") 450 Eventually(session).Should(Say(`Creating buildpack %s as %s\.\.\.`, buildpackName, username)) 451 Eventually(session).Should(Say("OK")) 452 Eventually(session).Should(Say(`Uploading buildpack %s as %s\.\.\.`, buildpackName, username)) 453 Eventually(session).Should(Say("Done uploading")) 454 Eventually(session).Should(Say("OK")) 455 Eventually(session).Should(Exit(0)) 456 }) 457 458 session := helpers.CF("buildpacks") 459 Eventually(session).Should(Say(`%s\s+1\s+false`, buildpackName)) 460 Eventually(session).Should(Exit(0)) 461 }) 462 }) 463 464 When("specifying both enable and disable flags", func() { 465 It("returns the appropriate error", func() { 466 helpers.BuildpackWithoutStack(func(buildpackPath string) { 467 session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1", "--enable", "--disable") 468 Eventually(session).Should(Say("FAILED")) 469 Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: --enable, --disable")) 470 Eventually(session).Should(Exit(1)) 471 }) 472 }) 473 }) 474 }) 475 }) 476 })