github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/command/v7/run_task_command_test.go (about)

     1  package v7_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	"code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     9  	"code.cloudfoundry.org/cli/command/commandfakes"
    10  	"code.cloudfoundry.org/cli/command/flag"
    11  	. "code.cloudfoundry.org/cli/command/v7"
    12  	"code.cloudfoundry.org/cli/command/v7/v7fakes"
    13  	"code.cloudfoundry.org/cli/resources"
    14  	"code.cloudfoundry.org/cli/types"
    15  	"code.cloudfoundry.org/cli/util/configv3"
    16  	"code.cloudfoundry.org/cli/util/ui"
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/gomega"
    19  	. "github.com/onsi/gomega/gbytes"
    20  )
    21  
    22  var _ = Describe("run-task Command", func() {
    23  	var (
    24  		cmd             RunTaskCommand
    25  		testUI          *ui.UI
    26  		fakeConfig      *commandfakes.FakeConfig
    27  		fakeSharedActor *commandfakes.FakeSharedActor
    28  		fakeActor       *v7fakes.FakeActor
    29  		binaryName      string
    30  		executeErr      error
    31  	)
    32  
    33  	BeforeEach(func() {
    34  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    35  		fakeConfig = new(commandfakes.FakeConfig)
    36  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    37  		fakeActor = new(v7fakes.FakeActor)
    38  
    39  		cmd = RunTaskCommand{
    40  			BaseCommand: BaseCommand{
    41  				UI:          testUI,
    42  				Config:      fakeConfig,
    43  				SharedActor: fakeSharedActor,
    44  				Actor:       fakeActor,
    45  			},
    46  		}
    47  
    48  		cmd.RequiredArgs.AppName = "some-app-name"
    49  		cmd.Command = "some command"
    50  
    51  		binaryName = "faceman"
    52  		fakeConfig.BinaryNameReturns(binaryName)
    53  	})
    54  
    55  	JustBeforeEach(func() {
    56  		executeErr = cmd.Execute(nil)
    57  	})
    58  
    59  	When("checking target fails", func() {
    60  		BeforeEach(func() {
    61  			fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
    62  		})
    63  
    64  		It("returns an error", func() {
    65  			Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName}))
    66  
    67  			Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
    68  			checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
    69  			Expect(checkTargetedOrg).To(BeTrue())
    70  			Expect(checkTargetedSpace).To(BeTrue())
    71  		})
    72  	})
    73  
    74  	When("the user is logged in, and a space and org are targeted", func() {
    75  		BeforeEach(func() {
    76  			fakeConfig.HasTargetedOrganizationReturns(true)
    77  			fakeConfig.TargetedOrganizationReturns(configv3.Organization{
    78  				GUID: "some-org-guid",
    79  				Name: "some-org",
    80  			})
    81  			fakeConfig.HasTargetedSpaceReturns(true)
    82  			fakeConfig.TargetedSpaceReturns(configv3.Space{
    83  				GUID: "some-space-guid",
    84  				Name: "some-space",
    85  			})
    86  		})
    87  
    88  		When("getting the current user returns an error", func() {
    89  			var expectedErr error
    90  
    91  			BeforeEach(func() {
    92  				expectedErr = errors.New("got bananapants??")
    93  				fakeActor.GetCurrentUserReturns(
    94  					configv3.User{},
    95  					expectedErr)
    96  			})
    97  
    98  			It("returns the error", func() {
    99  				Expect(executeErr).To(MatchError(expectedErr))
   100  			})
   101  		})
   102  
   103  		When("getting the current user does not return an error", func() {
   104  			BeforeEach(func() {
   105  				fakeActor.GetCurrentUserReturns(
   106  					configv3.User{Name: "some-user"},
   107  					nil)
   108  			})
   109  
   110  			When("provided a valid application name", func() {
   111  				BeforeEach(func() {
   112  					fakeActor.GetApplicationByNameAndSpaceReturns(
   113  						resources.Application{GUID: "some-app-guid"},
   114  						v7action.Warnings{"get-application-warning-1", "get-application-warning-2"},
   115  						nil)
   116  				})
   117  
   118  				When("the task name is not provided", func() {
   119  					BeforeEach(func() {
   120  						fakeActor.RunTaskReturns(
   121  							resources.Task{
   122  								Name:       "31337ddd",
   123  								SequenceID: 3,
   124  							},
   125  							v7action.Warnings{"get-application-warning-3"},
   126  							nil)
   127  					})
   128  
   129  					It("creates a new task and displays all warnings", func() {
   130  						Expect(executeErr).ToNot(HaveOccurred())
   131  
   132  						Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1))
   133  						appName, spaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0)
   134  						Expect(appName).To(Equal("some-app-name"))
   135  						Expect(spaceGUID).To(Equal("some-space-guid"))
   136  
   137  						Expect(fakeActor.RunTaskCallCount()).To(Equal(1))
   138  						appGUID, task := fakeActor.RunTaskArgsForCall(0)
   139  						Expect(appGUID).To(Equal("some-app-guid"))
   140  						Expect(task).To(Equal(resources.Task{Command: "some command"}))
   141  
   142  						Expect(testUI.Out).To(Say("Creating task for app some-app-name in org some-org / space some-space as some-user..."))
   143  						Expect(testUI.Out).To(Say("Task has been submitted successfully for execution."))
   144  						Expect(testUI.Out).To(Say("OK"))
   145  
   146  						Expect(testUI.Out).To(Say(`task name:\s+31337ddd`))
   147  						Expect(testUI.Out).To(Say(`task id:\s+3`))
   148  						Expect(testUI.Out).To(Say("OK"))
   149  
   150  						Expect(testUI.Err).To(Say("get-application-warning-1"))
   151  						Expect(testUI.Err).To(Say("get-application-warning-2"))
   152  						Expect(testUI.Err).To(Say("get-application-warning-3"))
   153  					})
   154  				})
   155  
   156  				When("task disk space is provided", func() {
   157  					BeforeEach(func() {
   158  						cmd.Name = "some-task-name"
   159  						cmd.Disk = flag.Megabytes{NullUint64: types.NullUint64{Value: 321, IsSet: true}}
   160  						cmd.Memory = flag.Megabytes{NullUint64: types.NullUint64{Value: 123, IsSet: true}}
   161  						fakeActor.RunTaskReturns(
   162  							resources.Task{
   163  								Name:       "some-task-name",
   164  								SequenceID: 3,
   165  							},
   166  							v7action.Warnings{"get-application-warning-3"},
   167  							nil)
   168  					})
   169  
   170  					It("creates a new task and outputs all warnings", func() {
   171  						Expect(executeErr).ToNot(HaveOccurred())
   172  
   173  						Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1))
   174  						appName, spaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0)
   175  						Expect(appName).To(Equal("some-app-name"))
   176  						Expect(spaceGUID).To(Equal("some-space-guid"))
   177  
   178  						Expect(fakeActor.RunTaskCallCount()).To(Equal(1))
   179  						appGUID, task := fakeActor.RunTaskArgsForCall(0)
   180  						Expect(appGUID).To(Equal("some-app-guid"))
   181  						Expect(task).To(Equal(resources.Task{
   182  							Command:    "some command",
   183  							Name:       "some-task-name",
   184  							DiskInMB:   321,
   185  							MemoryInMB: 123,
   186  						}))
   187  
   188  						Expect(testUI.Out).To(Say("Creating task for app some-app-name in org some-org / space some-space as some-user..."))
   189  						Expect(testUI.Out).To(Say("Task has been submitted successfully for execution."))
   190  						Expect(testUI.Out).To(Say("OK"))
   191  
   192  						Expect(testUI.Out).To(Say(`task name:\s+some-task-name`))
   193  						Expect(testUI.Out).To(Say(`task id:\s+3`))
   194  						Expect(testUI.Out).To(Say("OK"))
   195  
   196  						Expect(testUI.Err).To(Say("get-application-warning-1"))
   197  						Expect(testUI.Err).To(Say("get-application-warning-2"))
   198  						Expect(testUI.Err).To(Say("get-application-warning-3"))
   199  					})
   200  				})
   201  
   202  				When("task log rate limit is provided", func() {
   203  					BeforeEach(func() {
   204  						cmd.Name = "some-task-name"
   205  						cmd.LogRateLimit = flag.BytesWithUnlimited{Value: 1024 * 5, IsSet: true}
   206  						fakeActor.RunTaskReturns(
   207  							resources.Task{
   208  								Name:       "some-task-name",
   209  								SequenceID: 3,
   210  							},
   211  							v7action.Warnings{"get-application-warning-3"},
   212  							nil)
   213  					})
   214  
   215  					It("creates a new task and outputs all warnings", func() {
   216  						Expect(executeErr).ToNot(HaveOccurred())
   217  
   218  						Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1))
   219  						appName, spaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0)
   220  						Expect(appName).To(Equal("some-app-name"))
   221  						Expect(spaceGUID).To(Equal("some-space-guid"))
   222  
   223  						Expect(fakeActor.RunTaskCallCount()).To(Equal(1))
   224  						appGUID, task := fakeActor.RunTaskArgsForCall(0)
   225  						Expect(appGUID).To(Equal("some-app-guid"))
   226  						Expect(task).To(Equal(resources.Task{
   227  							Command:           "some command",
   228  							Name:              "some-task-name",
   229  							LogRateLimitInBPS: 1024 * 5,
   230  						}))
   231  
   232  						Expect(testUI.Out).To(Say("Creating task for app some-app-name in org some-org / space some-space as some-user..."))
   233  						Expect(testUI.Out).To(Say("Task has been submitted successfully for execution."))
   234  						Expect(testUI.Out).To(Say("OK"))
   235  
   236  						Expect(testUI.Out).To(Say(`task name:\s+some-task-name`))
   237  						Expect(testUI.Out).To(Say(`task id:\s+3`))
   238  
   239  						Expect(testUI.Err).To(Say("get-application-warning-1"))
   240  						Expect(testUI.Err).To(Say("get-application-warning-2"))
   241  						Expect(testUI.Err).To(Say("get-application-warning-3"))
   242  					})
   243  				})
   244  
   245  				When("process is provided", func() {
   246  					BeforeEach(func() {
   247  						cmd.Name = "some-task-name"
   248  						cmd.Process = "process-template-name"
   249  						cmd.Command = ""
   250  						fakeActor.RunTaskReturns(
   251  							resources.Task{
   252  								Name:       "some-task-name",
   253  								SequenceID: 3,
   254  							},
   255  							v7action.Warnings{"get-application-warning-3"},
   256  							nil)
   257  						fakeActor.GetProcessByTypeAndApplicationReturns(
   258  							resources.Process{
   259  								GUID: "some-process-guid",
   260  							},
   261  							v7action.Warnings{"get-process-warning"},
   262  							nil)
   263  					})
   264  
   265  					It("creates a new task and outputs all warnings", func() {
   266  						Expect(executeErr).ToNot(HaveOccurred())
   267  
   268  						Expect(fakeActor.RunTaskCallCount()).To(Equal(1))
   269  						appGUID, task := fakeActor.RunTaskArgsForCall(0)
   270  						Expect(appGUID).To(Equal("some-app-guid"))
   271  						Expect(task).To(Equal(resources.Task{
   272  							Command: "",
   273  							Name:    "some-task-name",
   274  							Template: &resources.TaskTemplate{
   275  								Process: resources.TaskProcessTemplate{Guid: "some-process-guid"},
   276  							},
   277  						}))
   278  
   279  						Expect(testUI.Out).To(Say("Creating task for app some-app-name in org some-org / space some-space as some-user..."))
   280  						Expect(testUI.Out).To(Say("Task has been submitted successfully for execution."))
   281  						Expect(testUI.Out).To(Say("OK"))
   282  
   283  						Expect(testUI.Out).To(Say(`task name:\s+some-task-name`))
   284  						Expect(testUI.Out).To(Say(`task id:\s+3`))
   285  						Expect(testUI.Out).To(Say("OK"))
   286  
   287  						Expect(testUI.Err).To(Say("get-application-warning-1"))
   288  						Expect(testUI.Err).To(Say("get-application-warning-2"))
   289  						Expect(testUI.Err).To(Say("get-process-warning"))
   290  						Expect(testUI.Err).To(Say("get-application-warning-3"))
   291  					})
   292  				})
   293  
   294  				When("neither command nor process template are provided", func() {
   295  					BeforeEach(func() {
   296  						cmd.Name = "some-task-name"
   297  						cmd.Command = ""
   298  						fakeActor.RunTaskReturns(
   299  							resources.Task{
   300  								Name:       "some-task-name",
   301  								SequenceID: 3,
   302  							},
   303  							v7action.Warnings{"get-application-warning-3"},
   304  							nil)
   305  						fakeActor.GetProcessByTypeAndApplicationReturns(
   306  							resources.Process{
   307  								GUID: "some-process-guid",
   308  							},
   309  							v7action.Warnings{"get-process-warning"},
   310  							nil)
   311  					})
   312  
   313  					It("creates a new task using 'task' as the template process type and outputs all warnings", func() {
   314  						Expect(executeErr).ToNot(HaveOccurred())
   315  
   316  						Expect(fakeActor.GetProcessByTypeAndApplicationCallCount()).To(Equal(1))
   317  						processType, _ := fakeActor.GetProcessByTypeAndApplicationArgsForCall(0)
   318  						Expect(processType).To(Equal("task"))
   319  
   320  						Expect(fakeActor.RunTaskCallCount()).To(Equal(1))
   321  						appGUID, task := fakeActor.RunTaskArgsForCall(0)
   322  						Expect(appGUID).To(Equal("some-app-guid"))
   323  						Expect(task).To(Equal(resources.Task{
   324  							Command: "",
   325  							Name:    "some-task-name",
   326  							Template: &resources.TaskTemplate{
   327  								Process: resources.TaskProcessTemplate{Guid: "some-process-guid"},
   328  							},
   329  						}))
   330  
   331  						Expect(testUI.Out).To(Say("Creating task for app some-app-name in org some-org / space some-space as some-user..."))
   332  						Expect(testUI.Out).To(Say("Task has been submitted successfully for execution."))
   333  						Expect(testUI.Out).To(Say("OK"))
   334  
   335  						Expect(testUI.Out).To(Say(`task name:\s+some-task-name`))
   336  						Expect(testUI.Out).To(Say(`task id:\s+3`))
   337  						Expect(testUI.Out).To(Say("OK"))
   338  
   339  						Expect(testUI.Err).To(Say("get-application-warning-1"))
   340  						Expect(testUI.Err).To(Say("get-application-warning-2"))
   341  						Expect(testUI.Err).To(Say("get-process-warning"))
   342  						Expect(testUI.Err).To(Say("get-application-warning-3"))
   343  					})
   344  				})
   345  
   346  				When("wait is provided", func() {
   347  					BeforeEach(func() {
   348  						cmd.Name = "some-task-name"
   349  						cmd.Command = "echo hello"
   350  						cmd.Wait = true
   351  						fakeActor.RunTaskReturns(
   352  							resources.Task{
   353  								Name:       "some-task-name",
   354  								SequenceID: 3,
   355  							},
   356  							v7action.Warnings{"get-application-warning-3"},
   357  							nil)
   358  						fakeActor.PollTaskReturns(
   359  							resources.Task{
   360  								Name:       "some-task-name",
   361  								SequenceID: 3,
   362  							},
   363  							v7action.Warnings{"poll-warnings"},
   364  							nil)
   365  					})
   366  
   367  					It("waits for the task to complete before exiting", func() {
   368  						Expect(executeErr).ToNot(HaveOccurred())
   369  
   370  						Expect(testUI.Out).To(Say("Creating task for app some-app-name in org some-org / space some-space as some-user..."))
   371  
   372  						Expect(testUI.Out).To(Say("Task has been submitted successfully for execution."))
   373  						Expect(testUI.Out).To(Say(`task name:\s+some-task-name`))
   374  						Expect(testUI.Out).To(Say(`task id:\s+3`))
   375  
   376  						Expect(testUI.Out).To(Say(`Waiting for task to complete execution...`))
   377  
   378  						Expect(testUI.Out).To(Say(`Task has completed successfully.`))
   379  						Expect(testUI.Out).To(Say("OK"))
   380  
   381  						Expect(testUI.Err).To(Say("get-application-warning-1"))
   382  						Expect(testUI.Err).To(Say("get-application-warning-2"))
   383  						Expect(testUI.Err).To(Say("get-application-warning-3"))
   384  						Expect(testUI.Err).To(Say("poll-warnings"))
   385  
   386  					})
   387  				})
   388  			})
   389  
   390  			When("there are errors", func() {
   391  				When("the error is translatable", func() {
   392  					When("getting the app returns the error", func() {
   393  						var (
   394  							returnedErr error
   395  							expectedErr error
   396  						)
   397  
   398  						BeforeEach(func() {
   399  							expectedErr = errors.New("request-error")
   400  							returnedErr = ccerror.RequestError{Err: expectedErr}
   401  							fakeActor.GetApplicationByNameAndSpaceReturns(
   402  								resources.Application{GUID: "some-app-guid"},
   403  								nil,
   404  								returnedErr)
   405  						})
   406  
   407  						It("returns a translatable error", func() {
   408  							Expect(executeErr).To(MatchError(ccerror.RequestError{Err: expectedErr}))
   409  						})
   410  					})
   411  
   412  					When("running the task returns the error", func() {
   413  						var returnedErr error
   414  
   415  						BeforeEach(func() {
   416  							returnedErr = ccerror.UnverifiedServerError{URL: "some-url"}
   417  							fakeActor.GetApplicationByNameAndSpaceReturns(
   418  								resources.Application{GUID: "some-app-guid"},
   419  								nil,
   420  								nil)
   421  							fakeActor.RunTaskReturns(
   422  								resources.Task{},
   423  								nil,
   424  								returnedErr)
   425  						})
   426  
   427  						It("returns a translatable error", func() {
   428  							Expect(executeErr).To(MatchError(returnedErr))
   429  						})
   430  					})
   431  
   432  					When("polling the task returns the error", func() {
   433  						var returnedErr error
   434  
   435  						BeforeEach(func() {
   436  							cmd.Wait = true
   437  							returnedErr = ccerror.UnverifiedServerError{URL: "some-url"}
   438  							fakeActor.GetApplicationByNameAndSpaceReturns(
   439  								resources.Application{GUID: "some-app-guid"},
   440  								nil,
   441  								nil)
   442  							fakeActor.RunTaskReturns(
   443  								resources.Task{},
   444  								nil,
   445  								nil)
   446  							fakeActor.PollTaskReturns(
   447  								resources.Task{},
   448  								nil,
   449  								returnedErr)
   450  						})
   451  
   452  						It("returns a translatable error", func() {
   453  							Expect(executeErr).To(MatchError(returnedErr))
   454  						})
   455  					})
   456  				})
   457  
   458  				When("the error is not translatable", func() {
   459  					When("getting the app returns the error", func() {
   460  						var expectedErr error
   461  
   462  						BeforeEach(func() {
   463  							expectedErr = errors.New("got bananapants??")
   464  							fakeActor.GetApplicationByNameAndSpaceReturns(
   465  								resources.Application{GUID: "some-app-guid"},
   466  								v7action.Warnings{"get-application-warning-1", "get-application-warning-2"},
   467  								expectedErr)
   468  						})
   469  
   470  						It("return the error and all warnings", func() {
   471  							Expect(executeErr).To(MatchError(expectedErr))
   472  
   473  							Expect(testUI.Err).To(Say("get-application-warning-1"))
   474  							Expect(testUI.Err).To(Say("get-application-warning-2"))
   475  						})
   476  					})
   477  
   478  					When("running the task returns an error", func() {
   479  						var expectedErr error
   480  
   481  						BeforeEach(func() {
   482  							expectedErr = errors.New("got bananapants??")
   483  							fakeActor.GetApplicationByNameAndSpaceReturns(
   484  								resources.Application{GUID: "some-app-guid"},
   485  								v7action.Warnings{"get-application-warning-1", "get-application-warning-2"},
   486  								nil)
   487  							fakeActor.RunTaskReturns(
   488  								resources.Task{},
   489  								v7action.Warnings{"run-task-warning-1", "run-task-warning-2"},
   490  								expectedErr)
   491  						})
   492  
   493  						It("returns the error and all warnings", func() {
   494  							Expect(executeErr).To(MatchError(expectedErr))
   495  
   496  							Expect(testUI.Err).To(Say("get-application-warning-1"))
   497  							Expect(testUI.Err).To(Say("get-application-warning-2"))
   498  							Expect(testUI.Err).To(Say("run-task-warning-1"))
   499  							Expect(testUI.Err).To(Say("run-task-warning-2"))
   500  						})
   501  					})
   502  				})
   503  			})
   504  		})
   505  	})
   506  })