github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/command/v6/restart_command_test.go (about) 1 package v6_test 2 3 import ( 4 "errors" 5 "time" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 "code.cloudfoundry.org/cli/actor/v2action" 9 "code.cloudfoundry.org/cli/actor/v2v3action" 10 "code.cloudfoundry.org/cli/actor/v3action" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 12 "code.cloudfoundry.org/cli/command/commandfakes" 13 "code.cloudfoundry.org/cli/command/translatableerror" 14 . "code.cloudfoundry.org/cli/command/v6" 15 "code.cloudfoundry.org/cli/command/v6/shared/sharedfakes" 16 "code.cloudfoundry.org/cli/command/v6/v6fakes" 17 "code.cloudfoundry.org/cli/types" 18 "code.cloudfoundry.org/cli/util/configv3" 19 "code.cloudfoundry.org/cli/util/ui" 20 . "github.com/onsi/ginkgo" 21 . "github.com/onsi/gomega" 22 . "github.com/onsi/gomega/gbytes" 23 ) 24 25 var _ = Describe("Restart Command", func() { 26 var ( 27 cmd RestartCommand 28 testUI *ui.UI 29 fakeConfig *commandfakes.FakeConfig 30 fakeSharedActor *commandfakes.FakeSharedActor 31 fakeApplicationSummaryActor *sharedfakes.FakeApplicationSummaryActor 32 fakeActor *v6fakes.FakeRestartActor 33 binaryName string 34 executeErr error 35 allLogsWritten chan bool 36 ) 37 38 BeforeEach(func() { 39 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 40 fakeConfig = new(commandfakes.FakeConfig) 41 fakeSharedActor = new(commandfakes.FakeSharedActor) 42 fakeActor = new(v6fakes.FakeRestartActor) 43 fakeApplicationSummaryActor = new(sharedfakes.FakeApplicationSummaryActor) 44 45 cmd = RestartCommand{ 46 UI: testUI, 47 Config: fakeConfig, 48 SharedActor: fakeSharedActor, 49 Actor: fakeActor, 50 ApplicationSummaryActor: fakeApplicationSummaryActor, 51 } 52 53 cmd.RequiredArgs.AppName = "some-app" 54 55 binaryName = "faceman" 56 fakeConfig.BinaryNameReturns(binaryName) 57 58 var err error 59 testUI.TimezoneLocation, err = time.LoadLocation("America/Los_Angeles") 60 Expect(err).NotTo(HaveOccurred()) 61 62 fakeActor.RestartApplicationStub = func(app v2action.Application) (<-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 63 appState := make(chan v2action.ApplicationStateChange) 64 warnings := make(chan string) 65 errs := make(chan error) 66 67 go func() { 68 <-allLogsWritten 69 appState <- v2action.ApplicationStateStopping 70 appState <- v2action.ApplicationStateStaging 71 appState <- v2action.ApplicationStateStarting 72 close(appState) 73 close(warnings) 74 close(errs) 75 }() 76 77 return appState, warnings, errs 78 } 79 allLogsWritten, fakeActor.GetStreamingLogsStub = GetStreamingLogsStub([]string{}, []string{}) 80 }) 81 82 JustBeforeEach(func() { 83 executeErr = cmd.Execute(nil) 84 }) 85 86 When("checking target fails", func() { 87 BeforeEach(func() { 88 fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName}) 89 }) 90 91 It("returns an error if the check fails", func() { 92 Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: "faceman"})) 93 94 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 95 checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0) 96 Expect(checkTargetedOrg).To(BeTrue()) 97 Expect(checkTargetedSpace).To(BeTrue()) 98 }) 99 }) 100 101 When("the user is logged in, and org and space are targeted", func() { 102 BeforeEach(func() { 103 fakeConfig.HasTargetedOrganizationReturns(true) 104 fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "some-org"}) 105 fakeConfig.HasTargetedSpaceReturns(true) 106 fakeConfig.TargetedSpaceReturns(configv3.Space{ 107 GUID: "some-space-guid", 108 Name: "some-space"}) 109 fakeConfig.CurrentUserReturns( 110 configv3.User{Name: "some-user"}, 111 nil) 112 }) 113 114 When("getting the current user returns an error", func() { 115 var expectedErr error 116 117 BeforeEach(func() { 118 expectedErr = errors.New("getting current user error") 119 fakeConfig.CurrentUserReturns( 120 configv3.User{}, 121 expectedErr) 122 }) 123 124 It("returns the error", func() { 125 Expect(executeErr).To(MatchError(expectedErr)) 126 }) 127 }) 128 129 It("displays flavor text", func() { 130 Expect(testUI.Out).To(Say("Restarting app some-app in org some-org / space some-space as some-user...")) 131 }) 132 133 When("the app exists", func() { 134 When("the app is started", func() { 135 BeforeEach(func() { 136 fakeActor.GetApplicationByNameAndSpaceReturns( 137 v2action.Application{State: constant.ApplicationStarted}, 138 v2action.Warnings{"warning-1", "warning-2"}, 139 nil, 140 ) 141 }) 142 143 It("stops and starts the app", func() { 144 Expect(executeErr).ToNot(HaveOccurred()) 145 146 Expect(testUI.Out).Should(Say("Stopping app...")) 147 Expect(testUI.Out).Should(Say("Staging app and tracing logs...")) 148 Expect(testUI.Out).Should(Say("Waiting for app to start...")) 149 Expect(testUI.Err).To(Say("warning-1")) 150 Expect(testUI.Err).To(Say("warning-2")) 151 152 Expect(fakeActor.RestartApplicationCallCount()).To(Equal(1)) 153 }) 154 }) 155 156 When("the app is not already started", func() { 157 BeforeEach(func() { 158 fakeActor.GetApplicationByNameAndSpaceReturns( 159 v2action.Application{GUID: "app-guid", State: constant.ApplicationStopped}, 160 v2action.Warnings{"warning-1", "warning-2"}, 161 nil, 162 ) 163 }) 164 165 It("starts the app", func() { 166 Expect(executeErr).ToNot(HaveOccurred()) 167 168 Expect(testUI.Err).To(Say("warning-1")) 169 Expect(testUI.Err).To(Say("warning-2")) 170 171 Expect(fakeActor.RestartApplicationCallCount()).To(Equal(1)) 172 app := fakeActor.RestartApplicationArgsForCall(0) 173 Expect(app.GUID).To(Equal("app-guid")) 174 }) 175 176 When("passed an appStarting message", func() { 177 BeforeEach(func() { 178 allLogsWritten, fakeActor.GetStreamingLogsStub = GetStreamingLogsStub([]string{"log message 1", "log message 2"}, []string{}) 179 fakeActor.RestartApplicationStub = func(app v2action.Application) (<-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 180 appState := make(chan v2action.ApplicationStateChange) 181 warnings := make(chan string) 182 errs := make(chan error) 183 184 go func() { 185 <-allLogsWritten 186 appState <- v2action.ApplicationStateStopping 187 appState <- v2action.ApplicationStateStaging 188 appState <- v2action.ApplicationStateStarting 189 close(appState) 190 close(warnings) 191 close(errs) 192 }() 193 194 return appState, warnings, errs 195 } 196 }) 197 198 It("displays the streaming logs", func() { 199 Expect(executeErr).ToNot(HaveOccurred()) 200 Expect(testUI.Out).To(Say("log message 1")) 201 Expect(testUI.Out).To(Say("log message 2")) 202 }) 203 It("displays the application stage-change logs", func() { 204 Expect(executeErr).ToNot(HaveOccurred()) 205 Expect(testUI.Out).To(Say("Waiting for app to start...")) 206 }) 207 }) 208 209 When("passed a warning", func() { 210 Context("while logcache is still logging", func() { 211 BeforeEach(func() { 212 fakeActor.RestartApplicationStub = func(app v2action.Application) (<-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 213 appState := make(chan v2action.ApplicationStateChange) 214 warnings := make(chan string) 215 errs := make(chan error) 216 217 go func() { 218 <-allLogsWritten 219 warnings <- "warning 1" 220 warnings <- "warning 2" 221 close(appState) 222 close(warnings) 223 close(errs) 224 }() 225 226 return appState, warnings, errs 227 } 228 }) 229 230 It("displays the warnings to STDERR", func() { 231 Expect(executeErr).ToNot(HaveOccurred()) 232 Expect(testUI.Err).To(Say("warning 1")) 233 Expect(testUI.Err).To(Say("warning 2")) 234 }) 235 }) 236 237 Context("while logcache is no longer logging", func() { 238 BeforeEach(func() { 239 fakeActor.RestartApplicationStub = func(app v2action.Application) (<-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 240 appState := make(chan v2action.ApplicationStateChange) 241 warnings := make(chan string) 242 errs := make(chan error) 243 244 go func() { 245 <-allLogsWritten 246 warnings <- "warning 1" 247 warnings <- "warning 2" 248 warnings <- "warning 3" 249 warnings <- "warning 4" 250 close(appState) 251 close(warnings) 252 close(errs) 253 }() 254 255 return appState, warnings, errs 256 } 257 }) 258 259 It("displays the warnings to STDERR", func() { 260 Expect(executeErr).ToNot(HaveOccurred()) 261 Expect(testUI.Err).To(Say("warning 1")) 262 Expect(testUI.Err).To(Say("warning 2")) 263 Expect(testUI.Err).To(Say("warning 3")) 264 Expect(testUI.Err).To(Say("warning 4")) 265 }) 266 }) 267 }) 268 269 When("passed an API err", func() { 270 var apiErr error 271 272 BeforeEach(func() { 273 fakeActor.RestartApplicationStub = func(app v2action.Application) (<-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 274 appState := make(chan v2action.ApplicationStateChange) 275 warnings := make(chan string) 276 errs := make(chan error) 277 278 go func() { 279 <-allLogsWritten 280 errs <- apiErr 281 close(appState) 282 close(warnings) 283 close(errs) 284 }() 285 286 return appState, warnings, errs 287 } 288 }) 289 290 Context("an unexpected error", func() { 291 BeforeEach(func() { 292 apiErr = errors.New("err log message") 293 }) 294 295 It("stops logging and returns the error", func() { 296 Expect(executeErr).To(MatchError(apiErr)) 297 }) 298 }) 299 300 Context("staging failed", func() { 301 BeforeEach(func() { 302 apiErr = actionerror.StagingFailedError{Reason: "Something, but not nothing"} 303 }) 304 305 It("stops logging and returns StagingFailedError", func() { 306 Expect(executeErr).To(MatchError(translatableerror.StagingFailedError{Message: "Something, but not nothing"})) 307 }) 308 }) 309 310 Context("staging timed out", func() { 311 BeforeEach(func() { 312 apiErr = actionerror.StagingTimeoutError{AppName: "some-app", Timeout: time.Nanosecond} 313 }) 314 315 It("stops logging and returns StagingTimeoutError", func() { 316 Expect(executeErr).To(MatchError(translatableerror.StagingTimeoutError{AppName: "some-app", Timeout: time.Nanosecond})) 317 }) 318 }) 319 320 When("the app instance crashes", func() { 321 BeforeEach(func() { 322 apiErr = actionerror.ApplicationInstanceCrashedError{Name: "some-app"} 323 }) 324 325 It("stops logging and returns ApplicationUnableToStartError", func() { 326 Expect(executeErr).To(MatchError(translatableerror.ApplicationUnableToStartError{AppName: "some-app", BinaryName: "faceman"})) 327 }) 328 }) 329 330 When("the app instance flaps", func() { 331 BeforeEach(func() { 332 apiErr = actionerror.ApplicationInstanceFlappingError{Name: "some-app"} 333 }) 334 335 It("stops logging and returns ApplicationUnableToStartError", func() { 336 Expect(executeErr).To(MatchError(translatableerror.ApplicationUnableToStartError{AppName: "some-app", BinaryName: "faceman"})) 337 }) 338 }) 339 340 Context("starting timeout", func() { 341 BeforeEach(func() { 342 apiErr = actionerror.StartupTimeoutError{Name: "some-app"} 343 }) 344 345 It("stops logging and returns StartupTimeoutError", func() { 346 Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{AppName: "some-app", BinaryName: "faceman"})) 347 }) 348 }) 349 }) 350 351 When("the app finishes starting", func() { 352 BeforeEach(func() { 353 fakeApplicationSummaryActor.GetApplicationSummaryByNameAndSpaceReturns( 354 v2v3action.ApplicationSummary{ 355 ApplicationSummary: v3action.ApplicationSummary{ 356 Application: v3action.Application{ 357 Name: "some-app", 358 }, 359 ProcessSummaries: v3action.ProcessSummaries{ 360 { 361 Process: v3action.Process{ 362 Type: "aba", 363 Command: *types.NewFilteredString("some-command-1"), 364 MemoryInMB: types.NullUint64{Value: 32, IsSet: true}, 365 DiskInMB: types.NullUint64{Value: 1024, IsSet: true}, 366 }, 367 }, 368 { 369 Process: v3action.Process{ 370 Type: "console", 371 Command: *types.NewFilteredString("some-command-2"), 372 MemoryInMB: types.NullUint64{Value: 16, IsSet: true}, 373 DiskInMB: types.NullUint64{Value: 512, IsSet: true}, 374 }, 375 }, 376 }, 377 }, 378 }, 379 v2v3action.Warnings{"combo-summary-warning"}, 380 nil) 381 }) 382 383 It("displays process information", func() { 384 Expect(executeErr).ToNot(HaveOccurred()) 385 386 Expect(testUI.Out).To(Say(`name:\s+%s`, "some-app")) 387 Expect(testUI.Out).To(Say(`type:\s+aba`)) 388 Expect(testUI.Out).To(Say(`instances:\s+0/0`)) 389 Expect(testUI.Out).To(Say(`memory usage:\s+32M`)) 390 Expect(testUI.Out).To(Say(`start command:\s+some-command-1`)) 391 Expect(testUI.Out).To(Say(`type:\s+console`)) 392 Expect(testUI.Out).To(Say(`instances:\s+0/0`)) 393 Expect(testUI.Out).To(Say(`memory usage:\s+16M`)) 394 Expect(testUI.Out).To(Say(`start command:\s+some-command-2`)) 395 396 Expect(testUI.Err).To(Say("combo-summary-warning")) 397 398 Expect(fakeApplicationSummaryActor.GetApplicationSummaryByNameAndSpaceCallCount()).To(Equal(1)) 399 passedAppName, spaceGUID, withObfuscatedValues := fakeApplicationSummaryActor.GetApplicationSummaryByNameAndSpaceArgsForCall(0) 400 Expect(passedAppName).To(Equal("some-app")) 401 Expect(spaceGUID).To(Equal("some-space-guid")) 402 Expect(withObfuscatedValues).To(BeTrue()) 403 }) 404 }) 405 }) 406 }) 407 408 When("the app does *not* exists", func() { 409 BeforeEach(func() { 410 fakeActor.GetApplicationByNameAndSpaceReturns( 411 v2action.Application{}, 412 v2action.Warnings{"warning-1", "warning-2"}, 413 actionerror.ApplicationNotFoundError{Name: "some-app"}, 414 ) 415 }) 416 417 It("returns back an error", func() { 418 Expect(executeErr).To(MatchError(actionerror.ApplicationNotFoundError{Name: "some-app"})) 419 420 Expect(testUI.Err).To(Say("warning-1")) 421 Expect(testUI.Err).To(Say("warning-2")) 422 }) 423 }) 424 }) 425 })