github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/integration/v7/global/update_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("update-buildpack command", func() {
    21  	var (
    22  		buildpackName string
    23  		username      string
    24  	)
    25  
    26  	BeforeEach(func() {
    27  		buildpackName = helpers.NewBuildpackName()
    28  		username, _ = helpers.GetCredentials()
    29  	})
    30  
    31  	When("--help flag is set", func() {
    32  		It("Displays command usage to output", func() {
    33  			session := helpers.CF("update-buildpack", "--help")
    34  			Eventually(session).Should(Say("NAME:"))
    35  			Eventually(session).Should(Say("update-buildpack - Update a buildpack"))
    36  			Eventually(session).Should(Say("USAGE:"))
    37  			Eventually(session).Should(Say(regexp.QuoteMeta(`cf update-buildpack BUILDPACK [-p PATH | -s STACK | --assign-stack NEW_STACK] [-i POSITION] [--enable|--disable] [--lock|--unlock] [--rename]`)))
    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.\n\n"))
    40  			Eventually(session).Should(Say("Use '--assign-stack' with caution. Associating a buildpack with a stack that it does not support may result in undefined behavior. Additionally, changing this association once made may require a local copy of the buildpack.\n\n"))
    41  			Eventually(session).Should(Say("OPTIONS:"))
    42  			Eventually(session).Should(Say(`--assign-stack\s+Assign a stack to a buildpack that does not have a stack association`))
    43  			Eventually(session).Should(Say(`--disable\s+Disable the buildpack from being used for staging`))
    44  			Eventually(session).Should(Say(`--enable\s+Enable the buildpack to be used for staging`))
    45  			Eventually(session).Should(Say(`--lock\s+Lock the buildpack to prevent updates`))
    46  			Eventually(session).Should(Say(`--path, -p\s+Path to directory or zip file`))
    47  			Eventually(session).Should(Say(`--position, -i\s+The order in which the buildpacks are checked during buildpack auto-detection`))
    48  			Eventually(session).Should(Say(`--rename\s+Rename an existing buildpack`))
    49  			Eventually(session).Should(Say(`--stack, -s\s+Specify stack to disambiguate buildpacks with the same name`))
    50  			Eventually(session).Should(Say(`--unlock\s+Unlock the buildpack to enable updates`))
    51  			Eventually(session).Should(Say("SEE ALSO:"))
    52  			Eventually(session).Should(Say("buildpacks, create-buildpack, delete-buildpack"))
    53  			Eventually(session).Should(Exit(0))
    54  		})
    55  	})
    56  
    57  	When("the environment is not setup correctly", func() {
    58  		It("fails with the appropriate errors", func() {
    59  			helpers.CheckEnvironmentTargetedCorrectly(false, false, ReadOnlyOrg, "update-buildpack", "fake-buildpack")
    60  		})
    61  	})
    62  
    63  	When("the user is logged in", func() {
    64  		BeforeEach(func() {
    65  			helpers.LoginCF()
    66  		})
    67  
    68  		AfterEach(func() {
    69  			helpers.DeleteBuildpackIfOnOldCCAPI(buildpackName)
    70  		})
    71  
    72  		When("the buildpack is not provided", func() {
    73  			It("returns a buildpack argument not provided error", func() {
    74  				session := helpers.CF("update-buildpack", "-p", ".")
    75  
    76  				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `BUILDPACK` was not provided"))
    77  				Eventually(session).Should(Exit(1))
    78  			})
    79  		})
    80  
    81  		When("the buildpack name is provided", func() {
    82  			When("the buildpack does not exist", func() {
    83  				It("returns a buildpack not found error", func() {
    84  					session := helpers.CF("update-buildpack", buildpackName)
    85  					Eventually(session.Err).Should(Say("Buildpack %s not found", buildpackName))
    86  					Eventually(session).Should(Say("FAILED"))
    87  					Eventually(session).Should(Exit(1))
    88  				})
    89  			})
    90  
    91  			Describe("stack association", func() {
    92  				var stacks []string
    93  
    94  				BeforeEach(func() {
    95  					stacks = helpers.EnsureMinimumNumberOfStacks(2)
    96  				})
    97  
    98  				When("multiple buildpacks with the same name exist in enabled and unlocked state, and one has nil stack", func() {
    99  					BeforeEach(func() {
   100  						helpers.BuildpackWithStack(func(buildpackArchive string) {
   101  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "99")
   102  							Eventually(createSession).Should(Exit(0))
   103  						}, stacks[0])
   104  
   105  						helpers.BuildpackWithoutStack(func(buildpackArchive string) {
   106  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "100")
   107  							Eventually(createSession).Should(Exit(0))
   108  						})
   109  
   110  						listSession := helpers.CF("buildpacks")
   111  						Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   112  							Name: buildpackName, Stack: stacks[0]})))
   113  						Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: buildpackName})))
   114  						Eventually(listSession).Should(Exit(0))
   115  					})
   116  
   117  					When("no stack association is specified", func() {
   118  						It("acts on the buildpack with the nil stack", func() {
   119  							session := helpers.CF("update-buildpack", buildpackName)
   120  
   121  							Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   122  							Eventually(session).Should(Say("OK"))
   123  							Eventually(session).Should(Exit(0))
   124  						})
   125  					})
   126  
   127  					When("the user specifies a stack association not matching any of the existing buildpacks with this name", func() {
   128  						It("reports that it couldn't find the buildpack", func() {
   129  							nonexistentStack := "some-incorrect-stack-name"
   130  							session := helpers.CF("update-buildpack", buildpackName, "-s", nonexistentStack)
   131  
   132  							Eventually(session.Err).Should(Say("Buildpack %s with stack %s not found", buildpackName, nonexistentStack))
   133  							Eventually(session).Should(Say("FAILED"))
   134  							Eventually(session).Should(Exit(1))
   135  						})
   136  					})
   137  
   138  					When("the user specifies a stack association matching one of the existing buildpacks with this name", func() {
   139  						It("finds the buildpack with the stack specified (and not the buildpack with the nil stack)", func() {
   140  							session := helpers.CF("update-buildpack", buildpackName, "-s", stacks[0])
   141  
   142  							Eventually(session).Should(Say("Updating buildpack %s with stack %s as %s...",
   143  								buildpackName, stacks[0], username,
   144  							))
   145  							Eventually(session).Should(Say("OK"))
   146  							Eventually(session).Should(Exit(0))
   147  						})
   148  					})
   149  				})
   150  
   151  				When("multiple buildpacks with the same name exist in enabled and unlocked state, and all have stacks", func() {
   152  					BeforeEach(func() {
   153  						helpers.BuildpackWithStack(func(buildpackArchive string) {
   154  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "98")
   155  							Eventually(createSession).Should(Exit(0))
   156  						}, stacks[0])
   157  
   158  						helpers.BuildpackWithStack(func(buildpackArchive string) {
   159  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "99")
   160  							Eventually(createSession).Should(Exit(0))
   161  						}, stacks[1])
   162  
   163  						listSession := helpers.CF("buildpacks")
   164  						Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   165  							Name: buildpackName, Stack: stacks[0]})))
   166  						Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   167  							Name: buildpackName, Stack: stacks[1]})))
   168  						Eventually(listSession).Should(Exit(0))
   169  					})
   170  
   171  					When("no stack association is specified", func() {
   172  						It("displays an error saying that multiple buildpacks were found", func() {
   173  							session := helpers.CF("update-buildpack", buildpackName)
   174  
   175  							Eventually(session.Err).Should(Say(`Multiple buildpacks named %s found\. Specify a stack name by using a '-s' flag\.`, buildpackName))
   176  							Eventually(session).Should(Say("FAILED"))
   177  							Eventually(session).Should(Exit(1))
   178  						})
   179  					})
   180  
   181  					When("the user specifies a stack association not matching any of the existing buildpacks with this name", func() {
   182  						It("reports that it couldn't find the buildpack", func() {
   183  							nonexistentStack := "some-incorrect-stack-name"
   184  							session := helpers.CF("update-buildpack", buildpackName, "-s", nonexistentStack)
   185  
   186  							Eventually(session.Err).Should(Say("Buildpack %s with stack %s not found", buildpackName, nonexistentStack))
   187  							Eventually(session).Should(Say("FAILED"))
   188  							Eventually(session).Should(Exit(1))
   189  						})
   190  					})
   191  
   192  					When("the user specifies a stack association matching one of the existing buildpacks with this name", func() {
   193  						It("finds the buildpack with the stack specified (and not the buildpack with the other stack)", func() {
   194  							session := helpers.CF("update-buildpack", buildpackName, "-s", stacks[0])
   195  
   196  							Eventually(session).Should(Say("Updating buildpack %s with stack %s as %s...",
   197  								buildpackName, stacks[0], username,
   198  							))
   199  							Eventually(session).Should(Say("OK"))
   200  							Eventually(session).Should(Exit(0))
   201  						})
   202  					})
   203  				})
   204  
   205  				When("one buildpack with the given name exists in enabled and unlocked state with a stack association", func() {
   206  					BeforeEach(func() {
   207  						helpers.BuildpackWithStack(func(buildpackArchive string) {
   208  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "99")
   209  							Eventually(createSession).Should(Exit(0))
   210  						}, stacks[0])
   211  
   212  						listSession := helpers.CF("buildpacks")
   213  						Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   214  							Name: buildpackName, Stack: stacks[0]})))
   215  						Eventually(listSession).Should(Exit(0))
   216  					})
   217  
   218  					When("no stack association is specified", func() {
   219  						It("updates the only buildpack with that name", func() {
   220  							session := helpers.CF("update-buildpack", buildpackName)
   221  
   222  							Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   223  							Eventually(session).Should(Say("OK"))
   224  							Eventually(session).Should(Exit(0))
   225  						})
   226  					})
   227  
   228  					When("the user specifies a stack association matching the buildpack with this name", func() {
   229  						It("finds the buildpack with the stack specified", func() {
   230  							session := helpers.CF("update-buildpack", buildpackName, "-s", stacks[0])
   231  
   232  							Eventually(session).Should(Say("Updating buildpack %s with stack %s as %s...",
   233  								buildpackName, stacks[0], username,
   234  							))
   235  							Eventually(session).Should(Say("OK"))
   236  							Eventually(session).Should(Exit(0))
   237  						})
   238  					})
   239  				})
   240  			})
   241  
   242  			When("one buildpack with given name exists in enabled and unlocked state with no stack association", func() {
   243  				BeforeEach(func() {
   244  					helpers.BuildpackWithoutStack(func(buildpackArchive string) {
   245  						createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "99")
   246  						Eventually(createSession).Should(Exit(0))
   247  					})
   248  
   249  					listSession := helpers.CF("buildpacks")
   250  					Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: buildpackName})))
   251  					Eventually(listSession).Should(Exit(0))
   252  				})
   253  
   254  				When("only a name is provided", func() {
   255  					It("prints a success message", func() {
   256  						session := helpers.CF("update-buildpack", buildpackName)
   257  
   258  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   259  						Eventually(session).Should(Say("OK"))
   260  						Eventually(session).Should(Exit(0))
   261  					})
   262  				})
   263  
   264  				When("the -s flag is provided", func() {
   265  					var (
   266  						stackName string
   267  						session   *Session
   268  					)
   269  
   270  					JustBeforeEach(func() {
   271  						stackName = "some-stack"
   272  						session = helpers.CF("update-buildpack", buildpackName, "-s", stackName)
   273  					})
   274  
   275  					It("returns a buildpack with stack not found error", func() {
   276  						Eventually(session.Err).Should(Say("Buildpack %s with stack %s not found", buildpackName, stackName))
   277  						Eventually(session).Should(Say("FAILED"))
   278  						Eventually(session).Should(Exit(1))
   279  					})
   280  				})
   281  
   282  				When("the -p flag is provided", func() {
   283  					var (
   284  						buildpackPath string
   285  						session       *Session
   286  					)
   287  
   288  					JustBeforeEach(func() {
   289  						session = helpers.CF("update-buildpack", buildpackName, "-p", buildpackPath)
   290  					})
   291  
   292  					When("the path is local", func() {
   293  						When("the buildpack path exists", func() {
   294  							When("the buildpack path is an empty directory", func() {
   295  								BeforeEach(func() {
   296  									var err error
   297  									buildpackPath, err = ioutil.TempDir("", "create-buildpack-test-")
   298  									Expect(err).ToNot(HaveOccurred())
   299  								})
   300  
   301  								AfterEach(func() {
   302  									err := os.RemoveAll(buildpackPath)
   303  									Expect(err).ToNot(HaveOccurred())
   304  								})
   305  
   306  								It("prints an error message", func() {
   307  									Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   308  									Eventually(session.Err).Should(Say("The specified path '%s' cannot be an empty directory.", regexp.QuoteMeta(buildpackPath)))
   309  									Eventually(session).Should(Exit(1))
   310  								})
   311  							})
   312  
   313  							When("the path is a buildpack directory", func() {
   314  								BeforeEach(func() {
   315  									var err error
   316  									buildpackPath, err = ioutil.TempDir("", "create-buildpack-test-")
   317  									Expect(err).ToNot(HaveOccurred())
   318  									file, err := ioutil.TempFile(buildpackPath, "")
   319  									defer file.Close()
   320  									Expect(err).ToNot(HaveOccurred())
   321  								})
   322  
   323  								AfterEach(func() {
   324  									err := os.RemoveAll(buildpackPath)
   325  									Expect(err).ToNot(HaveOccurred())
   326  								})
   327  
   328  								It("updates the buildpack with the given bits", func() {
   329  									Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   330  									Eventually(session).Should(Say("OK"))
   331  									Eventually(session).Should(Exit(0))
   332  								})
   333  							})
   334  
   335  							When("uploading from a zip", func() {
   336  								BeforeEach(func() {
   337  									buildpackPath = helpers.MakeBuildpackArchive("")
   338  								})
   339  
   340  								AfterEach(func() {
   341  									err := os.Remove(buildpackPath)
   342  									Expect(err).NotTo(HaveOccurred())
   343  								})
   344  
   345  								It("updates the buildpack with the given bits", func() {
   346  									Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   347  									Eventually(session).Should(Say("OK"))
   348  									Eventually(session).Should(Exit(0))
   349  								})
   350  							})
   351  						})
   352  
   353  						When("the buildpack path does not exist", func() {
   354  							BeforeEach(func() {
   355  								buildpackPath = "this-is-a-bogus-path"
   356  							})
   357  
   358  							It("returns a buildpack does not exist error", func() {
   359  								Eventually(session.Err).Should(Say("Incorrect Usage: The specified path 'this-is-a-bogus-path' does not exist."))
   360  								Eventually(session).Should(Exit(1))
   361  							})
   362  						})
   363  					})
   364  
   365  					When("path is a URL", func() {
   366  						When("specifying a valid URL", func() {
   367  							BeforeEach(func() {
   368  								buildpackPath = "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  								Eventually(session).Should(Say("Updating 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("OK"))
   376  								Eventually(session).Should(Exit(0))
   377  							})
   378  						})
   379  
   380  						When("a 4xx or 5xx HTTP response status is encountered", func() {
   381  							var server *Server
   382  
   383  							BeforeEach(func() {
   384  								server = NewServer()
   385  								// Suppresses ginkgo server logs
   386  								server.HTTPTestServer.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0)
   387  								server.AppendHandlers(
   388  									CombineHandlers(
   389  										VerifyRequest(http.MethodGet, "/"),
   390  										RespondWith(http.StatusNotFound, nil),
   391  									),
   392  								)
   393  								buildpackPath = server.URL()
   394  							})
   395  
   396  							AfterEach(func() {
   397  								server.Close()
   398  							})
   399  
   400  							It("displays an appropriate error", func() {
   401  								Eventually(session.Err).Should(Say("Download attempt failed; server returned 404 Not Found"))
   402  								Eventually(session.Err).Should(Say(`Unable to install; buildpack is not available from the given URL\.`))
   403  								Eventually(session).Should(Say("FAILED"))
   404  								Eventually(session).Should(Exit(1))
   405  							})
   406  						})
   407  
   408  						When("specifying an invalid URL", func() {
   409  							BeforeEach(func() {
   410  								buildpackPath = "http://not-a-real-url"
   411  							})
   412  
   413  							It("returns the appropriate error", func() {
   414  								Eventually(session.Err).Should(Say("Get %s: dial tcp: lookup", buildpackPath))
   415  								Eventually(session).Should(Say("FAILED"))
   416  								Eventually(session).Should(Exit(1))
   417  							})
   418  						})
   419  					})
   420  				})
   421  
   422  				When("the -i flag is provided", func() {
   423  					// TODO: These are tests that require global integration scoping, break these into their own test and isolate the others
   424  					var (
   425  						buildpackPosition string
   426  						session           *Session
   427  					)
   428  
   429  					JustBeforeEach(func() {
   430  						session = helpers.CF("update-buildpack", buildpackName, "-i", buildpackPosition)
   431  					})
   432  
   433  					When("position is a negative integer", func() {
   434  						BeforeEach(func() {
   435  							buildpackPosition = "-3"
   436  						})
   437  
   438  						It("fails with error that position must be at least 1", func() {
   439  							Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   440  							Eventually(session.Err).Should(Say("Position must be greater than or equal to 1"))
   441  							Eventually(session).Should(Exit(1))
   442  						})
   443  					})
   444  
   445  					When("position is positive integer", func() {
   446  						BeforeEach(func() {
   447  							buildpackPosition = "3"
   448  						})
   449  
   450  						It("successfully uploads buildpack in the provided position", func() {
   451  							Eventually(session).Should(Exit(0))
   452  
   453  							listSession := helpers.CF("buildpacks")
   454  							Eventually(listSession).Should(Say(`\s+3\s+%s`, buildpackName))
   455  							Eventually(listSession).Should(Exit(0))
   456  						})
   457  					})
   458  				})
   459  
   460  				When("the --assign-stack flag is provided", func() {
   461  					var (
   462  						stacks []string
   463  					)
   464  
   465  					BeforeEach(func() {
   466  						helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2)
   467  					})
   468  
   469  					When("the user assigns a stack that exists on the system", func() {
   470  						BeforeEach(func() {
   471  							stacks = helpers.EnsureMinimumNumberOfStacks(2)
   472  						})
   473  
   474  						It("successfully assigns the stack to the buildpack", func() {
   475  							session := helpers.CF("update-buildpack", buildpackName, "--assign-stack", stacks[0])
   476  
   477  							Eventually(session).Should(Say("Assigning stack %s to %s as %s...", stacks[0], buildpackName, username))
   478  							Eventually(session).Should(Say("OK"))
   479  							Eventually(session).Should(Exit(0))
   480  
   481  							listSession := helpers.CF("buildpacks")
   482  							Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   483  								Name: buildpackName, Stack: stacks[0]})))
   484  							Eventually(listSession).Should(Exit(0))
   485  						})
   486  
   487  						When("the buildpack already has a stack associated to it", func() {
   488  							BeforeEach(func() {
   489  								assignStackSession := helpers.CF("update-buildpack", buildpackName, "--assign-stack", stacks[0])
   490  								Eventually(assignStackSession).Should(Exit(0))
   491  							})
   492  
   493  							It("displays an error that the buildpack already has a stack association", func() {
   494  								session := helpers.CF("update-buildpack", buildpackName, "--assign-stack", stacks[1])
   495  								Eventually(session.Err).Should(Say("Buildpack stack can not be changed"))
   496  								Eventually(session).Should(Say("FAILED"))
   497  								Eventually(session).Should(Exit(1))
   498  							})
   499  						})
   500  					})
   501  
   502  					When("the user assigns a stack that does NOT exist on the system", func() {
   503  						It("displays an error that the stack isn't found", func() {
   504  							session := helpers.CF("update-buildpack", buildpackName, "--assign-stack", "nonexistent-stack")
   505  							Eventually(session.Err).Should(Say("Stack 'nonexistent-stack' does not exist"))
   506  							Eventually(session).Should(Say("FAILED"))
   507  							Eventually(session).Should(Exit(1))
   508  						})
   509  					})
   510  				})
   511  
   512  				When("the --lock is provided", func() {
   513  					It("locks the buildpack", func() {
   514  						session := helpers.CF("update-buildpack", buildpackName, "--lock")
   515  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   516  						Eventually(session).Should(Say("OK"))
   517  						Eventually(session).Should(Exit(0))
   518  
   519  						session = helpers.CF("buildpacks")
   520  						Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   521  							Name:   buildpackName,
   522  							Locked: "true",
   523  						})))
   524  						Eventually(session).Should(Exit(0))
   525  					})
   526  				})
   527  
   528  				When("the --disable is provided", func() {
   529  					It("disables buildpack", func() {
   530  						session := helpers.CF("update-buildpack", buildpackName, "--disable")
   531  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   532  						Eventually(session).Should(Say("OK"))
   533  						Eventually(session).Should(Exit(0))
   534  
   535  						session = helpers.CF("buildpacks")
   536  						Eventually(session).Should(Say(`%s\s+false`, buildpackName))
   537  						Eventually(session).Should(Exit(0))
   538  					})
   539  				})
   540  
   541  				When("the --rename flag is provided", func() {
   542  					var (
   543  						newBuildpackName string
   544  					)
   545  
   546  					BeforeEach(func() {
   547  						newBuildpackName = helpers.NewBuildpackName()
   548  					})
   549  
   550  					When("a buildpack with the new name does not already exist", func() {
   551  						It("renames the buildpack", func() {
   552  							session := helpers.CF("update-buildpack", buildpackName, "--rename", newBuildpackName)
   553  							Eventually(session).Should(Say("Renaming buildpack %s to %s as %s...", buildpackName, newBuildpackName, username))
   554  							Eventually(session).Should(Say("OK"))
   555  							Eventually(session).Should(Exit(0))
   556  
   557  							session = helpers.CF("buildpacks")
   558  							Eventually(session).Should(Say(`%s`, newBuildpackName))
   559  							Eventually(session).ShouldNot(Say(`%s`, buildpackName))
   560  							Eventually(session).Should(Exit(0))
   561  						})
   562  					})
   563  
   564  					When("a buildpack with the new name already exists", func() {
   565  						BeforeEach(func() {
   566  							helpers.BuildpackWithoutStack(func(buildpackArchive string) {
   567  								createSession := helpers.CF("create-buildpack", newBuildpackName, buildpackArchive, "99")
   568  								Eventually(createSession).Should(Exit(0))
   569  							})
   570  
   571  							listSession := helpers.CF("buildpacks")
   572  							Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: newBuildpackName})))
   573  							Eventually(listSession).Should(Exit(0))
   574  						})
   575  
   576  						It("fails to rename the buildpack", func() {
   577  							session := helpers.CF("update-buildpack", buildpackName, "--rename", newBuildpackName)
   578  							Eventually(session.Err).Should(Say("Buildpack with name '%s' and an unassigned stack already exists", newBuildpackName))
   579  							Eventually(session).Should(Say("FAILED"))
   580  							Eventually(session).Should(Exit(1))
   581  						})
   582  					})
   583  				})
   584  			})
   585  
   586  			When("the buildpack exists and is disabled", func() {
   587  				BeforeEach(func() {
   588  					helpers.BuildpackWithoutStack(func(buildpackPath string) {
   589  						session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1", "--disable")
   590  						Eventually(session).Should(Exit(0))
   591  					})
   592  				})
   593  
   594  				When("specifying enable flag", func() {
   595  					It("enables buildpack", func() {
   596  						session := helpers.CF("update-buildpack", buildpackName, "--enable")
   597  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   598  						Eventually(session).Should(Say("OK"))
   599  						Eventually(session).Should(Exit(0))
   600  
   601  						session = helpers.CF("buildpacks")
   602  						Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: buildpackName})))
   603  						Eventually(session).Should(Exit(0))
   604  					})
   605  				})
   606  			})
   607  
   608  			When("the buildpack exists and is locked", func() {
   609  				var buildpackURL string
   610  
   611  				BeforeEach(func() {
   612  					helpers.BuildpackWithoutStack(func(buildpackPath string) {
   613  						session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1")
   614  						Eventually(session).Should(Exit(0))
   615  						session = helpers.CF("update-buildpack", buildpackName, "--lock")
   616  						Eventually(session).Should(Exit(0))
   617  					})
   618  					buildpackURL = "https://github.com/cloudfoundry/binary-buildpack/releases/download/v1.0.21/binary-buildpack-v1.0.21.zip"
   619  				})
   620  
   621  				Context("specifying -p argument", func() {
   622  					It("fails to update buildpack", func() {
   623  						session := helpers.CF("update-buildpack", buildpackName, "-p", buildpackURL)
   624  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   625  						Eventually(session).Should(Say("FAILED"))
   626  						Eventually(session.Err).Should(Say("Buildpack is locked"))
   627  						Eventually(session).Should(Exit(1))
   628  					})
   629  				})
   630  
   631  				Context("specifying unlock flag", func() {
   632  					It("unlocks the buildpack", func() {
   633  						session := helpers.CF("update-buildpack", buildpackName, "--unlock")
   634  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   635  						Eventually(session).Should(Say("OK"))
   636  						Eventually(session).Should(Exit(0))
   637  
   638  						session = helpers.CF("buildpacks")
   639  						Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: buildpackName})))
   640  						Eventually(session).Should(Exit(0))
   641  					})
   642  				})
   643  			})
   644  		})
   645  	})
   646  })