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