github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/command/v7/update_buildpack_command_test.go (about)

     1  package v7_test
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/actor/v7action"
     5  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     6  	"code.cloudfoundry.org/cli/command/v7/v7fakes"
     7  	"code.cloudfoundry.org/cli/types"
     8  	"errors"
     9  
    10  	"code.cloudfoundry.org/cli/command/translatableerror"
    11  
    12  	"code.cloudfoundry.org/cli/actor/actionerror"
    13  	"code.cloudfoundry.org/cli/command/commandfakes"
    14  	"code.cloudfoundry.org/cli/command/flag"
    15  	. "code.cloudfoundry.org/cli/command/v7"
    16  	"code.cloudfoundry.org/cli/util/configv3"
    17  	"code.cloudfoundry.org/cli/util/ui"
    18  	. "github.com/onsi/ginkgo"
    19  	. "github.com/onsi/gomega"
    20  	. "github.com/onsi/gomega/gbytes"
    21  )
    22  
    23  var _ = Describe("UpdateBuildpackCommand", func() {
    24  	var (
    25  		cmd             UpdateBuildpackCommand
    26  		fakeSharedActor *commandfakes.FakeSharedActor
    27  		testUI          *ui.UI
    28  		input           *Buffer
    29  		fakeActor       *v7fakes.FakeUpdateBuildpackActor
    30  		fakeConfig      *commandfakes.FakeConfig
    31  		buildpackGUID   = "buildpack-guid"
    32  		buildpackName   = "some-bp"
    33  		binaryName      = "faceman"
    34  
    35  		executeErr  error
    36  		expectedErr error
    37  	)
    38  
    39  	BeforeEach(func() {
    40  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    41  		input = NewBuffer()
    42  		testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer())
    43  		fakeActor = new(v7fakes.FakeUpdateBuildpackActor)
    44  		fakeConfig = new(commandfakes.FakeConfig)
    45  		buildpackGUID = "some guid"
    46  
    47  		cmd = UpdateBuildpackCommand{
    48  			RequiredArgs: flag.BuildpackName{Buildpack: buildpackName},
    49  			UI:           testUI,
    50  			SharedActor:  fakeSharedActor,
    51  			Actor:        fakeActor,
    52  			Config:       fakeConfig,
    53  		}
    54  	})
    55  
    56  	JustBeforeEach(func() {
    57  		executeErr = cmd.Execute(nil)
    58  	})
    59  
    60  	Describe("invalid flag combinations", func() {
    61  		When("the --lock and --unlock flags are provided", func() {
    62  			BeforeEach(func() {
    63  				cmd.Lock = true
    64  				cmd.Unlock = true
    65  			})
    66  
    67  			It("returns an ArgumentCombinationError", func() {
    68  				Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{
    69  					Args: []string{"--lock", "--unlock"},
    70  				}))
    71  			})
    72  		})
    73  
    74  		When("the --enable and --disable flags are provided", func() {
    75  			BeforeEach(func() {
    76  				cmd.Enable = true
    77  				cmd.Disable = true
    78  			})
    79  
    80  			It("returns an ArgumentCombinationError", func() {
    81  				Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{
    82  					Args: []string{"--enable", "--disable"},
    83  				}))
    84  			})
    85  		})
    86  
    87  		When("the --path and --lock flags are provided", func() {
    88  			BeforeEach(func() {
    89  				cmd.Lock = true
    90  				cmd.Path = "asdf"
    91  			})
    92  
    93  			It("returns an ArgumentCombinationError", func() {
    94  				Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{
    95  					Args: []string{"--path", "--lock"},
    96  				}))
    97  			})
    98  		})
    99  
   100  		When("the --path and --assign-stack flags are provided", func() {
   101  			BeforeEach(func() {
   102  				cmd.Path = "asdf"
   103  				cmd.NewStack = "some-new-stack"
   104  			})
   105  
   106  			It("returns an ArgumentCombinationError", func() {
   107  				Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{
   108  					Args: []string{"--path", "--assign-stack"},
   109  				}))
   110  			})
   111  		})
   112  
   113  		When("the --stack and --assign-stack flags are provided", func() {
   114  			BeforeEach(func() {
   115  				cmd.CurrentStack = "current-stack"
   116  				cmd.NewStack = "some-new-stack"
   117  			})
   118  
   119  			It("returns an ArgumentCombinationError", func() {
   120  				Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{
   121  					Args: []string{"--stack", "--assign-stack"},
   122  				}))
   123  			})
   124  		})
   125  	})
   126  
   127  	When("the environment is not set up correctly", func() {
   128  		BeforeEach(func() {
   129  			fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
   130  		})
   131  
   132  		It("returns an error", func() {
   133  			Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName}))
   134  
   135  			Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   136  			checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   137  			Expect(checkTargetedOrg).To(BeFalse())
   138  			Expect(checkTargetedSpace).To(BeFalse())
   139  		})
   140  	})
   141  
   142  	When("the environment is setup correctly", func() {
   143  		When("getting the current user fails", func() {
   144  			BeforeEach(func() {
   145  				expectedErr = errors.New("some-error that happened")
   146  				fakeConfig.CurrentUserReturns(configv3.User{}, expectedErr)
   147  			})
   148  
   149  			It("returns the error", func() {
   150  				Expect(executeErr).To(MatchError(expectedErr))
   151  			})
   152  		})
   153  
   154  		When("getting the current user succeeds", func() {
   155  			var userName string
   156  
   157  			BeforeEach(func() {
   158  				userName = "some-user"
   159  				fakeConfig.CurrentUserReturns(configv3.User{Name: userName}, nil)
   160  			})
   161  
   162  			When("preparing buildpack bits causes an error", func() {
   163  				var emptyDirectoryError error
   164  				BeforeEach(func() {
   165  					emptyDirectoryError = actionerror.EmptyBuildpackDirectoryError{Path: "some-directory"}
   166  					fakeActor.PrepareBuildpackBitsReturns("", emptyDirectoryError)
   167  					cmd.Path = "some empty directory"
   168  				})
   169  
   170  				It("exits without updating if the path points to an empty directory", func() {
   171  					Expect(executeErr).To(MatchError(emptyDirectoryError))
   172  					Expect(fakeActor.UpdateBuildpackByNameAndStackCallCount()).To(Equal(0))
   173  				})
   174  			})
   175  
   176  			When("updating the buildpack fails", func() {
   177  				BeforeEach(func() {
   178  					cmd.Path = "path/to/buildpack"
   179  					fakeActor.PrepareBuildpackBitsReturns("path/to/prepared/bits", nil)
   180  					expectedErr = errors.New("update-error")
   181  					fakeActor.UpdateBuildpackByNameAndStackReturns(
   182  						v7action.Buildpack{},
   183  						v7action.Warnings{"update-bp-warning1", "update-bp-warning2"},
   184  						expectedErr,
   185  					)
   186  				})
   187  
   188  				It("returns the error and prints any warnings", func() {
   189  					Expect(testUI.Err).To(Say("update-bp-warning1"))
   190  					Expect(testUI.Err).To(Say("update-bp-warning2"))
   191  					Expect(executeErr).To(MatchError(expectedErr))
   192  					Expect(fakeActor.UploadBuildpackCallCount()).To(Equal(0))
   193  				})
   194  			})
   195  
   196  			When("the --lock flag is provided", func() {
   197  				BeforeEach(func() {
   198  					cmd.Lock = true
   199  				})
   200  
   201  				It("sets the locked value to true when updating the buildpack", func() {
   202  					Expect(executeErr).ToNot(HaveOccurred())
   203  					_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   204  					Expect(buildpack.Locked.IsSet).To(Equal(true))
   205  					Expect(buildpack.Locked.Value).To(Equal(true))
   206  				})
   207  			})
   208  
   209  			When("the --unlock flag is provided", func() {
   210  				BeforeEach(func() {
   211  					cmd.Unlock = true
   212  				})
   213  
   214  				It("sets the locked value to false when updating the buildpack", func() {
   215  					Expect(executeErr).ToNot(HaveOccurred())
   216  					_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   217  					Expect(buildpack.Locked.IsSet).To(Equal(true))
   218  					Expect(buildpack.Locked.Value).To(Equal(false))
   219  				})
   220  			})
   221  
   222  			When("the --enable flag is provided", func() {
   223  				BeforeEach(func() {
   224  					cmd.Enable = true
   225  				})
   226  
   227  				It("sets the enabled value to true when updating the buildpack", func() {
   228  					Expect(executeErr).ToNot(HaveOccurred())
   229  					_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   230  					Expect(buildpack.Enabled.IsSet).To(Equal(true))
   231  					Expect(buildpack.Enabled.Value).To(Equal(true))
   232  				})
   233  			})
   234  
   235  			When("the --disable flag is provided", func() {
   236  				BeforeEach(func() {
   237  					cmd.Disable = true
   238  				})
   239  
   240  				It("sets the enabled value to false when updating the buildpack", func() {
   241  					Expect(executeErr).ToNot(HaveOccurred())
   242  					_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   243  					Expect(buildpack.Enabled.IsSet).To(Equal(true))
   244  					Expect(buildpack.Enabled.Value).To(Equal(false))
   245  				})
   246  			})
   247  
   248  			When("the --index flag is provided", func() {
   249  				BeforeEach(func() {
   250  					cmd.Position = types.NullInt{IsSet: true, Value: 99}
   251  				})
   252  
   253  				It("sets the new buildpack order when updating the buildpack", func() {
   254  					Expect(executeErr).ToNot(HaveOccurred())
   255  					_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   256  					Expect(buildpack.Position.IsSet).To(Equal(true))
   257  					Expect(buildpack.Position.Value).To(Equal(99))
   258  				})
   259  			})
   260  
   261  			When("the --assign-stack flag is provided", func() {
   262  				BeforeEach(func() {
   263  					cmd.NewStack = "some-new-stack"
   264  				})
   265  
   266  				It("sets the new stack on the buildpack", func() {
   267  					Expect(executeErr).ToNot(HaveOccurred())
   268  					_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   269  					Expect(testUI.Out).ToNot(Say("Updating buildpack %s", buildpackName))
   270  					Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName))
   271  					Expect(buildpack.Stack).To(Equal("some-new-stack"))
   272  				})
   273  
   274  				Context("and the --index flag is provided", func() {
   275  					BeforeEach(func() {
   276  						cmd.Position = types.NullInt{IsSet: true, Value: 3}
   277  					})
   278  
   279  					It("sets the new stack and updates the priority of the buildpack", func() {
   280  						Expect(executeErr).ToNot(HaveOccurred())
   281  						Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName))
   282  						Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack))
   283  						Expect(testUI.Out).To(Say("OK"))
   284  					})
   285  				})
   286  
   287  				Context("and the --lock flag is provided", func() {
   288  					BeforeEach(func() {
   289  						cmd.Lock = true
   290  					})
   291  
   292  					It("sets the new stack and locks the buildpack", func() {
   293  						Expect(executeErr).ToNot(HaveOccurred())
   294  						Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName))
   295  						Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack))
   296  						Expect(testUI.Out).To(Say("OK"))
   297  					})
   298  				})
   299  
   300  				Context("and the --unlock flag is provided", func() {
   301  					BeforeEach(func() {
   302  						cmd.Unlock = true
   303  					})
   304  
   305  					It("sets the new stack and unlocks the buildpack", func() {
   306  						Expect(executeErr).ToNot(HaveOccurred())
   307  						Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName))
   308  						Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack))
   309  						Expect(testUI.Out).To(Say("OK"))
   310  					})
   311  				})
   312  
   313  				Context("and the --enable flag is provided", func() {
   314  					BeforeEach(func() {
   315  						cmd.Enable = true
   316  					})
   317  
   318  					It("sets the new stack and enables the buildpack", func() {
   319  						Expect(executeErr).ToNot(HaveOccurred())
   320  						Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName))
   321  						Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack))
   322  						Expect(testUI.Out).To(Say("OK"))
   323  					})
   324  				})
   325  
   326  				Context("and the --disable flag is provided", func() {
   327  					BeforeEach(func() {
   328  						cmd.Disable = true
   329  					})
   330  
   331  					It("sets the new stack and disables the buildpack", func() {
   332  						Expect(executeErr).ToNot(HaveOccurred())
   333  						Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName))
   334  						Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack))
   335  						Expect(testUI.Out).To(Say("OK"))
   336  					})
   337  				})
   338  
   339  			})
   340  
   341  			When("the --rename flag is provided", func() {
   342  				BeforeEach(func() {
   343  					cmd.NewName = "new-buildpack-name"
   344  				})
   345  
   346  				It("sets the new name on the buildpack", func() {
   347  					Expect(executeErr).ToNot(HaveOccurred())
   348  					_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   349  					Expect(buildpack.Name).To(Equal("new-buildpack-name"))
   350  
   351  					Expect(testUI.Out).ToNot(Say("Updating buildpack %s", buildpackName))
   352  					Expect(testUI.Out).To(Say(
   353  						"Renaming buildpack %s to %s as %s...", buildpackName, cmd.NewName, userName))
   354  					Expect(testUI.Out).To(Say("OK"))
   355  				})
   356  
   357  				Context("and the --assign-stack flag is provided", func() {
   358  					BeforeEach(func() {
   359  						cmd.NewStack = "new-stack"
   360  					})
   361  
   362  					It("sets the new name/stack on the buildpack and refers to the new name going forward", func() {
   363  						Expect(executeErr).ToNot(HaveOccurred())
   364  						_, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   365  						Expect(buildpack.Name).To(Equal("new-buildpack-name"))
   366  						Expect(buildpack.Stack).To(Equal("new-stack"))
   367  
   368  						Expect(testUI.Out).To(Say(
   369  							"Renaming buildpack %s to %s as %s...", buildpackName, cmd.NewName, userName))
   370  
   371  						Expect(testUI.Out).To(Say(
   372  							"Assigning stack %s to %s as %s", cmd.NewStack, cmd.NewName, userName))
   373  
   374  						Expect(testUI.Out).ToNot(Say("Updating buildpack %s", buildpackName))
   375  
   376  						Expect(testUI.Out).To(Say("OK"))
   377  					})
   378  				})
   379  			})
   380  
   381  			When("updating the buildpack succeeds", func() {
   382  				BeforeEach(func() {
   383  					fakeActor.UpdateBuildpackByNameAndStackReturns(
   384  						v7action.Buildpack{GUID: buildpackGUID},
   385  						v7action.Warnings{"update-bp-warning1", "update-bp-warning2"},
   386  						nil,
   387  					)
   388  				})
   389  
   390  				When("no arguments are specified", func() {
   391  					It("makes the actor call to update the buildpack", func() {
   392  						Expect(fakeActor.UpdateBuildpackByNameAndStackCallCount()).To(Equal(1))
   393  						_, newStack, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   394  						Expect(buildpack.Name).To(Equal(""))
   395  						Expect(buildpack.Stack).To(Equal(""))
   396  						Expect(buildpack.Position.IsSet).To(BeFalse())
   397  						Expect(buildpack.Locked.IsSet).To(BeFalse())
   398  						Expect(buildpack.Enabled.IsSet).To(BeFalse())
   399  						Expect(newStack).To(Equal(""))
   400  
   401  						Expect(testUI.Err).To(Say("update-bp-warning1"))
   402  						Expect(testUI.Err).To(Say("update-bp-warning2"))
   403  						Expect(testUI.Out).To(Say("Updating buildpack %s as %s...", buildpackName, userName))
   404  						Expect(testUI.Out).To(Say("OK"))
   405  					})
   406  				})
   407  
   408  				When("a path is specified", func() {
   409  					BeforeEach(func() {
   410  						cmd.Path = "some path"
   411  					})
   412  
   413  					It("makes the call to update the buildpack", func() {
   414  						Expect(fakeActor.UpdateBuildpackByNameAndStackCallCount()).To(Equal(1))
   415  						buildpackNameArg, _, _ := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0)
   416  						Expect(buildpackNameArg).To(Equal(buildpackName))
   417  
   418  						Expect(testUI.Err).To(Say("update-bp-warning1"))
   419  						Expect(testUI.Err).To(Say("update-bp-warning2"))
   420  						Expect(testUI.Out).To(Say("Updating buildpack %s as %s...", buildpackName, userName))
   421  						Expect(testUI.Out).To(Say("OK"))
   422  					})
   423  
   424  					When("preparing the bits succeeds", func() {
   425  						buildpackBitsPath := "some path on the file system"
   426  						BeforeEach(func() {
   427  							fakeActor.PrepareBuildpackBitsReturns(buildpackBitsPath, nil)
   428  						})
   429  
   430  						It("uploads the new buildpack bits", func() {
   431  							Expect(testUI.Out).To(Say("Uploading buildpack some-bp as some-user..."))
   432  							Expect(fakeActor.UploadBuildpackCallCount()).To(Equal(1))
   433  							buildpackGUIDUsed, pathUsed, _ := fakeActor.UploadBuildpackArgsForCall(0)
   434  							Expect(buildpackGUIDUsed).To(Equal(buildpackGUID))
   435  							Expect(pathUsed).To(Equal(buildpackBitsPath))
   436  						})
   437  
   438  						When("uploading the buildpack fails", func() {
   439  							BeforeEach(func() {
   440  								expectedErr = errors.New("upload error")
   441  								fakeActor.UploadBuildpackReturns("", v7action.Warnings{"upload-warning1", "upload-warning2"}, expectedErr)
   442  							})
   443  
   444  							It("returns all warnings and an error", func() {
   445  								Expect(testUI.Err).To(Say("update-bp-warning1"))
   446  								Expect(testUI.Err).To(Say("update-bp-warning2"))
   447  								Expect(testUI.Err).To(Say("upload-warning1"))
   448  								Expect(testUI.Err).To(Say("upload-warning2"))
   449  								Expect(executeErr).To(MatchError(expectedErr))
   450  							})
   451  						})
   452  
   453  						When("uploading the buildpack succeeds", func() {
   454  							BeforeEach(func() {
   455  								fakeActor.UploadBuildpackReturns(
   456  									"example.com/job/url/",
   457  									v7action.Warnings{"upload-warning1", "upload-warning2"},
   458  									nil,
   459  								)
   460  							})
   461  
   462  							When("polling the buildpack job fails", func() {
   463  								BeforeEach(func() {
   464  									expectedErr = ccerror.JobTimeoutError{JobGUID: "job-guid"}
   465  									fakeActor.PollUploadBuildpackJobReturns(
   466  										v7action.Warnings{"poll-warning1", "poll-warning2"},
   467  										expectedErr,
   468  									)
   469  								})
   470  
   471  								It("returns all warnings and an error", func() {
   472  									Expect(testUI.Err).To(Say("update-bp-warning1"))
   473  									Expect(testUI.Err).To(Say("update-bp-warning2"))
   474  									Expect(testUI.Err).To(Say("poll-warning1"))
   475  									Expect(testUI.Err).To(Say("poll-warning2"))
   476  									Expect(executeErr).To(MatchError(expectedErr))
   477  								})
   478  							})
   479  
   480  							When("polling the buildpack job succeeds", func() {
   481  								BeforeEach(func() {
   482  									fakeActor.PollUploadBuildpackJobReturns(
   483  										v7action.Warnings{"poll-warning1", "poll-warning2"},
   484  										nil,
   485  									)
   486  								})
   487  
   488  								It("displays success test and any warnings", func() {
   489  									Expect(testUI.Out).To(Say(`Uploading buildpack %s`, buildpackName))
   490  									Expect(testUI.Err).To(Say("upload-warning1"))
   491  									Expect(testUI.Err).To(Say("upload-warning2"))
   492  									Expect(testUI.Out).To(Say("OK"))
   493  
   494  									Expect(testUI.Out).To(Say(`Processing uploaded buildpack %s\.\.\.`, buildpackName))
   495  									Expect(testUI.Err).To(Say("poll-warning1"))
   496  									Expect(testUI.Err).To(Say("poll-warning2"))
   497  									Expect(testUI.Out).To(Say("OK"))
   498  								})
   499  							})
   500  						})
   501  					})
   502  				})
   503  			})
   504  		})
   505  	})
   506  })