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