github.com/wanddynosios/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  })