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