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 })