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