github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/actor/sharedaction/logging_test.go (about)

     1  package sharedaction_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"time"
     8  
     9  	"code.cloudfoundry.org/cli/actor/sharedaction"
    10  
    11  	"code.cloudfoundry.org/cli/actor/sharedaction/sharedactionfakes"
    12  	"code.cloudfoundry.org/go-loggregator/rpc/loggregator_v2"
    13  	logcache "code.cloudfoundry.org/log-cache/pkg/client"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  var _ = Describe("Logging Actions", func() {
    19  	var (
    20  		fakeLogCacheClient *sharedactionfakes.FakeLogCacheClient
    21  	)
    22  
    23  	BeforeEach(func() {
    24  		fakeLogCacheClient = new(sharedactionfakes.FakeLogCacheClient)
    25  	})
    26  
    27  	Describe("LogMessage", func() {
    28  		Describe("Staging", func() {
    29  			When("the log is a staging log", func() {
    30  				It("returns true", func() {
    31  					message := *sharedaction.NewLogMessage(
    32  						"some-message",
    33  						"OUT",
    34  						time.Unix(0, 0),
    35  						"STG",
    36  						"some-source-instance",
    37  					)
    38  
    39  					Expect(message.Staging()).To(BeTrue())
    40  				})
    41  			})
    42  
    43  			When("the log is any other kind of log", func() {
    44  				It("returns false", func() {
    45  					message := *sharedaction.NewLogMessage(
    46  						"some-message",
    47  						"OUT",
    48  						time.Unix(0, 0),
    49  						"APP",
    50  						"some-source-instance",
    51  					)
    52  					Expect(message.Staging()).To(BeFalse())
    53  				})
    54  			})
    55  		})
    56  	})
    57  
    58  	Describe("GetStreamingLogs", func() {
    59  		var (
    60  			expectedAppGUID string
    61  
    62  			messages      <-chan sharedaction.LogMessage
    63  			errs          <-chan error
    64  			stopStreaming context.CancelFunc
    65  		)
    66  
    67  		BeforeEach(func() {
    68  			expectedAppGUID = "some-app-guid"
    69  		})
    70  
    71  		AfterEach(func() {
    72  			Eventually(messages).Should(BeClosed())
    73  			Eventually(errs).Should(BeClosed())
    74  		})
    75  
    76  		JustBeforeEach(func() {
    77  			messages, errs, stopStreaming = sharedaction.GetStreamingLogs(expectedAppGUID, fakeLogCacheClient)
    78  		})
    79  
    80  		When("receiving logs", func() {
    81  			BeforeEach(func() {
    82  				fakeLogCacheClient.ReadStub = func(
    83  					ctx context.Context,
    84  					sourceID string,
    85  					start time.Time,
    86  					opts ...logcache.ReadOption,
    87  				) ([]*loggregator_v2.Envelope, error) {
    88  					if fakeLogCacheClient.ReadCallCount() > 2 {
    89  						stopStreaming()
    90  					}
    91  
    92  					return []*loggregator_v2.Envelope{{
    93  						// 2 seconds in the past to get past Walk delay
    94  						Timestamp:  time.Now().Add(-3 * time.Second).UnixNano(),
    95  						SourceId:   "some-app-guid",
    96  						InstanceId: "some-source-instance",
    97  						Message: &loggregator_v2.Envelope_Log{
    98  							Log: &loggregator_v2.Log{
    99  								Payload: []byte("message-1"),
   100  								Type:    loggregator_v2.Log_OUT,
   101  							},
   102  						},
   103  						Tags: map[string]string{
   104  							"source_type": "some-source-type",
   105  						},
   106  					}, {
   107  						// 2 seconds in the past to get past Walk delay
   108  						Timestamp:  time.Now().Add(-2 * time.Second).UnixNano(),
   109  						SourceId:   "some-app-guid",
   110  						InstanceId: "some-source-instance",
   111  						Message: &loggregator_v2.Envelope_Log{
   112  							Log: &loggregator_v2.Log{
   113  								Payload: []byte("message-2"),
   114  								Type:    loggregator_v2.Log_OUT,
   115  							},
   116  						},
   117  						Tags: map[string]string{
   118  							"source_type": "some-source-type",
   119  						},
   120  					}}, ctx.Err()
   121  				}
   122  			})
   123  
   124  			It("converts them to log messages and passes them through the messages channel", func() {
   125  				Eventually(messages).Should(HaveLen(4))
   126  				var message sharedaction.LogMessage
   127  				Expect(messages).To(Receive(&message))
   128  				Expect(message.Message()).To(Equal("message-1"))
   129  				Expect(messages).To(Receive(&message))
   130  				Expect(message.Message()).To(Equal("message-2"))
   131  
   132  				Expect(errs).ToNot(Receive())
   133  			})
   134  		})
   135  
   136  		When("logs are older than 5 seconds", func() {
   137  			var readStart chan time.Time
   138  
   139  			BeforeEach(func() {
   140  				readStart = make(chan time.Time, 100)
   141  				fakeLogCacheClient.ReadStub = func(
   142  					ctx context.Context,
   143  					sourceID string,
   144  					start time.Time,
   145  					opts ...logcache.ReadOption,
   146  				) ([]*loggregator_v2.Envelope, error) {
   147  					if fakeLogCacheClient.ReadCallCount() > 1 {
   148  						stopStreaming()
   149  					}
   150  
   151  					readStart <- start
   152  
   153  					return []*loggregator_v2.Envelope{{
   154  						// 6 seconds in the past to get past Walk delay
   155  						Timestamp:  time.Now().Add(-6 * time.Second).UnixNano(),
   156  						SourceId:   "some-app-guid",
   157  						InstanceId: "some-source-instance",
   158  						Message: &loggregator_v2.Envelope_Log{
   159  							Log: &loggregator_v2.Log{
   160  								Payload: []byte("message-1"),
   161  								Type:    loggregator_v2.Log_OUT,
   162  							},
   163  						},
   164  						Tags: map[string]string{
   165  							"source_type": "some-source-type",
   166  						},
   167  					}, {
   168  						// 2 seconds in the past to get past Walk delay
   169  						Timestamp:  time.Now().Add(-2 * time.Second).UnixNano(),
   170  						SourceId:   "some-app-guid",
   171  						InstanceId: "some-source-instance",
   172  						Message: &loggregator_v2.Envelope_Log{
   173  							Log: &loggregator_v2.Log{
   174  								Payload: []byte("message-2"),
   175  								Type:    loggregator_v2.Log_OUT,
   176  							},
   177  						},
   178  						Tags: map[string]string{
   179  							"source_type": "some-source-type",
   180  						},
   181  					}}, ctx.Err()
   182  				}
   183  			})
   184  
   185  			It("ignores them", func() {
   186  				Eventually(readStart).Should(Receive(BeTemporally("~", time.Now().Add(-5*time.Second), time.Second)))
   187  			})
   188  		})
   189  
   190  		When("cancelling log streaming", func() {
   191  			BeforeEach(func() {
   192  				fakeLogCacheClient.ReadStub = func(
   193  					ctx context.Context,
   194  					sourceID string,
   195  					start time.Time,
   196  					opts ...logcache.ReadOption,
   197  				) ([]*loggregator_v2.Envelope, error) {
   198  					return nil, ctx.Err()
   199  				}
   200  			})
   201  
   202  			It("can be called multiple times", func() {
   203  				Expect(stopStreaming).ToNot(Panic())
   204  				Expect(stopStreaming).ToNot(Panic())
   205  			})
   206  		})
   207  
   208  		Describe("log cache error", func() {
   209  			BeforeEach(func() {
   210  				fakeLogCacheClient.ReadStub = func(
   211  					ctx context.Context,
   212  					sourceID string,
   213  					start time.Time,
   214  					opts ...logcache.ReadOption,
   215  				) ([]*loggregator_v2.Envelope, error) {
   216  					if fakeLogCacheClient.ReadCallCount() > 2 {
   217  						stopStreaming()
   218  					}
   219  
   220  					return nil, fmt.Errorf("error number %d", fakeLogCacheClient.ReadCallCount())
   221  				}
   222  			})
   223  
   224  			It("passes them through the errors channel", func() {
   225  				Eventually(errs).Should(HaveLen(2))
   226  				Eventually(errs).Should(Receive(MatchError("error number 1")))
   227  				Eventually(errs).Should(Receive(MatchError("error number 2")))
   228  			})
   229  		})
   230  	})
   231  
   232  	Describe("GetRecentLogs", func() {
   233  		When("the application can be found", func() {
   234  			When("Log Cache returns logs", func() {
   235  				BeforeEach(func() {
   236  					messages := []*loggregator_v2.Envelope{
   237  						{
   238  							Timestamp:  int64(20),
   239  							SourceId:   "some-app-guid",
   240  							InstanceId: "some-source-instance",
   241  							Message: &loggregator_v2.Envelope_Log{
   242  								Log: &loggregator_v2.Log{
   243  									Payload: []byte("message-2"),
   244  									Type:    loggregator_v2.Log_OUT,
   245  								},
   246  							},
   247  							Tags: map[string]string{
   248  								"source_type": "some-source-type",
   249  							},
   250  						},
   251  						{
   252  							Timestamp:  int64(10),
   253  							SourceId:   "some-app-guid",
   254  							InstanceId: "some-source-instance",
   255  							Message: &loggregator_v2.Envelope_Log{
   256  								Log: &loggregator_v2.Log{
   257  									Payload: []byte("message-1"),
   258  									Type:    loggregator_v2.Log_OUT,
   259  								},
   260  							},
   261  							Tags: map[string]string{
   262  								"source_type": "some-source-type",
   263  							},
   264  						},
   265  					}
   266  
   267  					fakeLogCacheClient.ReadReturns(messages, nil)
   268  				})
   269  
   270  				It("returns all the recent logs and warnings", func() {
   271  					messages, err := sharedaction.GetRecentLogs("some-app-guid", fakeLogCacheClient)
   272  					Expect(err).ToNot(HaveOccurred())
   273  
   274  					Expect(messages[0].Message()).To(Equal("message-1"))
   275  					Expect(messages[0].Type()).To(Equal("OUT"))
   276  					Expect(messages[0].Timestamp()).To(Equal(time.Unix(0, 10)))
   277  					Expect(messages[0].SourceType()).To(Equal("some-source-type"))
   278  					Expect(messages[0].SourceInstance()).To(Equal("some-source-instance"))
   279  
   280  					Expect(messages[1].Message()).To(Equal("message-2"))
   281  					Expect(messages[1].Type()).To(Equal("OUT"))
   282  					Expect(messages[1].Timestamp()).To(Equal(time.Unix(0, 20)))
   283  					Expect(messages[1].SourceType()).To(Equal("some-source-type"))
   284  					Expect(messages[1].SourceInstance()).To(Equal("some-source-instance"))
   285  				})
   286  			})
   287  
   288  			When("Log Cache returns non-log envelopes", func() {
   289  				BeforeEach(func() {
   290  					messages := []*loggregator_v2.Envelope{
   291  						{
   292  							Timestamp:  int64(10),
   293  							SourceId:   "some-app-guid",
   294  							InstanceId: "some-source-instance",
   295  							Message:    &loggregator_v2.Envelope_Counter{},
   296  							Tags: map[string]string{
   297  								"source_type": "some-source-type",
   298  							},
   299  						},
   300  					}
   301  
   302  					fakeLogCacheClient.ReadReturns(messages, nil)
   303  				})
   304  
   305  				It("ignores them", func() {
   306  					messages, err := sharedaction.GetRecentLogs("some-app-guid", fakeLogCacheClient)
   307  					Expect(err).ToNot(HaveOccurred())
   308  					Expect(messages).To(BeEmpty())
   309  				})
   310  			})
   311  
   312  			When("Log Cache errors", func() {
   313  				var expectedErr error
   314  
   315  				BeforeEach(func() {
   316  					expectedErr = errors.New("ZOMG")
   317  					fakeLogCacheClient.ReadReturns(nil, expectedErr)
   318  				})
   319  
   320  				It("returns error and warnings", func() {
   321  					_, err := sharedaction.GetRecentLogs("some-app-guid", fakeLogCacheClient)
   322  					Expect(err).To(MatchError(expectedErr))
   323  				})
   324  			})
   325  		})
   326  	})
   327  
   328  })