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