github.com/randomtask1155/cli@v6.41.1-0.20181227003417-a98eed78cbde+incompatible/actor/v7action/application_summary_test.go (about) 1 package v7action_test 2 3 import ( 4 "errors" 5 6 "code.cloudfoundry.org/cli/actor/v2action" 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/types" 13 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/ginkgo/extensions/table" 16 . "github.com/onsi/gomega" 17 ) 18 19 var _ = Describe("Application Summary 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("ApplicationSummary", func() { 31 DescribeTable("GetIsolationSegmentName", 32 func(summary ApplicationSummary, isoName string, exists bool) { 33 name, ok := summary.GetIsolationSegmentName() 34 Expect(ok).To(Equal(exists)) 35 Expect(name).To(Equal(isoName)) 36 }, 37 38 Entry("when the there are application instances and the isolationSegmentName is set", 39 ApplicationSummary{ 40 ProcessSummaries: ProcessSummaries{ 41 ProcessSummary{ 42 InstanceDetails: []ProcessInstance{ 43 {IsolationSegment: "some-name"}, 44 }, 45 }, 46 }, 47 }, 48 "some-name", 49 true, 50 ), 51 52 Entry("when the there are application instances and the isolationSegmentName is blank", 53 ApplicationSummary{ 54 ProcessSummaries: ProcessSummaries{ 55 ProcessSummary{InstanceDetails: []ProcessInstance{{}}}, 56 }, 57 }, 58 "", 59 false, 60 ), 61 62 Entry("when the there are no application instances", ApplicationSummary{ProcessSummaries: ProcessSummaries{{}}}, "", false), 63 Entry("when the there are no processes", ApplicationSummary{}, "", false), 64 ) 65 }) 66 67 Describe("GetApplicationSummaryByNameAndSpace", func() { 68 var ( 69 appName string 70 spaceGUID string 71 withObfuscatedValues bool 72 fakeRouteActor *v7actionfakes.FakeRouteActor 73 74 summary ApplicationSummary 75 warnings Warnings 76 executeErr error 77 ) 78 79 BeforeEach(func() { 80 appName = "some-app-name" 81 spaceGUID = "some-space-guid" 82 withObfuscatedValues = true 83 fakeRouteActor = new(v7actionfakes.FakeRouteActor) 84 }) 85 86 Context("when a route actor is not provided", func() { 87 JustBeforeEach(func() { 88 summary, warnings, executeErr = actor.GetApplicationSummaryByNameAndSpace(appName, spaceGUID, withObfuscatedValues, nil) 89 }) 90 91 When("retrieving the application is successful", func() { 92 BeforeEach(func() { 93 fakeCloudControllerClient.GetApplicationsReturns( 94 []ccv3.Application{ 95 { 96 Name: "some-app-name", 97 GUID: "some-app-guid", 98 State: constant.ApplicationStarted, 99 }, 100 }, 101 ccv3.Warnings{"some-warning"}, 102 nil, 103 ) 104 }) 105 106 When("retrieving the process information is successful", func() { 107 BeforeEach(func() { 108 listedProcesses := []ccv3.Process{ 109 { 110 GUID: "some-process-guid", 111 Type: "some-type", 112 Command: *types.NewFilteredString("[Redacted Value]"), 113 MemoryInMB: types.NullUint64{Value: 32, IsSet: true}, 114 }, 115 { 116 GUID: "some-process-web-guid", 117 Type: "web", 118 Command: *types.NewFilteredString("[Redacted Value]"), 119 MemoryInMB: types.NullUint64{Value: 64, IsSet: true}, 120 }, 121 } 122 fakeCloudControllerClient.GetApplicationProcessesReturns( 123 listedProcesses, 124 ccv3.Warnings{"some-process-warning"}, 125 nil, 126 ) 127 128 explicitlyCalledProcess := listedProcesses[0] 129 explicitlyCalledProcess.Command = *types.NewFilteredString("some-start-command") 130 fakeCloudControllerClient.GetApplicationProcessByTypeReturnsOnCall( 131 0, 132 explicitlyCalledProcess, 133 ccv3.Warnings{"get-process-by-type-warning"}, 134 nil, 135 ) 136 137 fakeCloudControllerClient.GetApplicationProcessByTypeReturnsOnCall( 138 1, 139 listedProcesses[1], 140 ccv3.Warnings{"get-process-by-type-warning"}, 141 nil, 142 ) 143 144 fakeCloudControllerClient.GetProcessInstancesReturns( 145 []ccv3.ProcessInstance{ 146 { 147 State: constant.ProcessInstanceRunning, 148 CPU: 0.01, 149 MemoryUsage: 1000000, 150 DiskUsage: 2000000, 151 MemoryQuota: 3000000, 152 DiskQuota: 4000000, 153 Index: 0, 154 }, 155 }, 156 ccv3.Warnings{"some-process-stats-warning"}, 157 nil, 158 ) 159 }) 160 161 When("app has droplet", func() { 162 BeforeEach(func() { 163 fakeCloudControllerClient.GetApplicationDropletCurrentReturns( 164 ccv3.Droplet{ 165 Stack: "some-stack", 166 Buildpacks: []ccv3.DropletBuildpack{ 167 { 168 Name: "some-buildpack", 169 }, 170 }, 171 Image: "docker/some-image", 172 }, 173 ccv3.Warnings{"some-droplet-warning"}, 174 nil, 175 ) 176 }) 177 178 It("returns the summary and warnings with droplet information", func() { 179 Expect(executeErr).ToNot(HaveOccurred()) 180 Expect(summary).To(Equal(ApplicationSummary{ 181 Application: Application{ 182 Name: "some-app-name", 183 GUID: "some-app-guid", 184 State: constant.ApplicationStarted, 185 }, 186 CurrentDroplet: Droplet{ 187 Stack: "some-stack", 188 Image: "docker/some-image", 189 Buildpacks: []Buildpack{ 190 { 191 Name: "some-buildpack", 192 }, 193 }, 194 }, 195 ProcessSummaries: []ProcessSummary{ 196 { 197 Process: Process{ 198 GUID: "some-process-web-guid", 199 Type: "web", 200 Command: *types.NewFilteredString("[Redacted Value]"), 201 MemoryInMB: types.NullUint64{Value: 64, IsSet: true}, 202 }, 203 InstanceDetails: []ProcessInstance{ 204 { 205 State: constant.ProcessInstanceRunning, 206 CPU: 0.01, 207 MemoryUsage: 1000000, 208 DiskUsage: 2000000, 209 MemoryQuota: 3000000, 210 DiskQuota: 4000000, 211 Index: 0, 212 }, 213 }, 214 }, 215 { 216 Process: Process{ 217 GUID: "some-process-guid", 218 MemoryInMB: types.NullUint64{Value: 32, IsSet: true}, 219 Type: "some-type", 220 Command: *types.NewFilteredString("some-start-command"), 221 }, 222 InstanceDetails: []ProcessInstance{ 223 { 224 State: constant.ProcessInstanceRunning, 225 CPU: 0.01, 226 MemoryUsage: 1000000, 227 DiskUsage: 2000000, 228 MemoryQuota: 3000000, 229 DiskQuota: 4000000, 230 Index: 0, 231 }, 232 }, 233 }, 234 }, 235 })) 236 Expect(warnings).To(ConsistOf("some-warning", "some-process-warning", "get-process-by-type-warning", "get-process-by-type-warning", "some-process-stats-warning", "some-process-stats-warning", "some-droplet-warning")) 237 238 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 239 Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf( 240 ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app-name"}}, 241 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}}, 242 )) 243 244 Expect(fakeCloudControllerClient.GetApplicationDropletCurrentCallCount()).To(Equal(1)) 245 Expect(fakeCloudControllerClient.GetApplicationDropletCurrentArgsForCall(0)).To(Equal("some-app-guid")) 246 247 Expect(fakeCloudControllerClient.GetApplicationProcessesCallCount()).To(Equal(1)) 248 Expect(fakeCloudControllerClient.GetApplicationProcessesArgsForCall(0)).To(Equal("some-app-guid")) 249 250 Expect(fakeCloudControllerClient.GetApplicationProcessByTypeCallCount()).To(Equal(2)) 251 appGUID, processType := fakeCloudControllerClient.GetApplicationProcessByTypeArgsForCall(0) 252 Expect(appGUID).To(Equal("some-app-guid")) 253 Expect(processType).To(Equal("some-type")) 254 255 Expect(fakeCloudControllerClient.GetProcessInstancesCallCount()).To(Equal(2)) 256 Expect(fakeCloudControllerClient.GetProcessInstancesArgsForCall(0)).To(Equal("some-process-guid")) 257 }) 258 259 When("getting the current droplet returns an error", func() { 260 var expectedErr error 261 262 BeforeEach(func() { 263 expectedErr = errors.New("some error") 264 fakeCloudControllerClient.GetApplicationDropletCurrentReturns( 265 ccv3.Droplet{}, 266 ccv3.Warnings{"some-droplet-warning"}, 267 expectedErr, 268 ) 269 }) 270 271 It("returns the error", func() { 272 Expect(executeErr).To(Equal(expectedErr)) 273 Expect(warnings).To(ConsistOf("some-warning", "some-process-warning", "get-process-by-type-warning", "get-process-by-type-warning", "some-process-stats-warning", "some-process-stats-warning", "some-droplet-warning")) 274 }) 275 }) 276 }) 277 278 When("app does not have current droplet", func() { 279 BeforeEach(func() { 280 fakeCloudControllerClient.GetApplicationDropletCurrentReturns( 281 ccv3.Droplet{}, 282 ccv3.Warnings{"some-droplet-warning"}, 283 ccerror.DropletNotFoundError{}, 284 ) 285 }) 286 287 It("returns the summary and warnings without droplet information", func() { 288 Expect(executeErr).ToNot(HaveOccurred()) 289 Expect(summary).To(Equal(ApplicationSummary{ 290 Application: Application{ 291 Name: "some-app-name", 292 GUID: "some-app-guid", 293 State: constant.ApplicationStarted, 294 }, 295 ProcessSummaries: []ProcessSummary{ 296 { 297 Process: Process{ 298 GUID: "some-process-web-guid", 299 Type: "web", 300 Command: *types.NewFilteredString("[Redacted Value]"), 301 MemoryInMB: types.NullUint64{Value: 64, IsSet: true}, 302 }, 303 InstanceDetails: []ProcessInstance{ 304 { 305 State: constant.ProcessInstanceRunning, 306 CPU: 0.01, 307 MemoryUsage: 1000000, 308 DiskUsage: 2000000, 309 MemoryQuota: 3000000, 310 DiskQuota: 4000000, 311 Index: 0, 312 }, 313 }, 314 }, 315 { 316 Process: Process{ 317 GUID: "some-process-guid", 318 MemoryInMB: types.NullUint64{Value: 32, IsSet: true}, 319 Type: "some-type", 320 Command: *types.NewFilteredString("some-start-command"), 321 }, 322 InstanceDetails: []ProcessInstance{ 323 { 324 State: constant.ProcessInstanceRunning, 325 CPU: 0.01, 326 MemoryUsage: 1000000, 327 DiskUsage: 2000000, 328 MemoryQuota: 3000000, 329 DiskQuota: 4000000, 330 Index: 0, 331 }, 332 }, 333 }, 334 }, 335 })) 336 Expect(warnings).To(ConsistOf("some-warning", "some-process-warning", "get-process-by-type-warning", "get-process-by-type-warning", "some-process-stats-warning", "some-process-stats-warning", "some-droplet-warning")) 337 }) 338 }) 339 340 }) 341 342 When("getting the app process instances returns an error", func() { 343 var expectedErr error 344 345 BeforeEach(func() { 346 fakeCloudControllerClient.GetApplicationProcessesReturns( 347 []ccv3.Process{ 348 { 349 GUID: "some-process-guid", 350 Type: "some-type", 351 }, 352 }, 353 ccv3.Warnings{"some-process-warning"}, 354 nil, 355 ) 356 357 fakeCloudControllerClient.GetApplicationProcessByTypeReturns( 358 ccv3.Process{}, 359 ccv3.Warnings{"get-process-by-type-warning"}, 360 nil, 361 ) 362 363 expectedErr = errors.New("some error") 364 fakeCloudControllerClient.GetProcessInstancesReturns( 365 []ccv3.ProcessInstance{}, 366 ccv3.Warnings{"some-process-stats-warning"}, 367 expectedErr, 368 ) 369 }) 370 371 It("returns the error", func() { 372 Expect(executeErr).To(Equal(expectedErr)) 373 Expect(warnings).To(ConsistOf("some-warning", "some-process-warning", "get-process-by-type-warning", "some-process-stats-warning")) 374 }) 375 }) 376 }) 377 378 When("getting the app processes returns an error", func() { 379 var expectedErr error 380 381 BeforeEach(func() { 382 fakeCloudControllerClient.GetApplicationsReturns( 383 []ccv3.Application{ 384 { 385 Name: "some-app-name", 386 GUID: "some-app-guid", 387 State: constant.ApplicationStarted, 388 }, 389 }, 390 ccv3.Warnings{"some-warning"}, 391 nil, 392 ) 393 394 expectedErr = errors.New("some error") 395 fakeCloudControllerClient.GetApplicationProcessesReturns( 396 []ccv3.Process{{Type: constant.ProcessTypeWeb}}, 397 ccv3.Warnings{"some-process-warning"}, 398 expectedErr, 399 ) 400 }) 401 402 It("returns the error", func() { 403 Expect(executeErr).To(Equal(expectedErr)) 404 Expect(warnings).To(ConsistOf("some-warning", "some-process-warning")) 405 }) 406 }) 407 }) 408 409 When("passed with a routeActor", func() { 410 BeforeEach(func() { 411 fakeCloudControllerClient.GetApplicationsReturns( 412 []ccv3.Application{ 413 { 414 Name: "some-app-name", 415 GUID: "some-app-guid", 416 State: constant.ApplicationStarted, 417 }, 418 }, 419 ccv3.Warnings{"some-warning"}, 420 nil, 421 ) 422 }) 423 424 JustBeforeEach(func() { 425 summary, warnings, executeErr = actor.GetApplicationSummaryByNameAndSpace(appName, spaceGUID, withObfuscatedValues, fakeRouteActor) 426 }) 427 428 When("getting the routes is successful", func() { 429 BeforeEach(func() { 430 routes := v2action.Routes{ 431 {GUID: "some-route-guid"}, 432 {GUID: "some-other-route-guid"}, 433 } 434 435 fakeRouteActor.GetApplicationRoutesReturns(routes, v2action.Warnings{"v2-routes-warnings"}, nil) 436 }) 437 438 It("retrieves and sets the application routes", func() { 439 Expect(warnings).To(ConsistOf("some-warning", "v2-routes-warnings")) 440 Expect(summary.Routes).To(ConsistOf( 441 v2action.Route{GUID: "some-route-guid"}, 442 v2action.Route{GUID: "some-other-route-guid"}, 443 )) 444 445 Expect(fakeRouteActor.GetApplicationRoutesCallCount()).To(Equal(1)) 446 Expect(fakeRouteActor.GetApplicationRoutesArgsForCall(0)).To(Equal("some-app-guid")) 447 }) 448 }) 449 450 When("getting the application routes errors", func() { 451 When("a generic error is returned", func() { 452 BeforeEach(func() { 453 fakeRouteActor.GetApplicationRoutesReturns(nil, v2action.Warnings{"v2-routes-warnings"}, errors.New("some-error")) 454 }) 455 456 It("returns warnings and the error", func() { 457 Expect(executeErr).To(MatchError("some-error")) 458 Expect(warnings).To(ConsistOf("some-warning", "v2-routes-warnings")) 459 }) 460 }) 461 462 When("a ResourceNotFoundError is returned", func() { 463 BeforeEach(func() { 464 fakeRouteActor.GetApplicationRoutesReturns(nil, v2action.Warnings{"v2-routes-warnings"}, ccerror.ResourceNotFoundError{}) 465 }) 466 467 It("adds warnings and continues", func() { 468 Expect(executeErr).ToNot(HaveOccurred()) 469 Expect(warnings).To(ConsistOf("some-warning", "v2-routes-warnings")) 470 }) 471 }) 472 }) 473 }) 474 }) 475 })