github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/actor/v2action/logging_test.go (about)

     1  package v2action_test
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	. "code.cloudfoundry.org/cli/actor/v2action"
     8  	"code.cloudfoundry.org/cli/actor/v2action/v2actionfakes"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
    10  	noaaErrors "github.com/cloudfoundry/noaa/errors"
    11  	"github.com/cloudfoundry/sonde-go/events"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  )
    15  
    16  var _ = Describe("Logging Actions", func() {
    17  	var (
    18  		actor                     *Actor
    19  		fakeNOAAClient            *v2actionfakes.FakeNOAAClient
    20  		fakeConfig                *v2actionfakes.FakeConfig
    21  		fakeCloudControllerClient *v2actionfakes.FakeCloudControllerClient
    22  	)
    23  
    24  	BeforeEach(func() {
    25  		fakeNOAAClient = new(v2actionfakes.FakeNOAAClient)
    26  		fakeConfig = new(v2actionfakes.FakeConfig)
    27  		fakeCloudControllerClient = new(v2actionfakes.FakeCloudControllerClient)
    28  		actor = NewActor(fakeCloudControllerClient, nil, nil)
    29  	})
    30  
    31  	Describe("LogMessage", func() {
    32  		Describe("Staging", func() {
    33  			Context("when the log is a staging log", func() {
    34  				It("returns true", func() {
    35  					message := NewLogMessage("", 0, time.Now(), "STG", "")
    36  					Expect(message.Staging()).To(BeTrue())
    37  				})
    38  			})
    39  
    40  			Context("when the log is any other kind of log", func() {
    41  				It("returns true", func() {
    42  					message := NewLogMessage("", 0, time.Now(), "APP", "")
    43  					Expect(message.Staging()).To(BeFalse())
    44  				})
    45  			})
    46  		})
    47  	})
    48  
    49  	Describe("GetStreamingLogs", func() {
    50  		var (
    51  			expectedAppGUID string
    52  
    53  			messages    <-chan *LogMessage
    54  			errs        <-chan error
    55  			eventStream chan *events.LogMessage
    56  			errStream   chan error
    57  		)
    58  
    59  		BeforeEach(func() {
    60  			expectedAppGUID = "some-app-guid"
    61  
    62  			eventStream = make(chan *events.LogMessage)
    63  			errStream = make(chan error)
    64  		})
    65  
    66  		// If tests panic due to this close, it is likely you have a failing
    67  		// expectation and the channels are being closed because the test has
    68  		// failed/short circuited and is going through teardown.
    69  		AfterEach(func() {
    70  			close(eventStream)
    71  			close(errStream)
    72  
    73  			Eventually(messages).Should(BeClosed())
    74  			Eventually(errs).Should(BeClosed())
    75  		})
    76  
    77  		JustBeforeEach(func() {
    78  			messages, errs = actor.GetStreamingLogs(expectedAppGUID, fakeNOAAClient, fakeConfig)
    79  		})
    80  
    81  		Context("when receiving events", func() {
    82  			BeforeEach(func() {
    83  				fakeNOAAClient.TailingLogsStub = func(appGUID string, authToken string) (<-chan *events.LogMessage, <-chan error) {
    84  					Expect(appGUID).To(Equal(expectedAppGUID))
    85  					Expect(authToken).To(BeEmpty())
    86  
    87  					go func() {
    88  						outMessage := events.LogMessage_OUT
    89  						ts1 := int64(10)
    90  						sourceType := "some-source-type"
    91  						sourceInstance := "some-source-instance"
    92  
    93  						eventStream <- &events.LogMessage{
    94  							Message:        []byte("message-1"),
    95  							MessageType:    &outMessage,
    96  							Timestamp:      &ts1,
    97  							SourceType:     &sourceType,
    98  							SourceInstance: &sourceInstance,
    99  						}
   100  
   101  						errMessage := events.LogMessage_ERR
   102  						ts2 := int64(20)
   103  
   104  						eventStream <- &events.LogMessage{
   105  							Message:        []byte("message-2"),
   106  							MessageType:    &errMessage,
   107  							Timestamp:      &ts2,
   108  							SourceType:     &sourceType,
   109  							SourceInstance: &sourceInstance,
   110  						}
   111  					}()
   112  
   113  					return eventStream, errStream
   114  				}
   115  			})
   116  
   117  			It("converts them to log messages and passes them through the messages channel", func() {
   118  				message := <-messages
   119  				Expect(message.Message()).To(Equal("message-1"))
   120  				Expect(message.Type()).To(Equal("OUT"))
   121  				Expect(message.Timestamp()).To(Equal(time.Unix(0, 10)))
   122  				Expect(message.SourceType()).To(Equal("some-source-type"))
   123  				Expect(message.SourceInstance()).To(Equal("some-source-instance"))
   124  
   125  				message = <-messages
   126  				Expect(message.Message()).To(Equal("message-2"))
   127  				Expect(message.Type()).To(Equal("ERR"))
   128  				Expect(message.Timestamp()).To(Equal(time.Unix(0, 20)))
   129  				Expect(message.SourceType()).To(Equal("some-source-type"))
   130  				Expect(message.SourceInstance()).To(Equal("some-source-instance"))
   131  			})
   132  		})
   133  
   134  		Context("when receiving errors", func() {
   135  			var (
   136  				err1 error
   137  				err2 error
   138  
   139  				waiting chan bool
   140  			)
   141  
   142  			Describe("nil error", func() {
   143  				BeforeEach(func() {
   144  					waiting = make(chan bool)
   145  					fakeNOAAClient.TailingLogsStub = func(_ string, _ string) (<-chan *events.LogMessage, <-chan error) {
   146  						go func() {
   147  							errStream <- nil
   148  							close(waiting)
   149  						}()
   150  
   151  						return eventStream, errStream
   152  					}
   153  				})
   154  
   155  				It("does not pass the nil along", func() {
   156  					Eventually(waiting).Should(BeClosed())
   157  					Consistently(errs).ShouldNot(Receive())
   158  				})
   159  			})
   160  
   161  			Describe("unexpected error", func() {
   162  				BeforeEach(func() {
   163  					err1 = errors.New("ZOMG")
   164  					err2 = errors.New("Fiddlesticks")
   165  
   166  					fakeNOAAClient.TailingLogsStub = func(_ string, _ string) (<-chan *events.LogMessage, <-chan error) {
   167  						go func() {
   168  							errStream <- err1
   169  							errStream <- err2
   170  						}()
   171  
   172  						return eventStream, errStream
   173  					}
   174  				})
   175  
   176  				It("passes them through the errors channel", func() {
   177  					Eventually(errs).Should(Receive(Equal(err1)))
   178  					Eventually(errs).Should(Receive(Equal(err2)))
   179  				})
   180  			})
   181  
   182  			Describe("NOAA's RetryError", func() {
   183  				Context("when NOAA is able to recover", func() {
   184  					BeforeEach(func() {
   185  						fakeNOAAClient.TailingLogsStub = func(_ string, _ string) (<-chan *events.LogMessage, <-chan error) {
   186  							go func() {
   187  								errStream <- noaaErrors.NewRetryError(errors.New("error 1"))
   188  
   189  								outMessage := events.LogMessage_OUT
   190  								ts1 := int64(10)
   191  								sourceType := "some-source-type"
   192  								sourceInstance := "some-source-instance"
   193  
   194  								eventStream <- &events.LogMessage{
   195  									Message:        []byte("message-1"),
   196  									MessageType:    &outMessage,
   197  									Timestamp:      &ts1,
   198  									SourceType:     &sourceType,
   199  									SourceInstance: &sourceInstance,
   200  								}
   201  							}()
   202  
   203  							return eventStream, errStream
   204  						}
   205  					})
   206  
   207  					It("continues without issue", func() {
   208  						Eventually(messages).Should(Receive())
   209  						Consistently(errs).ShouldNot(Receive())
   210  					})
   211  				})
   212  			})
   213  		})
   214  	})
   215  
   216  	Describe("GetRecentLogsForApplicationByNameAndSpace", func() {
   217  		Context("when the application can be found", func() {
   218  			BeforeEach(func() {
   219  				fakeCloudControllerClient.GetApplicationsReturns(
   220  					[]ccv2.Application{
   221  						{
   222  							Name: "some-app",
   223  							GUID: "some-app-guid",
   224  						},
   225  					},
   226  					ccv2.Warnings{"some-app-warnings"},
   227  					nil,
   228  				)
   229  			})
   230  
   231  			Context("when NOAA returns logs", func() {
   232  				BeforeEach(func() {
   233  					outMessage := events.LogMessage_OUT
   234  					ts1 := int64(10)
   235  					ts2 := int64(20)
   236  					sourceType := "some-source-type"
   237  					sourceInstance := "some-source-instance"
   238  
   239  					var messages []*events.LogMessage
   240  					messages = append(messages, &events.LogMessage{
   241  						Message:        []byte("message-2"),
   242  						MessageType:    &outMessage,
   243  						Timestamp:      &ts2,
   244  						SourceType:     &sourceType,
   245  						SourceInstance: &sourceInstance,
   246  					})
   247  					messages = append(messages, &events.LogMessage{
   248  						Message:        []byte("message-1"),
   249  						MessageType:    &outMessage,
   250  						Timestamp:      &ts1,
   251  						SourceType:     &sourceType,
   252  						SourceInstance: &sourceInstance,
   253  					})
   254  
   255  					fakeNOAAClient.RecentLogsReturns(messages, nil)
   256  				})
   257  
   258  				It("returns all the recent logs and warnings", func() {
   259  					messages, warnings, err := actor.GetRecentLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeNOAAClient, fakeConfig)
   260  					Expect(err).ToNot(HaveOccurred())
   261  					Expect(warnings).To(ConsistOf("some-app-warnings"))
   262  					Expect(messages[0].Message()).To(Equal("message-1"))
   263  					Expect(messages[0].Type()).To(Equal("OUT"))
   264  					Expect(messages[0].Timestamp()).To(Equal(time.Unix(0, 10)))
   265  					Expect(messages[0].SourceType()).To(Equal("some-source-type"))
   266  					Expect(messages[0].SourceInstance()).To(Equal("some-source-instance"))
   267  
   268  					Expect(messages[1].Message()).To(Equal("message-2"))
   269  					Expect(messages[1].Type()).To(Equal("OUT"))
   270  					Expect(messages[1].Timestamp()).To(Equal(time.Unix(0, 20)))
   271  					Expect(messages[1].SourceType()).To(Equal("some-source-type"))
   272  					Expect(messages[1].SourceInstance()).To(Equal("some-source-instance"))
   273  				})
   274  			})
   275  
   276  			Context("when NOAA errors", func() {
   277  				var expectedErr error
   278  
   279  				BeforeEach(func() {
   280  					expectedErr = errors.New("ZOMG")
   281  					fakeNOAAClient.RecentLogsReturns(nil, expectedErr)
   282  				})
   283  
   284  				It("returns error and warnings", func() {
   285  					_, warnings, err := actor.GetRecentLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeNOAAClient, fakeConfig)
   286  					Expect(err).To(MatchError(expectedErr))
   287  					Expect(warnings).To(ConsistOf("some-app-warnings"))
   288  				})
   289  			})
   290  		})
   291  
   292  		Context("when finding the application errors", func() {
   293  			var expectedErr error
   294  
   295  			BeforeEach(func() {
   296  				expectedErr = errors.New("ZOMG")
   297  				fakeCloudControllerClient.GetApplicationsReturns(
   298  					nil,
   299  					ccv2.Warnings{"some-app-warnings"},
   300  					expectedErr,
   301  				)
   302  			})
   303  
   304  			It("returns error and warnings", func() {
   305  				_, warnings, err := actor.GetRecentLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeNOAAClient, fakeConfig)
   306  				Expect(err).To(MatchError(expectedErr))
   307  				Expect(warnings).To(ConsistOf("some-app-warnings"))
   308  
   309  				Expect(fakeNOAAClient.RecentLogsCallCount()).To(Equal(0))
   310  			})
   311  		})
   312  	})
   313  
   314  	Describe("GetStreamingLogsForApplicationByNameAndSpace", func() {
   315  		Context("when the application can be found", func() {
   316  			var (
   317  				expectedAppGUID string
   318  
   319  				eventStream chan *events.LogMessage
   320  				errStream   chan error
   321  
   322  				messages <-chan *LogMessage
   323  				logErrs  <-chan error
   324  			)
   325  
   326  			// If tests panic due to this close, it is likely you have a failing
   327  			// expectation and the channels are being closed because the test has
   328  			// failed/short circuited and is going through teardown.
   329  			AfterEach(func() {
   330  				close(eventStream)
   331  				close(errStream)
   332  
   333  				Eventually(messages).Should(BeClosed())
   334  				Eventually(logErrs).Should(BeClosed())
   335  			})
   336  
   337  			BeforeEach(func() {
   338  				expectedAppGUID = "some-app-guid"
   339  
   340  				eventStream = make(chan *events.LogMessage)
   341  				errStream = make(chan error)
   342  				fakeCloudControllerClient.GetApplicationsReturns(
   343  					[]ccv2.Application{
   344  						{
   345  							Name: "some-app",
   346  							GUID: expectedAppGUID,
   347  						},
   348  					},
   349  					ccv2.Warnings{"some-app-warnings"},
   350  					nil,
   351  				)
   352  
   353  				fakeNOAAClient.TailingLogsStub = func(appGUID string, authToken string) (<-chan *events.LogMessage, <-chan error) {
   354  					Expect(appGUID).To(Equal(expectedAppGUID))
   355  					Expect(authToken).To(BeEmpty())
   356  
   357  					go func() {
   358  						outMessage := events.LogMessage_OUT
   359  						ts1 := int64(10)
   360  						sourceType := "some-source-type"
   361  						sourceInstance := "some-source-instance"
   362  
   363  						eventStream <- &events.LogMessage{
   364  							Message:        []byte("message-1"),
   365  							MessageType:    &outMessage,
   366  							Timestamp:      &ts1,
   367  							SourceType:     &sourceType,
   368  							SourceInstance: &sourceInstance,
   369  						}
   370  
   371  						errMessage := events.LogMessage_ERR
   372  						ts2 := int64(20)
   373  
   374  						eventStream <- &events.LogMessage{
   375  							Message:        []byte("message-2"),
   376  							MessageType:    &errMessage,
   377  							Timestamp:      &ts2,
   378  							SourceType:     &sourceType,
   379  							SourceInstance: &sourceInstance,
   380  						}
   381  					}()
   382  
   383  					return eventStream, errStream
   384  				}
   385  			})
   386  
   387  			It("converts them to log messages and passes them through the messages channel", func() {
   388  				var err error
   389  				var warnings Warnings
   390  				messages, logErrs, warnings, err = actor.GetStreamingLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeNOAAClient, fakeConfig)
   391  
   392  				Expect(err).ToNot(HaveOccurred())
   393  				Expect(warnings).To(ConsistOf("some-app-warnings"))
   394  
   395  				message := <-messages
   396  				Expect(message.Message()).To(Equal("message-1"))
   397  				Expect(message.Type()).To(Equal("OUT"))
   398  				Expect(message.Timestamp()).To(Equal(time.Unix(0, 10)))
   399  				Expect(message.SourceType()).To(Equal("some-source-type"))
   400  				Expect(message.SourceInstance()).To(Equal("some-source-instance"))
   401  
   402  				message = <-messages
   403  				Expect(message.Message()).To(Equal("message-2"))
   404  				Expect(message.Type()).To(Equal("ERR"))
   405  				Expect(message.Timestamp()).To(Equal(time.Unix(0, 20)))
   406  				Expect(message.SourceType()).To(Equal("some-source-type"))
   407  				Expect(message.SourceInstance()).To(Equal("some-source-instance"))
   408  			})
   409  		})
   410  
   411  		Context("when finding the application errors", func() {
   412  			var expectedErr error
   413  
   414  			BeforeEach(func() {
   415  				expectedErr = errors.New("ZOMG")
   416  				fakeCloudControllerClient.GetApplicationsReturns(
   417  					nil,
   418  					ccv2.Warnings{"some-app-warnings"},
   419  					expectedErr,
   420  				)
   421  			})
   422  
   423  			It("returns error and warnings", func() {
   424  				_, _, warnings, err := actor.GetStreamingLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeNOAAClient, fakeConfig)
   425  				Expect(err).To(MatchError(expectedErr))
   426  				Expect(warnings).To(ConsistOf("some-app-warnings"))
   427  
   428  				Expect(fakeNOAAClient.TailingLogsCallCount()).To(Equal(0))
   429  			})
   430  		})
   431  	})
   432  })