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