github.com/arunkumar7540/cli@v6.45.0+incompatible/integration/v6/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]`)))
    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(`-i\s+The order in which the buildpacks are checked during buildpack auto-detection`))
    46  			Eventually(session).Should(Say(`--lock\s+Lock the buildpack to prevent updates`))
    47  			Eventually(session).Should(Say(`-p\s+Path to directory or zip file`))
    48  			Eventually(session).Should(Say(`--unlock\s+Unlock the buildpack to enable updates`))
    49  			Eventually(session).Should(Say(`-s\s+Specify stack to disambiguate buildpacks with the same name`))
    50  			Eventually(session).Should(Say("SEE ALSO:"))
    51  			Eventually(session).Should(Say("buildpacks, create-buildpack, delete-buildpack, rename-buildpack"))
    52  			Eventually(session).Should(Exit(0))
    53  		})
    54  	})
    55  
    56  	When("the environment is not setup correctly", func() {
    57  		It("fails with the appropriate errors", func() {
    58  			helpers.CheckEnvironmentTargetedCorrectly(false, false, ReadOnlyOrg, "update-buildpack", "fake-buildpack")
    59  		})
    60  	})
    61  
    62  	When("the user is logged in", func() {
    63  		BeforeEach(func() {
    64  			helpers.LoginCF()
    65  		})
    66  
    67  		AfterEach(func() {
    68  			helpers.DeleteBuildpackIfOnOldCCAPI(buildpackName)
    69  		})
    70  
    71  		When("the buildpack is not provided", func() {
    72  			It("returns a buildpack argument not provided error", func() {
    73  				session := helpers.CF("update-buildpack", "-p", ".")
    74  
    75  				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `BUILDPACK` was not provided"))
    76  				Eventually(session).Should(Exit(1))
    77  			})
    78  		})
    79  
    80  		When("the buildpack name is provided", func() {
    81  			When("the buildpack does not exist", func() {
    82  				It("returns a buildpack not found error", func() {
    83  					session := helpers.CF("update-buildpack", buildpackName)
    84  					Eventually(session.Err).Should(Say("Buildpack %s not found", buildpackName))
    85  					Eventually(session).Should(Say("FAILED"))
    86  					Eventually(session).Should(Exit(1))
    87  				})
    88  			})
    89  
    90  			Describe("stack association", func() {
    91  				var stacks []string
    92  
    93  				BeforeEach(func() {
    94  					helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2)
    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("--assign-stack is given", func() {
   182  						It("displays an error and exits", func() {
   183  							session := helpers.CF("update-buildpack", buildpackName, "--assign-stack", stacks[0])
   184  
   185  							Eventually(session.Err).Should(Say(`Buildpack %s already exists with a stack association`, buildpackName))
   186  							Eventually(session.Err).Should(Say(`TIP: Use 'cf buildpacks' to view buildpack and stack associations`))
   187  							Eventually(session).Should(Say("FAILED"))
   188  							Eventually(session).Should(Exit(1))
   189  						})
   190  					})
   191  
   192  					When("the user specifies a stack association not matching any of the existing buildpacks with this name", func() {
   193  						It("reports that it couldn't find the buildpack", func() {
   194  							nonexistentStack := "some-incorrect-stack-name"
   195  							session := helpers.CF("update-buildpack", buildpackName, "-s", nonexistentStack)
   196  
   197  							Eventually(session.Err).Should(Say("Buildpack %s with stack %s not found", buildpackName, nonexistentStack))
   198  							Eventually(session).Should(Say("FAILED"))
   199  							Eventually(session).Should(Exit(1))
   200  						})
   201  					})
   202  
   203  					When("the user specifies a stack association matching one of the existing buildpacks with this name", func() {
   204  						It("finds the buildpack with the stack specified (and not the buildpack with the nil stack)", func() {
   205  							session := helpers.CF("update-buildpack", buildpackName, "-s", stacks[0])
   206  
   207  							Eventually(session).Should(Say("Updating buildpack %s with stack %s as %s...",
   208  								buildpackName, stacks[0], username,
   209  							))
   210  							Eventually(session).Should(Say("OK"))
   211  							Eventually(session).Should(Exit(0))
   212  						})
   213  					})
   214  				})
   215  
   216  				When("one buildpack with the given name exists in enabled and unlocked state with a stack association", func() {
   217  					BeforeEach(func() {
   218  						helpers.BuildpackWithStack(func(buildpackArchive string) {
   219  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "99")
   220  							Eventually(createSession).Should(Exit(0))
   221  						}, stacks[0])
   222  
   223  						listSession := helpers.CF("buildpacks")
   224  						Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   225  							Name: buildpackName, Stack: stacks[0]})))
   226  						Eventually(listSession).Should(Exit(0))
   227  					})
   228  
   229  					When("no stack association is specified", func() {
   230  						It("updates the only buildpack with that name", func() {
   231  							session := helpers.CF("update-buildpack", buildpackName)
   232  
   233  							Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   234  							Eventually(session).Should(Say("OK"))
   235  							Eventually(session).Should(Exit(0))
   236  						})
   237  					})
   238  
   239  					When("the user specifies a stack association not matching any of the existing buildpacks with this name", func() {
   240  						It("reports that it couldn't find the buildpack", func() {
   241  							nonexistentStack := "some-incorrect-stack-name"
   242  							session := helpers.CF("update-buildpack", buildpackName, "-s", nonexistentStack)
   243  
   244  							Eventually(session.Err).Should(Say("Buildpack %s with stack %s not found", buildpackName, nonexistentStack))
   245  							Eventually(session).Should(Say("FAILED"))
   246  							Eventually(session).Should(Exit(1))
   247  						})
   248  					})
   249  
   250  					When("the user specifies a stack association matching one of the existing buildpacks with this name", func() {
   251  						It("finds the buildpack with the stack specified (and not the buildpack with the nil stack)", func() {
   252  							session := helpers.CF("update-buildpack", buildpackName, "-s", stacks[0])
   253  
   254  							Eventually(session).Should(Say("Updating buildpack %s with stack %s as %s...",
   255  								buildpackName, stacks[0], username,
   256  							))
   257  							Eventually(session).Should(Say("OK"))
   258  							Eventually(session).Should(Exit(0))
   259  						})
   260  					})
   261  				})
   262  			})
   263  
   264  			When("one buildpack with given name exists in enabled and unlocked state with no stack association", func() {
   265  				BeforeEach(func() {
   266  					helpers.BuildpackWithoutStack(func(buildpackArchive string) {
   267  						createSession := helpers.CF("create-buildpack", buildpackName, buildpackArchive, "99")
   268  						Eventually(createSession).Should(Exit(0))
   269  					})
   270  
   271  					listSession := helpers.CF("buildpacks")
   272  					Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: buildpackName})))
   273  					Eventually(listSession).Should(Exit(0))
   274  				})
   275  
   276  				When("only a name is provided", func() {
   277  					It("prints a success message", func() {
   278  						session := helpers.CF("update-buildpack", buildpackName)
   279  
   280  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   281  						Eventually(session).Should(Say("OK"))
   282  						Eventually(session).Should(Exit(0))
   283  					})
   284  				})
   285  
   286  				When("the -s flag is provided", func() {
   287  					var (
   288  						stackName string
   289  						session   *Session
   290  					)
   291  
   292  					JustBeforeEach(func() {
   293  						stackName = "some-stack"
   294  						session = helpers.CF("update-buildpack", buildpackName, "-s", stackName)
   295  					})
   296  
   297  					When("the targeted API does not support stack associations", func() {
   298  						BeforeEach(func() {
   299  							helpers.SkipIfVersionAtLeast(ccversion.MinVersionBuildpackStackAssociationV2)
   300  						})
   301  
   302  						It("fails with a minimum version error", func() {
   303  							Eventually(session.Err).Should(Say("Option '-s' requires CF API version %s or higher. Your target is %s.", ccversion.MinVersionBuildpackStackAssociationV2, helpers.GetAPIVersionV2()))
   304  							Eventually(session).Should(Say("FAILED"))
   305  							Eventually(session).Should(Exit(1))
   306  						})
   307  					})
   308  
   309  					When("the targeted API supports stack associations", func() {
   310  						BeforeEach(func() {
   311  							helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2)
   312  						})
   313  
   314  						It("returns a buildpack with stack not found error", func() {
   315  							Eventually(session.Err).Should(Say("Buildpack %s with stack %s not found", buildpackName, stackName))
   316  							Eventually(session).Should(Say("FAILED"))
   317  							Eventually(session).Should(Exit(1))
   318  						})
   319  					})
   320  				})
   321  
   322  				When("the -p flag is provided", func() {
   323  					var (
   324  						buildpackPath string
   325  						session       *Session
   326  					)
   327  
   328  					JustBeforeEach(func() {
   329  						session = helpers.CF("update-buildpack", buildpackName, "-p", buildpackPath)
   330  					})
   331  
   332  					When("the path is local", func() {
   333  						When("the buildpack path exists", func() {
   334  							When("the buildpack path is an empty directory", func() {
   335  								BeforeEach(func() {
   336  									var err error
   337  									buildpackPath, err = ioutil.TempDir("", "create-buildpack-test-")
   338  									Expect(err).ToNot(HaveOccurred())
   339  								})
   340  
   341  								AfterEach(func() {
   342  									err := os.RemoveAll(buildpackPath)
   343  									Expect(err).ToNot(HaveOccurred())
   344  								})
   345  
   346  								It("prints an error message", func() {
   347  									Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   348  									Eventually(session.Err).Should(Say("The specified path '%s' cannot be an empty directory.", regexp.QuoteMeta(buildpackPath)))
   349  									Eventually(session).Should(Exit(1))
   350  								})
   351  							})
   352  
   353  							When("uploading from a directory", func() {
   354  								BeforeEach(func() {
   355  									var err error
   356  									buildpackPath, err = ioutil.TempDir("", "create-buildpack-test-")
   357  									Expect(err).ToNot(HaveOccurred())
   358  									file, err := ioutil.TempFile(buildpackPath, "")
   359  									defer file.Close()
   360  									Expect(err).ToNot(HaveOccurred())
   361  								})
   362  
   363  								AfterEach(func() {
   364  									err := os.RemoveAll(buildpackPath)
   365  									Expect(err).ToNot(HaveOccurred())
   366  								})
   367  
   368  								It("updates the buildpack with the given bits", func() {
   369  									Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   370  									Eventually(session).Should(Say("OK"))
   371  									Eventually(session).Should(Exit(0))
   372  								})
   373  							})
   374  
   375  							When("uploading from a zip", func() {
   376  								BeforeEach(func() {
   377  									buildpackPath = helpers.MakeBuildpackArchive("")
   378  								})
   379  
   380  								AfterEach(func() {
   381  									err := os.Remove(buildpackPath)
   382  									Expect(err).NotTo(HaveOccurred())
   383  								})
   384  
   385  								It("updates the buildpack with the given bits", func() {
   386  									Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   387  									Eventually(session).Should(Say("OK"))
   388  									Eventually(session).Should(Exit(0))
   389  								})
   390  							})
   391  						})
   392  
   393  						When("the buildpack path does not exist", func() {
   394  							BeforeEach(func() {
   395  								buildpackPath = "this-is-a-bogus-path"
   396  							})
   397  
   398  							It("returns a buildpack does not exist error", func() {
   399  								Eventually(session.Err).Should(Say("Incorrect Usage: The specified path 'this-is-a-bogus-path' does not exist."))
   400  								Eventually(session).Should(Exit(1))
   401  							})
   402  						})
   403  					})
   404  
   405  					When("path is a URL", func() {
   406  						When("specifying a valid URL", func() {
   407  							BeforeEach(func() {
   408  								buildpackPath = "https://github.com/cloudfoundry/binary-buildpack/releases/download/v1.0.21/binary-buildpack-v1.0.21.zip"
   409  							})
   410  
   411  							It("successfully uploads a buildpack", func() {
   412  								Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   413  								Eventually(session).Should(Say("OK"))
   414  								Eventually(session).Should(Say("Uploading buildpack %s as %s...", buildpackName, username))
   415  								Eventually(session).Should(Say("OK"))
   416  								Eventually(session).Should(Exit(0))
   417  							})
   418  						})
   419  
   420  						When("a 4xx or 5xx HTTP response status is encountered", func() {
   421  							var server *Server
   422  
   423  							BeforeEach(func() {
   424  								server = NewServer()
   425  								// Suppresses ginkgo server logs
   426  								server.HTTPTestServer.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0)
   427  								server.AppendHandlers(
   428  									CombineHandlers(
   429  										VerifyRequest(http.MethodGet, "/"),
   430  										RespondWith(http.StatusNotFound, nil),
   431  									),
   432  								)
   433  								buildpackPath = server.URL()
   434  							})
   435  
   436  							AfterEach(func() {
   437  								server.Close()
   438  							})
   439  
   440  							It("displays an appropriate error", func() {
   441  								Eventually(session.Err).Should(Say("Download attempt failed; server returned 404 Not Found"))
   442  								Eventually(session.Err).Should(Say(`Unable to install; buildpack is not available from the given URL\.`))
   443  								Eventually(session).Should(Say("FAILED"))
   444  								Eventually(session).Should(Exit(1))
   445  							})
   446  						})
   447  
   448  						When("specifying an invalid URL", func() {
   449  							BeforeEach(func() {
   450  								buildpackPath = "http://not-a-real-url"
   451  							})
   452  
   453  							It("returns the appropriate error", func() {
   454  								Eventually(session.Err).Should(Say("Get %s: dial tcp: lookup", buildpackPath))
   455  								Eventually(session).Should(Say("FAILED"))
   456  								Eventually(session).Should(Exit(1))
   457  							})
   458  						})
   459  					})
   460  				})
   461  
   462  				When("the -i flag is provided", func() {
   463  					var (
   464  						buildpackPosition string
   465  						session           *Session
   466  					)
   467  
   468  					JustBeforeEach(func() {
   469  						session = helpers.CF("update-buildpack", buildpackName, "-i", buildpackPosition)
   470  					})
   471  
   472  					When("position is a negative integer", func() {
   473  						BeforeEach(func() {
   474  							buildpackPosition = "-3"
   475  						})
   476  
   477  						It("successfully uploads buildpack as the first position", func() {
   478  							Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   479  							Eventually(session).Should(Say("OK"))
   480  							Eventually(session).Should(Exit(0))
   481  
   482  							listSession := helpers.CF("buildpacks")
   483  							Eventually(listSession).Should(Say(`%s\s+1\s`, buildpackName))
   484  							Eventually(listSession).Should(Exit(0))
   485  						})
   486  					})
   487  
   488  					When("position is positive integer", func() {
   489  						BeforeEach(func() {
   490  							buildpackPosition = "3"
   491  						})
   492  
   493  						It("successfully uploads buildpack in the provided position", func() {
   494  							Eventually(session).Should(Exit(0))
   495  
   496  							listSession := helpers.CF("buildpacks")
   497  							Eventually(listSession).Should(Say(`%s\s+3\s`, buildpackName))
   498  							Eventually(listSession).Should(Exit(0))
   499  						})
   500  					})
   501  				})
   502  
   503  				When("the --assign-stack flag is provided", func() {
   504  					var (
   505  						stacks []string
   506  					)
   507  
   508  					BeforeEach(func() {
   509  						helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2)
   510  					})
   511  
   512  					When("the user assigns a stack that exists on the system", func() {
   513  						BeforeEach(func() {
   514  							stacks = helpers.EnsureMinimumNumberOfStacks(2)
   515  						})
   516  
   517  						It("successfully assigns the stack to the buildpack", func() {
   518  							session := helpers.CF("update-buildpack", buildpackName, "--assign-stack", stacks[0])
   519  
   520  							Eventually(session).Should(Say("Assigning stack %s to %s as %s...", stacks[0], buildpackName, username))
   521  							Eventually(session).Should(Say("OK"))
   522  							Eventually(session).Should(Exit(0))
   523  
   524  							listSession := helpers.CF("buildpacks")
   525  							Eventually(listSession).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   526  								Name: buildpackName, Stack: stacks[0]})))
   527  							Eventually(listSession).Should(Exit(0))
   528  						})
   529  
   530  						When("the buildpack already has a stack associated to it", func() {
   531  							BeforeEach(func() {
   532  								assignStackSession := helpers.CF("update-buildpack", buildpackName, "--assign-stack", stacks[0])
   533  								Eventually(assignStackSession).Should(Exit(0))
   534  							})
   535  
   536  							It("displays an error that the buildpack already has a stack association", func() {
   537  								session := helpers.CF("update-buildpack", buildpackName, "--assign-stack", stacks[1])
   538  								Eventually(session.Err).Should(Say("Buildpack %s already exists with a stack association", buildpackName))
   539  								Eventually(session).Should(Say("FAILED"))
   540  								Eventually(session).Should(Exit(1))
   541  							})
   542  						})
   543  					})
   544  
   545  					When("the user assigns a stack that does NOT exist on the system", func() {
   546  						It("displays an error that the stack isn't found", func() {
   547  							session := helpers.CF("update-buildpack", buildpackName, "--assign-stack", "nonexistent-stack")
   548  							Eventually(session.Err).Should(Say("Stack 'nonexistent-stack' not found"))
   549  							Eventually(session).Should(Say("FAILED"))
   550  							Eventually(session).Should(Exit(1))
   551  						})
   552  					})
   553  				})
   554  
   555  				When("the --lock is provided", func() {
   556  					It("locks the buildpack", func() {
   557  						session := helpers.CF("update-buildpack", buildpackName, "--lock")
   558  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   559  						Eventually(session).Should(Say("OK"))
   560  						Eventually(session).Should(Exit(0))
   561  
   562  						session = helpers.CF("buildpacks")
   563  						Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{
   564  							Name:   buildpackName,
   565  							Locked: "true",
   566  						})))
   567  						Eventually(session).Should(Exit(0))
   568  					})
   569  				})
   570  
   571  				When("the --disable is provided", func() {
   572  					It("disables buildpack", func() {
   573  						session := helpers.CF("update-buildpack", buildpackName, "--disable")
   574  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   575  						Eventually(session).Should(Say("OK"))
   576  						Eventually(session).Should(Exit(0))
   577  
   578  						session = helpers.CF("buildpacks")
   579  						Eventually(session).Should(Say(`%s\s+\d+\s+false`, buildpackName))
   580  						Eventually(session).Should(Exit(0))
   581  					})
   582  				})
   583  
   584  				Describe("flag combinations", func() {
   585  					When("specifying both enable and disable flags", func() {
   586  						It("returns the appropriate error", func() {
   587  							session := helpers.CF("update-buildpack", buildpackName, "--enable", "--disable")
   588  							Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: --enable, --disable"))
   589  							Eventually(session).Should(Say("FAILED"))
   590  							Eventually(session).Should(Exit(1))
   591  						})
   592  					})
   593  
   594  					When("specifying both lock and unlock flags", func() {
   595  						It("returns the appropriate error", func() {
   596  							session := helpers.CF("update-buildpack", buildpackName, "--lock", "--unlock")
   597  							Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: --lock, --unlock"))
   598  							Eventually(session).Should(Say("FAILED"))
   599  							Eventually(session).Should(Exit(1))
   600  						})
   601  					})
   602  
   603  					When("specifying --lock and -p", func() {
   604  						It("returns the an error saying that those flags cannot be used together", func() {
   605  							session := helpers.CF("update-buildpack", buildpackName, "--lock", "-p", "http://google.com")
   606  							Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: -p, --lock"))
   607  							Eventually(session).Should(Say("FAILED"))
   608  							Eventually(session).Should(Exit(1))
   609  						})
   610  					})
   611  
   612  					When("specifying --unlock and -p", func() {
   613  						It("returns the an error saying that those flags cannot be used together", func() {
   614  							session := helpers.CF("update-buildpack", buildpackName, "--unlock", "-p", "http://google.com")
   615  							Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: -p, --unlock"))
   616  							Eventually(session).Should(Say("FAILED"))
   617  							Eventually(session).Should(Exit(1))
   618  						})
   619  					})
   620  
   621  					When("specifying -s and --assign-stack", func() {
   622  						It("returns the an error saying that those flags cannot be used together", func() {
   623  							session := helpers.CF("update-buildpack", buildpackName, "-s", "old-stack", "--assign-stack", "some-new-stack")
   624  							Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: -s, --assign-stack"))
   625  							Eventually(session).Should(Say("FAILED"))
   626  							Eventually(session).Should(Exit(1))
   627  						})
   628  					})
   629  
   630  					When("specifying -p and --assign-stack", func() {
   631  						It("returns the an error saying that those flags cannot be used together", func() {
   632  							session := helpers.CF("update-buildpack", buildpackName, "-p", "http://google.com", "--assign-stack", "some-new-stack")
   633  							Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: -p, --assign-stack"))
   634  							Eventually(session).Should(Say("FAILED"))
   635  							Eventually(session).Should(Exit(1))
   636  						})
   637  					})
   638  
   639  					When("specifying -i and --assign-stack", func() {
   640  						BeforeEach(func() {
   641  							helpers.SkipIfVersionLessThan(ccversion.MinVersionBuildpackStackAssociationV2)
   642  						})
   643  
   644  						It("displays text that the stack is being assigned and the buildpack is being updated", func() {
   645  							stacks := helpers.EnsureMinimumNumberOfStacks(1)
   646  							newStack := stacks[0]
   647  							session := helpers.CF("update-buildpack", buildpackName, "-i", "99", "--assign-stack", newStack)
   648  							Eventually(session).Should(Say("Assigning stack %s to %s as %s...", newStack, buildpackName, username))
   649  							Eventually(session).Should(Say("Updating buildpack %s with stack %s...", buildpackName, newStack))
   650  							Eventually(session).Should(Say("OK"))
   651  							Eventually(session).Should(Exit(0))
   652  						})
   653  					})
   654  				})
   655  			})
   656  
   657  			When("the buildpack exists and is disabled", func() {
   658  				BeforeEach(func() {
   659  					helpers.BuildpackWithoutStack(func(buildpackPath string) {
   660  						session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1", "--disable")
   661  						Eventually(session).Should(Exit(0))
   662  					})
   663  				})
   664  
   665  				When("specifying enable flag", func() {
   666  					It("enables buildpack", func() {
   667  						session := helpers.CF("update-buildpack", buildpackName, "--enable")
   668  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   669  						Eventually(session).Should(Say("OK"))
   670  						Eventually(session).Should(Exit(0))
   671  
   672  						session = helpers.CF("buildpacks")
   673  						Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: buildpackName})))
   674  						Eventually(session).Should(Exit(0))
   675  					})
   676  				})
   677  			})
   678  
   679  			When("the buildpack exists and is locked", func() {
   680  				var buildpackURL string
   681  
   682  				BeforeEach(func() {
   683  					helpers.BuildpackWithoutStack(func(buildpackPath string) {
   684  						session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "1")
   685  						Eventually(session).Should(Exit(0))
   686  						session = helpers.CF("update-buildpack", buildpackName, "--lock")
   687  						Eventually(session).Should(Exit(0))
   688  					})
   689  					buildpackURL = "https://github.com/cloudfoundry/binary-buildpack/releases/download/v1.0.21/binary-buildpack-v1.0.21.zip"
   690  				})
   691  
   692  				Context("specifying -p argument", func() {
   693  					It("fails to update buildpack", func() {
   694  						session := helpers.CF("update-buildpack", buildpackName, "-p", buildpackURL)
   695  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   696  						Eventually(session).Should(Say("FAILED"))
   697  						Eventually(session.Err).Should(Say("The buildpack is locked"))
   698  						Eventually(session).Should(Exit(1))
   699  					})
   700  				})
   701  
   702  				Context("specifying unlock flag", func() {
   703  					It("unlocks the buildpack", func() {
   704  						session := helpers.CF("update-buildpack", buildpackName, "--unlock")
   705  						Eventually(session).Should(Say("Updating buildpack %s as %s...", buildpackName, username))
   706  						Eventually(session).Should(Say("OK"))
   707  						Eventually(session).Should(Exit(0))
   708  
   709  						session = helpers.CF("buildpacks")
   710  						Eventually(session).Should(Say(helpers.BuildpacksOutputRegex(helpers.BuildpackFields{Name: buildpackName})))
   711  						Eventually(session).Should(Exit(0))
   712  					})
   713  				})
   714  			})
   715  		})
   716  	})
   717  })