github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/actor/v7action/process_test.go (about) 1 package v7action_test 2 3 import ( 4 "code.cloudfoundry.org/cli/resources" 5 "errors" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 . "code.cloudfoundry.org/cli/actor/v7action" 9 "code.cloudfoundry.org/cli/actor/v7action/v7actionfakes" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 12 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 13 "code.cloudfoundry.org/cli/types" 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 . "github.com/onsi/gomega/gstruct" 17 ) 18 19 var _ = Describe("Process Actions", func() { 20 var ( 21 actor *Actor 22 fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient 23 ) 24 25 BeforeEach(func() { 26 fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient) 27 actor = NewActor(fakeCloudControllerClient, nil, nil, nil) 28 }) 29 30 Describe("GetProcessByTypeAndApplication", func() { 31 var ( 32 processType string 33 appGUID string 34 35 process Process 36 warnings Warnings 37 err error 38 ) 39 40 BeforeEach(func() { 41 processType = "web" 42 appGUID = "some-app-guid" 43 }) 44 45 JustBeforeEach(func() { 46 process, warnings, err = actor.GetProcessByTypeAndApplication(processType, appGUID) 47 }) 48 49 When("getting the application process is succesful", func() { 50 BeforeEach(func() { 51 fakeCloudControllerClient.GetApplicationProcessByTypeReturns( 52 resources.Process{ 53 GUID: "some-process-guid", 54 }, 55 ccv3.Warnings{"some-process-warning"}, 56 nil, 57 ) 58 }) 59 60 It("returns the process and warnings", func() { 61 Expect(err).NotTo(HaveOccurred()) 62 Expect(warnings).To(ConsistOf("some-process-warning")) 63 Expect(process).To(Equal(Process{ 64 GUID: "some-process-guid", 65 })) 66 67 Expect(fakeCloudControllerClient.GetApplicationProcessByTypeCallCount()).To(Equal(1)) 68 passedAppGUID, passedProcessType := fakeCloudControllerClient.GetApplicationProcessByTypeArgsForCall(0) 69 Expect(passedAppGUID).To(Equal(appGUID)) 70 Expect(passedProcessType).To(Equal(processType)) 71 }) 72 }) 73 74 When("getting application process by type returns an error", func() { 75 var expectedErr error 76 77 When("the api returns a ProcessNotFoundError", func() { 78 BeforeEach(func() { 79 fakeCloudControllerClient.GetApplicationProcessByTypeReturns( 80 resources.Process{}, 81 ccv3.Warnings{"some-process-warning"}, 82 ccerror.ProcessNotFoundError{}, 83 ) 84 }) 85 86 It("returns a ProcessNotFoundError and all warnings", func() { 87 Expect(err).To(Equal(actionerror.ProcessNotFoundError{ProcessType: "web"})) 88 Expect(warnings).To(ConsistOf("some-process-warning")) 89 }) 90 }) 91 92 Context("generic error", func() { 93 BeforeEach(func() { 94 expectedErr = errors.New("some-error") 95 fakeCloudControllerClient.GetApplicationProcessByTypeReturns( 96 resources.Process{}, 97 ccv3.Warnings{"some-process-warning"}, 98 expectedErr, 99 ) 100 }) 101 102 It("returns the error and warnings", func() { 103 Expect(err).To(Equal(expectedErr)) 104 Expect(warnings).To(ConsistOf("some-process-warning")) 105 }) 106 }) 107 }) 108 }) 109 110 Describe("ScaleProcessByApplication", func() { 111 var ( 112 passedProcess Process 113 warnings Warnings 114 executeErr error 115 ) 116 117 BeforeEach(func() { 118 passedProcess = Process{ 119 Type: constant.ProcessTypeWeb, 120 Instances: types.NullInt{Value: 2, IsSet: true}, 121 MemoryInMB: types.NullUint64{Value: 100, IsSet: true}, 122 DiskInMB: types.NullUint64{Value: 200, IsSet: true}, 123 } 124 }) 125 126 JustBeforeEach(func() { 127 warnings, executeErr = actor.ScaleProcessByApplication("some-app-guid", passedProcess) 128 }) 129 130 When("no errors are encountered scaling the application process", func() { 131 BeforeEach(func() { 132 fakeCloudControllerClient.CreateApplicationProcessScaleReturns( 133 resources.Process{GUID: "some-process-guid"}, 134 ccv3.Warnings{"scale-process-warning"}, 135 nil) 136 }) 137 138 It("scales correct process", func() { 139 Expect(executeErr).ToNot(HaveOccurred()) 140 Expect(warnings).To(ConsistOf("scale-process-warning")) 141 142 Expect(fakeCloudControllerClient.CreateApplicationProcessScaleCallCount()).To(Equal(1)) 143 appGUIDArg, processArg := fakeCloudControllerClient.CreateApplicationProcessScaleArgsForCall(0) 144 Expect(appGUIDArg).To(Equal("some-app-guid")) 145 Expect(processArg).To(Equal(resources.Process{ 146 Type: constant.ProcessTypeWeb, 147 Instances: passedProcess.Instances, 148 MemoryInMB: passedProcess.MemoryInMB, 149 DiskInMB: passedProcess.DiskInMB, 150 })) 151 }) 152 }) 153 154 When("an error is encountered scaling the application process", func() { 155 var expectedErr error 156 157 BeforeEach(func() { 158 expectedErr = errors.New("scale process error") 159 fakeCloudControllerClient.CreateApplicationProcessScaleReturns( 160 resources.Process{GUID: "some-process-guid"}, 161 ccv3.Warnings{"scale-process-warning"}, 162 expectedErr) 163 }) 164 165 It("returns the error and all warnings", func() { 166 Expect(executeErr).To(MatchError(expectedErr)) 167 Expect(warnings).To(ConsistOf("scale-process-warning")) 168 }) 169 }) 170 171 When("a ProcessNotFoundError error is encountered scaling the application process", func() { 172 BeforeEach(func() { 173 fakeCloudControllerClient.CreateApplicationProcessScaleReturns( 174 resources.Process{GUID: "some-process-guid"}, 175 ccv3.Warnings{"scale-process-warning"}, 176 ccerror.ProcessNotFoundError{}, 177 ) 178 }) 179 180 It("returns the error and all warnings", func() { 181 Expect(executeErr).To(Equal(actionerror.ProcessNotFoundError{ProcessType: constant.ProcessTypeWeb})) 182 Expect(warnings).To(ConsistOf("scale-process-warning")) 183 }) 184 }) 185 }) 186 187 Describe("UpdateProcessByTypeAndApplication", func() { 188 var ( 189 processType string 190 appGUID string 191 inputProcess Process 192 193 warnings Warnings 194 err error 195 ) 196 197 BeforeEach(func() { 198 processType = "web" 199 appGUID = "some-app-guid" 200 inputProcess = Process{} 201 }) 202 203 JustBeforeEach(func() { 204 warnings, err = actor.UpdateProcessByTypeAndApplication(processType, appGUID, inputProcess) 205 }) 206 207 When("the user specifies an endpoint for a non-http health check", func() { 208 BeforeEach(func() { 209 inputProcess.HealthCheckType = constant.Port 210 inputProcess.HealthCheckEndpoint = "some-http-endpoint" 211 }) 212 213 It("returns an HTTPHealthCheckInvalidError", func() { 214 Expect(err).To(MatchError(actionerror.HTTPHealthCheckInvalidError{})) 215 Expect(warnings).To(BeNil()) 216 }) 217 }) 218 219 When("getting application process by type returns an error", func() { 220 var expectedErr error 221 222 BeforeEach(func() { 223 expectedErr = errors.New("some-error") 224 fakeCloudControllerClient.GetApplicationProcessByTypeReturns( 225 resources.Process{}, 226 ccv3.Warnings{"some-process-warning"}, 227 expectedErr, 228 ) 229 }) 230 231 It("returns the error and warnings", func() { 232 Expect(err).To(Equal(expectedErr)) 233 Expect(warnings).To(ConsistOf("some-process-warning")) 234 }) 235 }) 236 237 When("application process exists", func() { 238 BeforeEach(func() { 239 fakeCloudControllerClient.GetApplicationProcessByTypeReturns( 240 resources.Process{ 241 GUID: "some-process-guid", 242 }, 243 ccv3.Warnings{"some-process-warning"}, 244 nil, 245 ) 246 }) 247 248 When("updating the process errors", func() { 249 var expectedErr error 250 251 BeforeEach(func() { 252 inputProcess.HealthCheckType = constant.Port 253 inputProcess.HealthCheckEndpoint = constant.ProcessHealthCheckEndpointDefault 254 255 expectedErr = errors.New("some-error") 256 fakeCloudControllerClient.UpdateProcessReturns( 257 resources.Process{}, 258 ccv3.Warnings{"some-health-check-warning"}, 259 expectedErr, 260 ) 261 }) 262 263 It("returns the error and warnings", func() { 264 Expect(err).To(Equal(expectedErr)) 265 Expect(warnings).To(ConsistOf("some-process-warning", "some-health-check-warning")) 266 }) 267 }) 268 269 When("update the process is successful", func() { 270 BeforeEach(func() { 271 fakeCloudControllerClient.UpdateProcessReturns( 272 resources.Process{GUID: "some-process-guid"}, 273 ccv3.Warnings{"some-health-check-warning"}, 274 nil, 275 ) 276 }) 277 278 It("gets the correct application process", func() { 279 Expect(err).NotTo(HaveOccurred()) 280 281 Expect(fakeCloudControllerClient.GetApplicationProcessByTypeCallCount()).To(Equal(1)) 282 passedAppGUID, passedProcessType := fakeCloudControllerClient.GetApplicationProcessByTypeArgsForCall(0) 283 Expect(passedAppGUID).To(Equal(appGUID)) 284 Expect(passedProcessType).To(Equal(processType)) 285 }) 286 287 When("updating the command is successful", func() { 288 var command types.FilteredString 289 BeforeEach(func() { 290 command = *types.NewFilteredString("some-command") 291 inputProcess.Command = command 292 }) 293 294 It("returns the application", func() { 295 Expect(err).NotTo(HaveOccurred()) 296 Expect(warnings).To(ConsistOf("some-process-warning", "some-health-check-warning")) 297 298 Expect(fakeCloudControllerClient.UpdateProcessCallCount()).To(Equal(1)) 299 process := fakeCloudControllerClient.UpdateProcessArgsForCall(0) 300 Expect(process).To(MatchFields(IgnoreExtras, 301 Fields{ 302 "GUID": Equal("some-process-guid"), 303 "Command": Equal(command), 304 })) 305 }) 306 }) 307 308 When("the health check type is http", func() { 309 BeforeEach(func() { 310 inputProcess.HealthCheckType = constant.HTTP 311 inputProcess.HealthCheckEndpoint = "some-http-endpoint" 312 inputProcess.HealthCheckInvocationTimeout = 42 313 }) 314 315 It("returns the application", func() { 316 Expect(err).NotTo(HaveOccurred()) 317 Expect(warnings).To(ConsistOf("some-process-warning", "some-health-check-warning")) 318 319 Expect(fakeCloudControllerClient.UpdateProcessCallCount()).To(Equal(1)) 320 process := fakeCloudControllerClient.UpdateProcessArgsForCall(0) 321 Expect(process).To(MatchFields(IgnoreExtras, 322 Fields{ 323 "GUID": Equal("some-process-guid"), 324 "HealthCheckType": Equal(constant.HTTP), 325 "HealthCheckEndpoint": Equal("some-http-endpoint"), 326 "HealthCheckInvocationTimeout": BeEquivalentTo(42), 327 })) 328 }) 329 }) 330 331 When("the health check type is not http", func() { 332 BeforeEach(func() { 333 inputProcess.HealthCheckType = constant.Port 334 inputProcess.HealthCheckInvocationTimeout = 42 335 }) 336 337 When("the endpoint is set to '/'", func() { 338 BeforeEach(func() { 339 inputProcess.HealthCheckEndpoint = constant.ProcessHealthCheckEndpointDefault 340 }) 341 342 It("does not send the / endpoint and returns the application", func() { 343 Expect(err).NotTo(HaveOccurred()) 344 Expect(warnings).To(ConsistOf("some-process-warning", "some-health-check-warning")) 345 346 Expect(fakeCloudControllerClient.UpdateProcessCallCount()).To(Equal(1)) 347 process := fakeCloudControllerClient.UpdateProcessArgsForCall(0) 348 Expect(process).To(MatchFields(IgnoreExtras, 349 Fields{ 350 "GUID": Equal("some-process-guid"), 351 "HealthCheckType": Equal(constant.Port), 352 "HealthCheckEndpoint": BeEmpty(), 353 "HealthCheckInvocationTimeout": BeEquivalentTo(42), 354 })) 355 }) 356 }) 357 358 When("the endpoint is empty", func() { 359 It("does not send the / endpoint and returns the application", func() { 360 Expect(err).NotTo(HaveOccurred()) 361 Expect(warnings).To(ConsistOf("some-process-warning", "some-health-check-warning")) 362 363 Expect(fakeCloudControllerClient.UpdateProcessCallCount()).To(Equal(1)) 364 process := fakeCloudControllerClient.UpdateProcessArgsForCall(0) 365 Expect(process).To(MatchFields(IgnoreExtras, 366 Fields{ 367 "GUID": Equal("some-process-guid"), 368 "HealthCheckType": Equal(constant.Port), 369 "HealthCheckEndpoint": BeEmpty(), 370 "HealthCheckInvocationTimeout": BeEquivalentTo(42), 371 })) 372 }) 373 }) 374 }) 375 }) 376 }) 377 }) 378 })