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