github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v7/logs_command_test.go (about)

     1  package v7_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"time"
     7  
     8  	"code.cloudfoundry.org/cli/actor/actionerror"
     9  	"code.cloudfoundry.org/cli/actor/v7action"
    10  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
    11  	"code.cloudfoundry.org/cli/command/commandfakes"
    12  	. "code.cloudfoundry.org/cli/command/v7"
    13  	"code.cloudfoundry.org/cli/command/v7/v7fakes"
    14  	"code.cloudfoundry.org/cli/util/configv3"
    15  	"code.cloudfoundry.org/cli/util/ui"
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/gomega"
    18  	. "github.com/onsi/gomega/gbytes"
    19  )
    20  
    21  var _ = Describe("logs command", func() {
    22  	var (
    23  		cmd             LogsCommand
    24  		testUI          *ui.UI
    25  		fakeConfig      *commandfakes.FakeConfig
    26  		fakeSharedActor *commandfakes.FakeSharedActor
    27  		fakeActor       *v7fakes.FakeLogsActor
    28  		logCacheClient  *v7actionfakes.FakeLogCacheClient
    29  		binaryName      string
    30  		executeErr      error
    31  	)
    32  
    33  	BeforeEach(func() {
    34  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    35  		fakeConfig = new(commandfakes.FakeConfig)
    36  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    37  		fakeActor = new(v7fakes.FakeLogsActor)
    38  		logCacheClient = new(v7actionfakes.FakeLogCacheClient)
    39  
    40  		cmd = LogsCommand{
    41  			UI:             testUI,
    42  			Config:         fakeConfig,
    43  			SharedActor:    fakeSharedActor,
    44  			Actor:          fakeActor,
    45  			LogCacheClient: logCacheClient,
    46  		}
    47  
    48  		binaryName = "faceman"
    49  		fakeConfig.BinaryNameReturns(binaryName)
    50  		cmd.RequiredArgs.AppName = "some-app"
    51  		fakeConfig.CurrentUserReturns(configv3.User{Name: "some-user"}, nil)
    52  	})
    53  
    54  	JustBeforeEach(func() {
    55  		executeErr = cmd.Execute(nil)
    56  	})
    57  
    58  	When("the checkTarget fails", func() {
    59  		BeforeEach(func() {
    60  			fakeSharedActor.CheckTargetReturns(
    61  				actionerror.NotLoggedInError{BinaryName: binaryName})
    62  		})
    63  		It("returns an error", func() {
    64  			orgRequired, spaceRequired := fakeSharedActor.CheckTargetArgsForCall(0)
    65  			Expect(orgRequired).To(BeTrue())
    66  			Expect(spaceRequired).To(BeTrue())
    67  
    68  			Expect(executeErr).To(MatchError(
    69  				actionerror.NotLoggedInError{BinaryName: binaryName}))
    70  		})
    71  	})
    72  
    73  	When("checkTarget succeeds", func() {
    74  		BeforeEach(func() {
    75  			fakeConfig.TargetedSpaceReturns(configv3.Space{
    76  				Name: "some-space-name",
    77  				GUID: "some-space-guid",
    78  			})
    79  			fakeConfig.TargetedOrganizationReturns(configv3.Organization{
    80  				Name: "some-org-name",
    81  			})
    82  		})
    83  
    84  		When("the --recent flag is provided", func() {
    85  			BeforeEach(func() {
    86  				cmd.Recent = true
    87  			})
    88  
    89  			It("displays flavor text", func() {
    90  				Expect(testUI.Out).To(Say("Retrieving logs for app some-app in org some-org-name / space some-space-name as some-user..."))
    91  			})
    92  
    93  			When("the logs actor returns an error", func() {
    94  				var expectedErr error
    95  				BeforeEach(func() {
    96  					expectedErr = errors.New("some-error")
    97  					fakeActor.GetRecentLogsForApplicationByNameAndSpaceReturns(
    98  						[]v7action.LogMessage{
    99  							*v7action.NewLogMessage(
   100  								"all your base are belong to us",
   101  								"1",
   102  								time.Unix(0, 0),
   103  								"app",
   104  								"1",
   105  							),
   106  						},
   107  						v7action.Warnings{"some-warning-1", "some-warning-2"},
   108  						expectedErr)
   109  				})
   110  
   111  				It("displays the errors along with the logs and warnings", func() {
   112  					Expect(executeErr).To(MatchError(expectedErr))
   113  					Expect(testUI.Out).To(Say("all your base are belong to us"))
   114  					Expect(testUI.Err).To(Say("some-warning-1"))
   115  					Expect(testUI.Err).To(Say("some-warning-2"))
   116  				})
   117  			})
   118  
   119  			When("the logs actor returns logs", func() {
   120  				BeforeEach(func() {
   121  					fakeActor.GetRecentLogsForApplicationByNameAndSpaceReturns(
   122  						[]v7action.LogMessage{
   123  							*v7action.NewLogMessage(
   124  								"i am message 1",
   125  								"1",
   126  								time.Unix(0, 0),
   127  								"app",
   128  								"1",
   129  							),
   130  							*v7action.NewLogMessage(
   131  								"i am message 2",
   132  								"1",
   133  								time.Unix(1, 0),
   134  								"another-app",
   135  								"2",
   136  							),
   137  						},
   138  						v7action.Warnings{"some-warning-1", "some-warning-2"},
   139  						nil)
   140  				})
   141  
   142  				It("displays the recent log messages and warnings", func() {
   143  					Expect(executeErr).NotTo(HaveOccurred())
   144  					Expect(testUI.Err).To(Say("some-warning-1"))
   145  					Expect(testUI.Err).To(Say("some-warning-2"))
   146  
   147  					Expect(testUI.Out).To(Say("i am message 1"))
   148  					Expect(testUI.Out).To(Say("i am message 2"))
   149  
   150  					Expect(fakeActor.GetRecentLogsForApplicationByNameAndSpaceCallCount()).To(Equal(1))
   151  					appName, spaceGUID, client := fakeActor.GetRecentLogsForApplicationByNameAndSpaceArgsForCall(0)
   152  
   153  					Expect(appName).To(Equal("some-app"))
   154  					Expect(spaceGUID).To(Equal("some-space-guid"))
   155  					Expect(client).To(Equal(logCacheClient))
   156  				})
   157  			})
   158  		})
   159  
   160  		When("the --recent flag is not provided", func() {
   161  			BeforeEach(func() {
   162  				cmd.Recent = false
   163  				fakeActor.ScheduleTokenRefreshStub = func() (chan bool, error) {
   164  					quitNowChannel := make(chan bool, 1)
   165  					go func() {
   166  						<-quitNowChannel
   167  					}()
   168  					return quitNowChannel, nil
   169  				}
   170  			})
   171  
   172  			When("the logs setup returns an error", func() {
   173  				var expectedErr error
   174  
   175  				BeforeEach(func() {
   176  					expectedErr = errors.New("some-error")
   177  					fakeActor.GetStreamingLogsForApplicationByNameAndSpaceReturns(nil,
   178  						nil,
   179  						nil,
   180  						v7action.Warnings{"some-warning-1",
   181  							"some-warning-2"},
   182  						expectedErr)
   183  				})
   184  
   185  				It("displays the error and all warnings", func() {
   186  					Expect(executeErr).To(MatchError(expectedErr))
   187  					Expect(testUI.Err).To(Say("some-warning-1"))
   188  					Expect(testUI.Err).To(Say("some-warning-2"))
   189  				})
   190  			})
   191  
   192  			When("the logs stream returns an error", func() {
   193  				var (
   194  					expectedErr                 error
   195  					cancelFunctionHasBeenCalled bool
   196  				)
   197  
   198  				BeforeEach(func() {
   199  					expectedErr = errors.New("banana")
   200  
   201  					fakeActor.GetStreamingLogsForApplicationByNameAndSpaceStub =
   202  						func(appName string, spaceGUID string, client v7action.LogCacheClient) (
   203  							<-chan v7action.LogMessage,
   204  							<-chan error,
   205  							context.CancelFunc,
   206  							v7action.Warnings, error) {
   207  							logStream := make(chan v7action.LogMessage)
   208  							errorStream := make(chan error)
   209  							cancelFunctionHasBeenCalled = false
   210  
   211  							cancelFunc := func() {
   212  								if cancelFunctionHasBeenCalled {
   213  									return
   214  								}
   215  								cancelFunctionHasBeenCalled = true
   216  								close(logStream)
   217  								close(errorStream)
   218  							}
   219  							go func() {
   220  								errorStream <- expectedErr
   221  							}()
   222  
   223  							return logStream, errorStream, cancelFunc, v7action.Warnings{"steve for all I care"}, nil
   224  						}
   225  				})
   226  
   227  				When("the token refresher returns an error", func() {
   228  					BeforeEach(func() {
   229  						cmd.Recent = false
   230  						fakeActor.ScheduleTokenRefreshReturns(nil, errors.New("firs swimming"))
   231  					})
   232  					It("displays the errors", func() {
   233  						Expect(executeErr).To(MatchError("firs swimming"))
   234  						Expect(fakeActor.GetStreamingLogsForApplicationByNameAndSpaceCallCount()).To(Equal(0))
   235  					})
   236  				})
   237  
   238  				It("displays the error and all warnings", func() {
   239  					Expect(executeErr).To(MatchError("banana"))
   240  					Expect(testUI.Err).To(Say("steve for all I care"))
   241  					Expect(cancelFunctionHasBeenCalled).To(BeTrue())
   242  				})
   243  			})
   244  
   245  			When("the logs actor returns logs", func() {
   246  				BeforeEach(func() {
   247  					fakeActor.GetStreamingLogsForApplicationByNameAndSpaceStub =
   248  						func(_ string, _ string, _ v7action.LogCacheClient) (
   249  							<-chan v7action.LogMessage,
   250  							<-chan error, context.CancelFunc,
   251  							v7action.Warnings,
   252  							error) {
   253  
   254  							logStream := make(chan v7action.LogMessage)
   255  							errorStream := make(chan error)
   256  
   257  							go func() {
   258  								logStream <- *v7action.NewLogMessage("Here are some staging logs!", "OUT", time.Now(), v7action.StagingLog, "sourceInstance") //TODO: is it ok to leave staging logs here?
   259  								logStream <- *v7action.NewLogMessage("Here are some other staging logs!", "OUT", time.Now(), v7action.StagingLog, "sourceInstance")
   260  								close(logStream)
   261  								close(errorStream)
   262  							}()
   263  
   264  							return logStream, errorStream, func() {}, v7action.Warnings{"some-warning-1", "some-warning-2"}, nil
   265  						}
   266  				})
   267  
   268  				It("displays flavor text", func() {
   269  					Expect(testUI.Out).To(Say("Retrieving logs for app some-app in org some-org-name / space some-space-name as some-user..."))
   270  				})
   271  
   272  				It("displays all streaming log messages and warnings", func() {
   273  					Expect(executeErr).NotTo(HaveOccurred())
   274  					Expect(testUI.Err).To(Say("some-warning-1"))
   275  					Expect(testUI.Err).To(Say("some-warning-2"))
   276  
   277  					Expect(testUI.Out).To(Say("Here are some staging logs!"))
   278  					Expect(testUI.Out).To(Say("Here are some other staging logs!"))
   279  
   280  					Expect(fakeActor.GetStreamingLogsForApplicationByNameAndSpaceCallCount()).To(Equal(1))
   281  					appName, spaceGUID, client := fakeActor.GetStreamingLogsForApplicationByNameAndSpaceArgsForCall(0)
   282  
   283  					Expect(appName).To(Equal("some-app"))
   284  					Expect(spaceGUID).To(Equal("some-space-guid"))
   285  					Expect(client).To(Equal(logCacheClient))
   286  				})
   287  			})
   288  		})
   289  	})
   290  })