github.com/chenbh/concourse/v6@v6.4.2/fly/eventstream/render_test.go (about) 1 package eventstream_test 2 3 import ( 4 "io" 5 "time" 6 7 "github.com/fatih/color" 8 . "github.com/onsi/ginkgo" 9 . "github.com/onsi/gomega" 10 11 "github.com/onsi/gomega/gbytes" 12 13 "github.com/chenbh/concourse/v6/atc" 14 "github.com/chenbh/concourse/v6/atc/event" 15 "github.com/chenbh/concourse/v6/fly/eventstream" 16 "github.com/chenbh/concourse/v6/fly/ui" 17 "github.com/chenbh/concourse/v6/go-concourse/concourse/eventstream/eventstreamfakes" 18 ) 19 20 var _ = Describe("V1.0 Renderer", func() { 21 var ( 22 out *gbytes.Buffer 23 stream *eventstreamfakes.FakeEventStream 24 options eventstream.RenderOptions 25 26 receivedEvents chan<- atc.Event 27 28 exitStatus int 29 ) 30 31 BeforeEach(func() { 32 color.NoColor = false 33 out = gbytes.NewBuffer() 34 stream = new(eventstreamfakes.FakeEventStream) 35 options = eventstream.RenderOptions{} 36 37 events := make(chan atc.Event, 100) 38 receivedEvents = events 39 40 stream.NextEventStub = func() (atc.Event, error) { 41 select { 42 case ev := <-events: 43 return ev, nil 44 default: 45 return nil, io.EOF 46 } 47 } 48 }) 49 50 JustBeforeEach(func() { 51 exitStatus = eventstream.Render(out, stream, options) 52 }) 53 54 Context("when a Log event is received", func() { 55 BeforeEach(func() { 56 receivedEvents <- event.Log{ 57 Payload: "hello", 58 Time: time.Now().Unix(), 59 } 60 }) 61 62 It("prints its payload", func() { 63 Expect(out).To(gbytes.Say("hello")) 64 }) 65 66 Context("and time configuration is enabled", func() { 67 BeforeEach(func() { 68 options.ShowTimestamp = true 69 }) 70 71 It("prints its payload with a timestamp", func() { 72 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}hello`)) 73 }) 74 75 }) 76 }) 77 78 Context("when an Error event is received", func() { 79 BeforeEach(func() { 80 receivedEvents <- event.Error{ 81 Message: "oh no!", 82 } 83 }) 84 85 It("prints its message in bold red, followed by a linebreak", func() { 86 Expect(out.Contents()).To(ContainSubstring(ui.ErroredColor.SprintFunc()("oh no!") + "\n")) 87 }) 88 89 Context("and time configuration is enabled", func() { 90 BeforeEach(func() { 91 options.ShowTimestamp = true 92 }) 93 94 It("empty space is prefixed", func() { 95 Expect(out).To(gbytes.Say(`\s{10}\w*`)) 96 }) 97 }) 98 }) 99 100 Context("when an InitializeTask event is received", func() { 101 BeforeEach(func() { 102 receivedEvents <- event.InitializeTask{ 103 Time: time.Now().Unix(), 104 } 105 }) 106 107 It("prints initializing", func() { 108 Expect(out.Contents()).To(ContainSubstring("\x1b[1minitializing\x1b[0m\n")) 109 }) 110 111 Context("and time configuration is enabled", func() { 112 BeforeEach(func() { 113 options.ShowTimestamp = true 114 }) 115 116 It("timestamp is prefixed", func() { 117 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}\w*`)) 118 }) 119 }) 120 }) 121 122 Context("and a StartTask event is received", func() { 123 BeforeEach(func() { 124 receivedEvents <- event.StartTask{ 125 Time: time.Now().Unix(), 126 TaskConfig: event.TaskConfig{ 127 Image: "some-image", 128 Run: event.TaskRunConfig{ 129 Path: "/some/script", 130 Args: []string{"arg1", "arg2"}, 131 }, 132 }, 133 } 134 }) 135 136 It("prints the build's run script", func() { 137 Expect(out.Contents()).To(ContainSubstring("\x1b[1mrunning /some/script arg1 arg2\x1b[0m\n")) 138 }) 139 140 Context("and time configuration enabled", func() { 141 BeforeEach(func() { 142 options.ShowTimestamp = true 143 }) 144 145 It("timestamp is prefixed", func() { 146 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}\w*`)) 147 }) 148 }) 149 }) 150 151 Context("when a FinishTask event is received", func() { 152 BeforeEach(func() { 153 receivedEvents <- event.FinishTask{ 154 ExitStatus: 42, 155 } 156 }) 157 158 It("returns its exit status", func() { 159 Expect(exitStatus).To(Equal(42)) 160 }) 161 162 Context("and a Status event is received", func() { 163 BeforeEach(func() { 164 receivedEvents <- event.Status{ 165 Status: atc.StatusSucceeded, 166 } 167 }) 168 169 It("still processes it", func() { 170 Expect(out.Contents()).To(ContainSubstring("succeeded")) 171 }) 172 173 It("exits with the status from the FinishTask event", func() { 174 Expect(exitStatus).To(Equal(42)) 175 }) 176 177 Context("and time configuration is enabled", func() { 178 BeforeEach(func() { 179 options.ShowTimestamp = true 180 }) 181 182 It("empty string is prefixed", func() { 183 Expect(out).To(gbytes.Say(`\s{10}\w*`)) 184 }) 185 }) 186 }) 187 }) 188 189 Describe("receiving a Status event", func() { 190 Context("with status 'succeeded'", func() { 191 BeforeEach(func() { 192 receivedEvents <- event.Status{ 193 Status: atc.StatusSucceeded, 194 Time: time.Now().Unix(), 195 } 196 }) 197 198 It("prints it in green", func() { 199 Expect(out.Contents()).To(ContainSubstring(ui.SucceededColor.SprintFunc()("succeeded") + "\n")) 200 }) 201 202 It("exits 0", func() { 203 Expect(exitStatus).To(Equal(0)) 204 }) 205 206 Context("and time configuration is enabled", func() { 207 BeforeEach(func() { 208 options.ShowTimestamp = true 209 }) 210 211 It("timestamp is prefixed", func() { 212 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}\w*`)) 213 }) 214 }) 215 }) 216 217 Context("with status 'failed'", func() { 218 BeforeEach(func() { 219 receivedEvents <- event.Status{ 220 Status: atc.StatusFailed, 221 Time: time.Now().Unix(), 222 } 223 }) 224 225 It("prints it in red", func() { 226 Expect(out.Contents()).To(ContainSubstring(ui.FailedColor.SprintFunc()("failed") + "\n")) 227 }) 228 229 It("exits 1", func() { 230 Expect(exitStatus).To(Equal(1)) 231 }) 232 233 Context("and time configuration is enabled", func() { 234 BeforeEach(func() { 235 options.ShowTimestamp = true 236 }) 237 238 It("timestamp is prefixed", func() { 239 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}\w*`)) 240 }) 241 }) 242 }) 243 244 Context("with status 'errored'", func() { 245 BeforeEach(func() { 246 receivedEvents <- event.Status{ 247 Status: atc.StatusErrored, 248 Time: time.Now().Unix(), 249 } 250 }) 251 252 It("prints it in bold red", func() { 253 Expect(out.Contents()).To(ContainSubstring(ui.ErroredColor.SprintFunc()("errored") + "\n")) 254 }) 255 256 It("exits 2", func() { 257 Expect(exitStatus).To(Equal(2)) 258 }) 259 260 Context("and time configuration is enabled", func() { 261 BeforeEach(func() { 262 options.ShowTimestamp = true 263 }) 264 265 It("timestamp is prefixed", func() { 266 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}\w*`)) 267 }) 268 }) 269 }) 270 271 Context("with status 'aborted'", func() { 272 BeforeEach(func() { 273 receivedEvents <- event.Status{ 274 Status: atc.StatusAborted, 275 Time: time.Now().Unix(), 276 } 277 }) 278 279 It("prints it in yellow", func() { 280 Expect(out.Contents()).To(ContainSubstring(ui.AbortedColor.SprintFunc()("aborted") + "\n")) 281 }) 282 283 It("exits 3", func() { 284 Expect(exitStatus).To(Equal(3)) 285 }) 286 287 Context("and time configuration is enabled", func() { 288 BeforeEach(func() { 289 options.ShowTimestamp = true 290 }) 291 292 It("timestamp is prefixed", func() { 293 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}\w*`)) 294 }) 295 }) 296 }) 297 }) 298 299 Context("when a SelectedWorker event is received", func() { 300 BeforeEach(func() { 301 receivedEvents <- event.SelectedWorker{ 302 Time: time.Now().Unix(), 303 WorkerName: "some-worker", 304 } 305 }) 306 307 It("prints the build's run script", func() { 308 Expect(out.Contents()).To(ContainSubstring("\x1b[1mselected worker:\u001B[0m some-worker\n")) 309 }) 310 311 Context("and time configuration enabled", func() { 312 BeforeEach(func() { 313 options.ShowTimestamp = true 314 }) 315 316 It("timestamp is prefixed", func() { 317 Expect(out).To(gbytes.Say(`\d{2}\:\d{2}\:\d{2}\s{2}\w*`)) 318 }) 319 }) 320 }) 321 322 Context("when an UnknownEventTypeError or UnknownEventVersionError is received", func() { 323 324 BeforeEach(func() { 325 errors := make(chan error, 100) 326 327 stream.NextEventStub = func() (atc.Event, error) { 328 select { 329 case ev := <-errors: 330 return nil, ev 331 default: 332 return nil, io.EOF 333 } 334 } 335 errors <- event.UnknownEventTypeError{"some-event"} 336 errors <- event.UnknownEventVersionError{Type: "some-bad-version-event"} 337 }) 338 339 It("prints the build's run script", func() { 340 Expect(out.Contents()).To(ContainSubstring("failed to parse next event")) 341 }) 342 343 It("exits with 255 exit code", func() { 344 Expect(exitStatus).To(Equal(255)) 345 }) 346 347 Context("when IgnoreEventParsingErrors is configured", func() { 348 BeforeEach(func() { 349 options.IgnoreEventParsingErrors = true 350 }) 351 It("exits with 0 exit code", func() { 352 Expect(exitStatus).To(Equal(0)) 353 }) 354 355 }) 356 357 }) 358 359 })