github.com/LukasHeimann/cloudfoundrycli@v7.1.0+incompatible/actor/v7action/application_summary_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/v7action"
     7  	. "code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    12  	"code.cloudfoundry.org/cli/resources"
    13  	"code.cloudfoundry.org/cli/types"
    14  	"code.cloudfoundry.org/clock"
    15  
    16  	"code.cloudfoundry.org/cli/actor/actionerror"
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/ginkgo/extensions/table"
    19  	. "github.com/onsi/gomega"
    20  )
    21  
    22  var _ = Describe("Application Summary Actions", func() {
    23  	var (
    24  		actor                     *Actor
    25  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    26  	)
    27  
    28  	BeforeEach(func() {
    29  		fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
    30  		actor = NewActor(fakeCloudControllerClient, nil, nil, nil, nil, clock.NewClock())
    31  	})
    32  
    33  	Describe("ApplicationSummary", func() {
    34  		DescribeTable("GetIsolationSegmentName",
    35  			func(summary ApplicationSummary, isoName string, exists bool) {
    36  				name, ok := summary.GetIsolationSegmentName()
    37  				Expect(ok).To(Equal(exists))
    38  				Expect(name).To(Equal(isoName))
    39  			},
    40  
    41  			Entry("when the there are application instances and the isolationSegmentName is set",
    42  				ApplicationSummary{
    43  					ProcessSummaries: ProcessSummaries{
    44  						ProcessSummary{
    45  							InstanceDetails: []ProcessInstance{
    46  								{IsolationSegment: "some-name"},
    47  							},
    48  						},
    49  					},
    50  				},
    51  				"some-name",
    52  				true,
    53  			),
    54  
    55  			Entry("when the there are application instances and the isolationSegmentName is blank",
    56  				ApplicationSummary{
    57  					ProcessSummaries: ProcessSummaries{
    58  						ProcessSummary{InstanceDetails: []ProcessInstance{{}}},
    59  					},
    60  				},
    61  				"",
    62  				false,
    63  			),
    64  
    65  			Entry("when the there are no application instances", ApplicationSummary{ProcessSummaries: ProcessSummaries{{}}}, "", false),
    66  			Entry("when the there are no processes", ApplicationSummary{}, "", false),
    67  		)
    68  	})
    69  
    70  	Describe("GetAppSummariesForSpace", func() {
    71  		var (
    72  			spaceGUID     string
    73  			labelSelector string
    74  
    75  			summaries  []ApplicationSummary
    76  			warnings   Warnings
    77  			executeErr error
    78  		)
    79  
    80  		BeforeEach(func() {
    81  			spaceGUID = "some-space-guid"
    82  			labelSelector = "some-key=some-value"
    83  		})
    84  
    85  		JustBeforeEach(func() {
    86  			summaries, warnings, executeErr = actor.GetAppSummariesForSpace(spaceGUID, labelSelector)
    87  		})
    88  
    89  		When("getting the application is successful", func() {
    90  			BeforeEach(func() {
    91  				fakeCloudControllerClient.GetApplicationsReturns(
    92  					[]resources.Application{
    93  						{
    94  							Name:  "some-app-name",
    95  							GUID:  "some-app-guid",
    96  							State: constant.ApplicationStarted,
    97  						},
    98  					},
    99  					ccv3.Warnings{"get-apps-warning"},
   100  					nil,
   101  				)
   102  
   103  				listedProcesses := []ccv3.Process{
   104  					{
   105  						GUID:       "some-process-guid",
   106  						Type:       "some-type",
   107  						Command:    *types.NewFilteredString("[Redacted Value]"),
   108  						MemoryInMB: types.NullUint64{Value: 32, IsSet: true},
   109  						AppGUID:    "some-app-guid",
   110  					},
   111  					{
   112  						GUID:       "some-process-web-guid",
   113  						Type:       "web",
   114  						Command:    *types.NewFilteredString("[Redacted Value]"),
   115  						MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
   116  						AppGUID:    "some-app-guid",
   117  					},
   118  				}
   119  
   120  				fakeCloudControllerClient.GetProcessesReturns(
   121  					listedProcesses,
   122  					ccv3.Warnings{"get-app-processes-warning"},
   123  					nil,
   124  				)
   125  
   126  				explicitlyCalledProcess := listedProcesses[0]
   127  				explicitlyCalledProcess.Command = *types.NewFilteredString("some-start-command")
   128  				fakeCloudControllerClient.GetProcessReturnsOnCall(
   129  					0,
   130  					explicitlyCalledProcess,
   131  					ccv3.Warnings{"get-process-by-type-warning"},
   132  					nil,
   133  				)
   134  
   135  				fakeCloudControllerClient.GetProcessReturnsOnCall(
   136  					1,
   137  					listedProcesses[1],
   138  					ccv3.Warnings{"get-process-by-type-warning"},
   139  					nil,
   140  				)
   141  
   142  				fakeCloudControllerClient.GetProcessInstancesReturns(
   143  					[]ccv3.ProcessInstance{
   144  						{
   145  							State:       constant.ProcessInstanceRunning,
   146  							CPU:         0.01,
   147  							MemoryUsage: 1000000,
   148  							DiskUsage:   2000000,
   149  							MemoryQuota: 3000000,
   150  							DiskQuota:   4000000,
   151  							Index:       0,
   152  						},
   153  					},
   154  					ccv3.Warnings{"get-process-instances-warning"},
   155  					nil,
   156  				)
   157  
   158  				fakeCloudControllerClient.GetRoutesReturns(
   159  					[]resources.Route{
   160  						{
   161  							GUID: "some-route-guid",
   162  							Destinations: []resources.RouteDestination{
   163  								{
   164  									App: resources.RouteDestinationApp{
   165  										GUID: "some-app-guid",
   166  									},
   167  								},
   168  							},
   169  						},
   170  						{
   171  							GUID: "some-other-route-guid",
   172  							Destinations: []resources.RouteDestination{
   173  								{
   174  									App: resources.RouteDestinationApp{
   175  										GUID: "some-app-guid",
   176  									},
   177  								},
   178  							},
   179  						},
   180  					},
   181  					ccv3.Warnings{"get-routes-warning"},
   182  					nil,
   183  				)
   184  			})
   185  
   186  			It("returns the summary and warnings with droplet information", func() {
   187  				Expect(executeErr).ToNot(HaveOccurred())
   188  
   189  				Expect(summaries).To(Equal([]ApplicationSummary{
   190  					{
   191  						Application: resources.Application{
   192  							Name:  "some-app-name",
   193  							GUID:  "some-app-guid",
   194  							State: constant.ApplicationStarted,
   195  						},
   196  						ProcessSummaries: []ProcessSummary{
   197  							{
   198  								Process: Process{
   199  									GUID:       "some-process-web-guid",
   200  									Type:       "web",
   201  									Command:    *types.NewFilteredString("[Redacted Value]"),
   202  									MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
   203  									AppGUID:    "some-app-guid",
   204  								},
   205  								InstanceDetails: []ProcessInstance{
   206  									{
   207  										State:       constant.ProcessInstanceRunning,
   208  										CPU:         0.01,
   209  										MemoryUsage: 1000000,
   210  										DiskUsage:   2000000,
   211  										MemoryQuota: 3000000,
   212  										DiskQuota:   4000000,
   213  										Index:       0,
   214  									},
   215  								},
   216  							},
   217  							{
   218  								Process: Process{
   219  									GUID:       "some-process-guid",
   220  									MemoryInMB: types.NullUint64{Value: 32, IsSet: true},
   221  									Type:       "some-type",
   222  									Command:    *types.NewFilteredString("[Redacted Value]"),
   223  									AppGUID:    "some-app-guid",
   224  								},
   225  								InstanceDetails: []ProcessInstance{
   226  									{
   227  										State:       constant.ProcessInstanceRunning,
   228  										CPU:         0.01,
   229  										MemoryUsage: 1000000,
   230  										DiskUsage:   2000000,
   231  										MemoryQuota: 3000000,
   232  										DiskQuota:   4000000,
   233  										Index:       0,
   234  									},
   235  								},
   236  							},
   237  						},
   238  						Routes: []resources.Route{
   239  							{
   240  								GUID: "some-route-guid",
   241  								Destinations: []resources.RouteDestination{
   242  									{
   243  										App: resources.RouteDestinationApp{
   244  											GUID: "some-app-guid",
   245  										},
   246  									},
   247  								},
   248  							},
   249  							{
   250  								GUID: "some-other-route-guid",
   251  								Destinations: []resources.RouteDestination{
   252  									{
   253  										App: resources.RouteDestinationApp{
   254  											GUID: "some-app-guid",
   255  										},
   256  									},
   257  								},
   258  							},
   259  						},
   260  					},
   261  				}))
   262  
   263  				Expect(warnings).To(ConsistOf(
   264  					"get-apps-warning",
   265  					"get-app-processes-warning",
   266  					"get-process-instances-warning",
   267  					"get-process-instances-warning",
   268  					"get-routes-warning",
   269  				))
   270  
   271  				Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
   272  				Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
   273  					ccv3.Query{Key: ccv3.OrderBy, Values: []string{"name"}},
   274  					ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}},
   275  					ccv3.Query{Key: ccv3.LabelSelectorFilter, Values: []string{"some-key=some-value"}},
   276  				))
   277  
   278  				Expect(fakeCloudControllerClient.GetProcessesCallCount()).To(Equal(1))
   279  				Expect(fakeCloudControllerClient.GetProcessesArgsForCall(0)).To(ConsistOf(
   280  					ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{"some-app-guid"}},
   281  				))
   282  
   283  				Expect(fakeCloudControllerClient.GetProcessInstancesCallCount()).To(Equal(2))
   284  				Expect(fakeCloudControllerClient.GetProcessInstancesArgsForCall(0)).To(Equal("some-process-guid"))
   285  			})
   286  
   287  			When("there is no label selector", func() {
   288  				BeforeEach(func() {
   289  					labelSelector = ""
   290  				})
   291  				It("doesn't pass a label selection filter", func() {
   292  					Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
   293  					Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
   294  						ccv3.Query{Key: ccv3.OrderBy, Values: []string{"name"}},
   295  						ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}},
   296  					))
   297  				})
   298  			})
   299  		})
   300  
   301  		When("getting the application fails", func() {
   302  			BeforeEach(func() {
   303  				fakeCloudControllerClient.GetApplicationsReturns(
   304  					[]resources.Application{
   305  						{
   306  							Name:  "some-app-name",
   307  							GUID:  "some-app-guid",
   308  							State: constant.ApplicationStarted,
   309  						},
   310  					},
   311  					ccv3.Warnings{"get-apps-warning"},
   312  					errors.New("failed to get app"),
   313  				)
   314  			})
   315  
   316  			It("returns the error and warnings", func() {
   317  				Expect(executeErr).To(MatchError("failed to get app"))
   318  				Expect(warnings).To(ConsistOf("get-apps-warning"))
   319  			})
   320  		})
   321  	})
   322  
   323  	Describe("GetDetailedAppSummary", func() {
   324  		var (
   325  			appName              string
   326  			spaceGUID            string
   327  			withObfuscatedValues bool
   328  
   329  			summary    DetailedApplicationSummary
   330  			warnings   Warnings
   331  			executeErr error
   332  		)
   333  
   334  		BeforeEach(func() {
   335  			appName = "some-app-name"
   336  			spaceGUID = "some-space-guid"
   337  			withObfuscatedValues = true
   338  		})
   339  
   340  		JustBeforeEach(func() {
   341  			summary, warnings, executeErr = actor.GetDetailedAppSummary(appName, spaceGUID, withObfuscatedValues)
   342  		})
   343  
   344  		When("getting the application is successful", func() {
   345  			BeforeEach(func() {
   346  				fakeCloudControllerClient.GetApplicationsReturns(
   347  					[]resources.Application{
   348  						{
   349  							Name:  "some-app-name",
   350  							GUID:  "some-app-guid",
   351  							State: constant.ApplicationStarted,
   352  						},
   353  					},
   354  					ccv3.Warnings{"get-apps-warning"},
   355  					nil,
   356  				)
   357  			})
   358  
   359  			When("getting the process information is successful", func() {
   360  				BeforeEach(func() {
   361  					listedProcesses := []ccv3.Process{
   362  						{
   363  							GUID:       "some-process-guid",
   364  							Type:       "some-type",
   365  							Command:    *types.NewFilteredString("[Redacted Value]"),
   366  							MemoryInMB: types.NullUint64{Value: 32, IsSet: true},
   367  						},
   368  						{
   369  							GUID:       "some-process-web-guid",
   370  							Type:       "web",
   371  							Command:    *types.NewFilteredString("[Redacted Value]"),
   372  							MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
   373  						},
   374  					}
   375  					fakeCloudControllerClient.GetApplicationProcessesReturns(
   376  						listedProcesses,
   377  						ccv3.Warnings{"get-app-processes-warning"},
   378  						nil,
   379  					)
   380  
   381  					explicitlyCalledProcess := listedProcesses[0]
   382  					explicitlyCalledProcess.Command = *types.NewFilteredString("some-start-command")
   383  					fakeCloudControllerClient.GetProcessReturnsOnCall(
   384  						0,
   385  						explicitlyCalledProcess,
   386  						ccv3.Warnings{"get-process-by-type-warning"},
   387  						nil,
   388  					)
   389  
   390  					fakeCloudControllerClient.GetProcessReturnsOnCall(
   391  						1,
   392  						listedProcesses[1],
   393  						ccv3.Warnings{"get-process-by-type-warning"},
   394  						nil,
   395  					)
   396  
   397  					fakeCloudControllerClient.GetProcessSidecarsReturns(
   398  						[]ccv3.Sidecar{
   399  							{
   400  								GUID:    "sidecar-guid",
   401  								Name:    "sidecar_name",
   402  								Command: *types.NewFilteredString("my-sidecar-command"),
   403  							},
   404  						},
   405  						ccv3.Warnings{"get-process-sidecars-warning"},
   406  						nil,
   407  					)
   408  
   409  					fakeCloudControllerClient.GetProcessInstancesReturns(
   410  						[]ccv3.ProcessInstance{
   411  							{
   412  								State:       constant.ProcessInstanceRunning,
   413  								CPU:         0.01,
   414  								MemoryUsage: 1000000,
   415  								DiskUsage:   2000000,
   416  								MemoryQuota: 3000000,
   417  								DiskQuota:   4000000,
   418  								Index:       0,
   419  							},
   420  						},
   421  						ccv3.Warnings{"get-process-instances-warning"},
   422  						nil,
   423  					)
   424  				})
   425  
   426  				When("getting current droplet succeeds", func() {
   427  					BeforeEach(func() {
   428  						fakeCloudControllerClient.GetApplicationDropletCurrentReturns(
   429  							resources.Droplet{
   430  								Stack: "some-stack",
   431  								Buildpacks: []resources.DropletBuildpack{
   432  									{
   433  										Name: "some-buildpack",
   434  									},
   435  								},
   436  								Image: "docker/some-image",
   437  							},
   438  							ccv3.Warnings{"get-app-droplet-warning"},
   439  							nil,
   440  						)
   441  					})
   442  
   443  					When("getting application routes succeeds", func() {
   444  						BeforeEach(func() {
   445  							fakeCloudControllerClient.GetApplicationRoutesReturns(
   446  								[]resources.Route{
   447  									{GUID: "some-route-guid"},
   448  									{GUID: "some-other-route-guid"},
   449  								},
   450  								ccv3.Warnings{"get-routes-warning"},
   451  								nil,
   452  							)
   453  						})
   454  
   455  						It("returns the summary and warnings with droplet information", func() {
   456  							Expect(executeErr).ToNot(HaveOccurred())
   457  							Expect(summary).To(Equal(DetailedApplicationSummary{
   458  								ApplicationSummary: v7action.ApplicationSummary{
   459  									Application: resources.Application{
   460  										Name:  "some-app-name",
   461  										GUID:  "some-app-guid",
   462  										State: constant.ApplicationStarted,
   463  									},
   464  									ProcessSummaries: []ProcessSummary{
   465  										{
   466  											Process: Process{
   467  												GUID:       "some-process-web-guid",
   468  												Type:       "web",
   469  												Command:    *types.NewFilteredString("[Redacted Value]"),
   470  												MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
   471  											},
   472  											Sidecars: []Sidecar{
   473  												{
   474  													GUID:    "sidecar-guid",
   475  													Name:    "sidecar_name",
   476  													Command: *types.NewFilteredString("my-sidecar-command"),
   477  												},
   478  											},
   479  											InstanceDetails: []ProcessInstance{
   480  												{
   481  													State:       constant.ProcessInstanceRunning,
   482  													CPU:         0.01,
   483  													MemoryUsage: 1000000,
   484  													DiskUsage:   2000000,
   485  													MemoryQuota: 3000000,
   486  													DiskQuota:   4000000,
   487  													Index:       0,
   488  												},
   489  											},
   490  										},
   491  										{
   492  											Process: Process{
   493  												GUID:       "some-process-guid",
   494  												MemoryInMB: types.NullUint64{Value: 32, IsSet: true},
   495  												Type:       "some-type",
   496  												Command:    *types.NewFilteredString("some-start-command"),
   497  											},
   498  											Sidecars: []Sidecar{
   499  												{
   500  													GUID:    "sidecar-guid",
   501  													Name:    "sidecar_name",
   502  													Command: *types.NewFilteredString("my-sidecar-command"),
   503  												},
   504  											},
   505  											InstanceDetails: []ProcessInstance{
   506  												{
   507  													State:       constant.ProcessInstanceRunning,
   508  													CPU:         0.01,
   509  													MemoryUsage: 1000000,
   510  													DiskUsage:   2000000,
   511  													MemoryQuota: 3000000,
   512  													DiskQuota:   4000000,
   513  													Index:       0,
   514  												},
   515  											},
   516  										},
   517  									},
   518  									Routes: []resources.Route{
   519  										{GUID: "some-route-guid"},
   520  										{GUID: "some-other-route-guid"},
   521  									},
   522  								},
   523  								CurrentDroplet: resources.Droplet{
   524  									Stack: "some-stack",
   525  									Image: "docker/some-image",
   526  									Buildpacks: []resources.DropletBuildpack{
   527  										{
   528  											Name: "some-buildpack",
   529  										},
   530  									},
   531  								},
   532  							}))
   533  
   534  							Expect(warnings).To(ConsistOf(
   535  								"get-apps-warning",
   536  								"get-app-processes-warning",
   537  								"get-process-by-type-warning",
   538  								"get-process-by-type-warning",
   539  								"get-process-instances-warning",
   540  								"get-process-instances-warning",
   541  								"get-process-sidecars-warning",
   542  								"get-process-sidecars-warning",
   543  								"get-app-droplet-warning",
   544  								"get-routes-warning",
   545  							))
   546  
   547  							Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
   548  							Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
   549  								ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app-name"}},
   550  								ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}},
   551  							))
   552  
   553  							Expect(fakeCloudControllerClient.GetApplicationDropletCurrentCallCount()).To(Equal(1))
   554  							Expect(fakeCloudControllerClient.GetApplicationDropletCurrentArgsForCall(0)).To(Equal("some-app-guid"))
   555  
   556  							Expect(fakeCloudControllerClient.GetApplicationProcessesCallCount()).To(Equal(1))
   557  							Expect(fakeCloudControllerClient.GetApplicationProcessesArgsForCall(0)).To(Equal("some-app-guid"))
   558  
   559  							Expect(fakeCloudControllerClient.GetProcessCallCount()).To(Equal(2))
   560  							processGUID := fakeCloudControllerClient.GetProcessArgsForCall(0)
   561  							Expect(processGUID).To(Equal("some-process-guid"))
   562  
   563  							Expect(fakeCloudControllerClient.GetProcessInstancesCallCount()).To(Equal(2))
   564  							Expect(fakeCloudControllerClient.GetProcessInstancesArgsForCall(0)).To(Equal("some-process-guid"))
   565  						})
   566  					})
   567  
   568  					When("getting application routes fails", func() {
   569  						BeforeEach(func() {
   570  							fakeCloudControllerClient.GetApplicationRoutesReturns(nil, ccv3.Warnings{"get-routes-warnings"}, errors.New("some-error"))
   571  						})
   572  
   573  						It("returns the warnings and error", func() {
   574  							Expect(executeErr).To(MatchError("some-error"))
   575  							Expect(warnings).To(ConsistOf(
   576  								"get-apps-warning",
   577  								"get-app-processes-warning",
   578  								"get-process-by-type-warning",
   579  								"get-process-by-type-warning",
   580  								"get-process-instances-warning",
   581  								"get-process-instances-warning",
   582  								"get-process-sidecars-warning",
   583  								"get-process-sidecars-warning",
   584  								"get-routes-warnings",
   585  							))
   586  						})
   587  					})
   588  				})
   589  
   590  				When("app does not have current droplet", func() {
   591  					BeforeEach(func() {
   592  						fakeCloudControllerClient.GetApplicationDropletCurrentReturns(
   593  							resources.Droplet{},
   594  							ccv3.Warnings{"get-app-droplet-warning"},
   595  							ccerror.DropletNotFoundError{},
   596  						)
   597  					})
   598  
   599  					It("returns the summary and warnings without droplet information", func() {
   600  						Expect(executeErr).ToNot(HaveOccurred())
   601  						Expect(summary).To(Equal(DetailedApplicationSummary{
   602  							ApplicationSummary: v7action.ApplicationSummary{
   603  								Application: resources.Application{
   604  									Name:  "some-app-name",
   605  									GUID:  "some-app-guid",
   606  									State: constant.ApplicationStarted,
   607  								},
   608  								ProcessSummaries: []ProcessSummary{
   609  									{
   610  										Process: Process{
   611  											GUID:       "some-process-web-guid",
   612  											Type:       "web",
   613  											Command:    *types.NewFilteredString("[Redacted Value]"),
   614  											MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
   615  										},
   616  										Sidecars: []Sidecar{
   617  											{
   618  												GUID:    "sidecar-guid",
   619  												Name:    "sidecar_name",
   620  												Command: *types.NewFilteredString("my-sidecar-command"),
   621  											},
   622  										},
   623  										InstanceDetails: []ProcessInstance{
   624  											{
   625  												State:       constant.ProcessInstanceRunning,
   626  												CPU:         0.01,
   627  												MemoryUsage: 1000000,
   628  												DiskUsage:   2000000,
   629  												MemoryQuota: 3000000,
   630  												DiskQuota:   4000000,
   631  												Index:       0,
   632  											},
   633  										},
   634  									},
   635  									{
   636  										Process: Process{
   637  											GUID:       "some-process-guid",
   638  											MemoryInMB: types.NullUint64{Value: 32, IsSet: true},
   639  											Type:       "some-type",
   640  											Command:    *types.NewFilteredString("some-start-command"),
   641  										},
   642  										Sidecars: []Sidecar{
   643  											{
   644  												GUID:    "sidecar-guid",
   645  												Name:    "sidecar_name",
   646  												Command: *types.NewFilteredString("my-sidecar-command"),
   647  											},
   648  										},
   649  										InstanceDetails: []ProcessInstance{
   650  											{
   651  												State:       constant.ProcessInstanceRunning,
   652  												CPU:         0.01,
   653  												MemoryUsage: 1000000,
   654  												DiskUsage:   2000000,
   655  												MemoryQuota: 3000000,
   656  												DiskQuota:   4000000,
   657  												Index:       0,
   658  											},
   659  										},
   660  									},
   661  								},
   662  							},
   663  						}))
   664  
   665  						Expect(warnings).To(ConsistOf(
   666  							"get-apps-warning",
   667  							"get-app-processes-warning",
   668  							"get-process-by-type-warning",
   669  							"get-process-by-type-warning",
   670  							"get-process-instances-warning",
   671  							"get-process-instances-warning",
   672  							"get-process-sidecars-warning",
   673  							"get-process-sidecars-warning",
   674  							"get-app-droplet-warning",
   675  						))
   676  					})
   677  				})
   678  
   679  				When("getting the current droplet returns an error", func() {
   680  					var expectedErr error
   681  
   682  					BeforeEach(func() {
   683  						expectedErr = errors.New("some error")
   684  						fakeCloudControllerClient.GetApplicationDropletCurrentReturns(
   685  							resources.Droplet{},
   686  							ccv3.Warnings{"get-droplet-warning"},
   687  							expectedErr,
   688  						)
   689  					})
   690  
   691  					It("returns the error", func() {
   692  						Expect(executeErr).To(Equal(expectedErr))
   693  						Expect(warnings).To(ConsistOf(
   694  							"get-apps-warning",
   695  							"get-app-processes-warning",
   696  							"get-process-by-type-warning",
   697  							"get-process-by-type-warning",
   698  							"get-process-instances-warning",
   699  							"get-process-instances-warning",
   700  							"get-process-sidecars-warning",
   701  							"get-process-sidecars-warning",
   702  							"get-droplet-warning",
   703  						))
   704  					})
   705  				})
   706  			})
   707  
   708  			When("getting the app processes returns an error", func() {
   709  				var expectedErr error
   710  
   711  				BeforeEach(func() {
   712  					fakeCloudControllerClient.GetApplicationProcessesReturns(
   713  						[]ccv3.Process{
   714  							{
   715  								GUID: "some-process-guid",
   716  								Type: "some-type",
   717  							},
   718  						},
   719  						ccv3.Warnings{"get-app-processes-warning"},
   720  						nil,
   721  					)
   722  
   723  					fakeCloudControllerClient.GetProcessReturns(
   724  						ccv3.Process{},
   725  						ccv3.Warnings{"get-process-warning"},
   726  						nil,
   727  					)
   728  
   729  					expectedErr = errors.New("some error")
   730  					fakeCloudControllerClient.GetProcessInstancesReturns(
   731  						[]ccv3.ProcessInstance{},
   732  						ccv3.Warnings{"get-process-instances-warning"},
   733  						expectedErr,
   734  					)
   735  				})
   736  
   737  				It("returns the error and warnings", func() {
   738  					Expect(executeErr).To(Equal(expectedErr))
   739  					Expect(warnings).To(ConsistOf("get-apps-warning", "get-app-processes-warning", "get-process-warning", "get-process-instances-warning"))
   740  				})
   741  			})
   742  		})
   743  
   744  		When("no applications are returned", func() {
   745  			BeforeEach(func() {
   746  				fakeCloudControllerClient.GetApplicationsReturns(
   747  					[]resources.Application{},
   748  					ccv3.Warnings{"get-apps-warning"},
   749  					nil,
   750  				)
   751  			})
   752  
   753  			It("returns an error and warnings", func() {
   754  				Expect(executeErr).To(MatchError(actionerror.ApplicationNotFoundError{Name: appName}))
   755  				Expect(warnings).To(ConsistOf("get-apps-warning"))
   756  			})
   757  		})
   758  
   759  		When("getting the application fails", func() {
   760  			BeforeEach(func() {
   761  				fakeCloudControllerClient.GetApplicationsReturns(
   762  					[]resources.Application{
   763  						{
   764  							Name:  "some-app-name",
   765  							GUID:  "some-app-guid",
   766  							State: constant.ApplicationStarted,
   767  						},
   768  					},
   769  					ccv3.Warnings{"get-apps-warning"},
   770  					errors.New("failed to get app"),
   771  				)
   772  			})
   773  
   774  			It("returns the error and warnings", func() {
   775  				Expect(executeErr).To(MatchError("failed to get app"))
   776  				Expect(warnings).To(ConsistOf("get-apps-warning"))
   777  			})
   778  		})
   779  	})
   780  })