github.com/lukasheimann/cloudfoundrycli@v7.1.0+incompatible/actor/v7action/logging_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"time"
     7  
     8  	"code.cloudfoundry.org/cli/actor/sharedaction"
     9  	"code.cloudfoundry.org/cli/actor/sharedaction/sharedactionfakes"
    10  	. "code.cloudfoundry.org/cli/actor/v7action"
    11  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
    12  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    13  	"code.cloudfoundry.org/cli/resources"
    14  	logcache "code.cloudfoundry.org/go-log-cache"
    15  	"code.cloudfoundry.org/go-loggregator/rpc/loggregator_v2"
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/gomega"
    18  )
    19  
    20  var _ = Describe("Logging Actions", func() {
    21  	var (
    22  		actor                     *Actor
    23  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    24  		fakeConfig                *v7actionfakes.FakeConfig
    25  		fakeLogCacheClient        *sharedactionfakes.FakeLogCacheClient
    26  	)
    27  
    28  	BeforeEach(func() {
    29  		actor, fakeCloudControllerClient, fakeConfig, _, _, _, _ = NewTestActor()
    30  		fakeLogCacheClient = new(sharedactionfakes.FakeLogCacheClient)
    31  		fakeConfig.AccessTokenReturns("AccessTokenForTest")
    32  	})
    33  
    34  	Describe("GetRecentLogsForApplicationByNameAndSpace", func() {
    35  		When("the application can be found", func() {
    36  			BeforeEach(func() {
    37  				fakeCloudControllerClient.GetApplicationsReturns(
    38  					[]resources.Application{
    39  						{
    40  							Name: "some-app",
    41  							GUID: "some-app-guid",
    42  						},
    43  					},
    44  					ccv3.Warnings{"some-app-warnings"},
    45  					nil,
    46  				)
    47  			})
    48  
    49  			When("Log Cache returns logs", func() {
    50  				BeforeEach(func() {
    51  					messages := []*loggregator_v2.Envelope{
    52  						{
    53  							Timestamp:  int64(20),
    54  							SourceId:   "some-app-guid",
    55  							InstanceId: "some-source-instance",
    56  							Message: &loggregator_v2.Envelope_Log{
    57  								Log: &loggregator_v2.Log{
    58  									Payload: []byte("message-2"),
    59  									Type:    loggregator_v2.Log_OUT,
    60  								},
    61  							},
    62  							Tags: map[string]string{
    63  								"source_type": "some-source-type",
    64  							},
    65  						},
    66  						{
    67  							Timestamp:  int64(10),
    68  							SourceId:   "some-app-guid",
    69  							InstanceId: "some-source-instance",
    70  							Message: &loggregator_v2.Envelope_Log{
    71  								Log: &loggregator_v2.Log{
    72  									Payload: []byte("message-1"),
    73  									Type:    loggregator_v2.Log_OUT,
    74  								},
    75  							},
    76  							Tags: map[string]string{
    77  								"source_type": "some-source-type",
    78  							},
    79  						},
    80  					}
    81  
    82  					fakeLogCacheClient.ReadReturns(messages, nil)
    83  				})
    84  
    85  				It("returns all the recent logs and warnings", func() {
    86  					messages, warnings, err := actor.GetRecentLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeLogCacheClient)
    87  					Expect(err).ToNot(HaveOccurred())
    88  					Expect(warnings).To(ConsistOf("some-app-warnings"))
    89  
    90  					Expect(messages[0].Message()).To(Equal("message-1"))
    91  					Expect(messages[0].Type()).To(Equal("OUT"))
    92  					Expect(messages[0].Timestamp()).To(Equal(time.Unix(0, 10)))
    93  					Expect(messages[0].SourceType()).To(Equal("some-source-type"))
    94  					Expect(messages[0].SourceInstance()).To(Equal("some-source-instance"))
    95  
    96  					Expect(messages[1].Message()).To(Equal("message-2"))
    97  					Expect(messages[1].Type()).To(Equal("OUT"))
    98  					Expect(messages[1].Timestamp()).To(Equal(time.Unix(0, 20)))
    99  					Expect(messages[1].SourceType()).To(Equal("some-source-type"))
   100  					Expect(messages[1].SourceInstance()).To(Equal("some-source-instance"))
   101  				})
   102  			})
   103  
   104  			When("Log Cache errors", func() {
   105  				var expectedErr error
   106  
   107  				BeforeEach(func() {
   108  					expectedErr = errors.New("failure-to-read-from-log-cache")
   109  					fakeLogCacheClient.ReadReturns(nil, expectedErr)
   110  				})
   111  
   112  				It("returns error and warnings", func() {
   113  					_, warnings, err := actor.GetRecentLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeLogCacheClient)
   114  					Expect(err).To(MatchError("Failed to retrieve logs from Log Cache: failure-to-read-from-log-cache"))
   115  					Expect(warnings).To(ConsistOf("some-app-warnings"))
   116  				})
   117  			})
   118  		})
   119  
   120  		When("finding the application errors", func() {
   121  			var expectedErr error
   122  
   123  			BeforeEach(func() {
   124  				expectedErr = errors.New("ZOMG")
   125  				fakeCloudControllerClient.GetApplicationsReturns(
   126  					nil,
   127  					ccv3.Warnings{"some-app-warnings"},
   128  					expectedErr,
   129  				)
   130  			})
   131  
   132  			It("returns error and warnings", func() {
   133  				_, warnings, err := actor.GetRecentLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeLogCacheClient)
   134  				Expect(err).To(MatchError(expectedErr))
   135  				Expect(warnings).To(ConsistOf("some-app-warnings"))
   136  			})
   137  		})
   138  	})
   139  
   140  	Describe("GetStreamingLogsForApplicationByNameAndSpace", func() {
   141  		When("the application can be found", func() {
   142  			var (
   143  				expectedAppGUID string
   144  
   145  				messages      <-chan sharedaction.LogMessage
   146  				logErrs       <-chan error
   147  				stopStreaming context.CancelFunc
   148  			)
   149  
   150  			AfterEach(func() {
   151  				Eventually(messages).Should(BeClosed())
   152  				Eventually(logErrs).Should(BeClosed())
   153  			})
   154  
   155  			BeforeEach(func() {
   156  				expectedAppGUID = "some-app-guid"
   157  
   158  				fakeCloudControllerClient.GetApplicationsReturns(
   159  					[]resources.Application{
   160  						{
   161  							Name: "some-app",
   162  							GUID: expectedAppGUID,
   163  						},
   164  					},
   165  					ccv3.Warnings{"some-app-warnings"},
   166  					nil,
   167  				)
   168  
   169  				fakeConfig.DialTimeoutReturns(60 * time.Minute)
   170  				fakeLogCacheClient.ReadStub = func(
   171  					ctx context.Context,
   172  					sourceID string,
   173  					start time.Time,
   174  					opts ...logcache.ReadOption,
   175  				) ([]*loggregator_v2.Envelope, error) {
   176  					if fakeLogCacheClient.ReadCallCount() > 2 {
   177  						stopStreaming()
   178  					}
   179  
   180  					return []*loggregator_v2.Envelope{{
   181  						// 2 seconds in the past to get past Walk delay
   182  						Timestamp:  time.Now().Add(-3 * time.Second).UnixNano(),
   183  						SourceId:   expectedAppGUID,
   184  						InstanceId: "some-source-instance",
   185  						Message: &loggregator_v2.Envelope_Log{
   186  							Log: &loggregator_v2.Log{
   187  								Payload: []byte("message-1"),
   188  								Type:    loggregator_v2.Log_OUT,
   189  							},
   190  						},
   191  						Tags: map[string]string{
   192  							"source_type": "some-source-type",
   193  						},
   194  					}, {
   195  						// 2 seconds in the past to get past Walk delay
   196  						Timestamp:  time.Now().Add(-2 * time.Second).UnixNano(),
   197  						SourceId:   expectedAppGUID,
   198  						InstanceId: "some-source-instance",
   199  						Message: &loggregator_v2.Envelope_Log{
   200  							Log: &loggregator_v2.Log{
   201  								Payload: []byte("message-2"),
   202  								Type:    loggregator_v2.Log_OUT,
   203  							},
   204  						},
   205  						Tags: map[string]string{
   206  							"source_type": "some-source-type",
   207  						},
   208  					}}, ctx.Err()
   209  				}
   210  			})
   211  
   212  			It("converts them to log messages and passes them through the messages channel", func() {
   213  				var err error
   214  				var warnings Warnings
   215  				var message sharedaction.LogMessage
   216  
   217  				messages, logErrs, stopStreaming, warnings, err = actor.GetStreamingLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeLogCacheClient)
   218  
   219  				Expect(err).ToNot(HaveOccurred())
   220  				Expect(warnings).To(ConsistOf("some-app-warnings"))
   221  
   222  				Eventually(messages).Should(Receive(&message))
   223  				Expect(message.Message()).To(Equal("message-1"))
   224  
   225  				Eventually(messages).Should(Receive(&message))
   226  				Expect(message.Message()).To(Equal("message-2"))
   227  			})
   228  		})
   229  
   230  		When("finding the application errors", func() {
   231  			var expectedErr error
   232  
   233  			BeforeEach(func() {
   234  				expectedErr = errors.New("ZOMG")
   235  				fakeCloudControllerClient.GetApplicationsReturns(
   236  					nil,
   237  					ccv3.Warnings{"some-app-warnings"},
   238  					expectedErr,
   239  				)
   240  			})
   241  
   242  			It("returns error and warnings", func() {
   243  				_, _, _, warnings, err := actor.GetStreamingLogsForApplicationByNameAndSpace("some-app", "some-space-guid", fakeLogCacheClient)
   244  				Expect(err).To(MatchError(expectedErr))
   245  				Expect(warnings).To(ConsistOf("some-app-warnings"))
   246  
   247  				Expect(fakeLogCacheClient.ReadCallCount()).To(Equal(0))
   248  			})
   249  		})
   250  	})
   251  })