123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- package engine
- import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "strings"
- "testing"
- )
- type sentinelWriteCloser struct {
- calledWrite bool
- calledClose bool
- }
- func (w *sentinelWriteCloser) Write(p []byte) (int, error) {
- w.calledWrite = true
- return len(p), nil
- }
- func (w *sentinelWriteCloser) Close() error {
- w.calledClose = true
- return nil
- }
- func TestOutputAddEnv(t *testing.T) {
- input := "{\"foo\": \"bar\", \"answer_to_life_the_universe_and_everything\": 42}"
- o := NewOutput()
- result, err := o.AddEnv()
- if err != nil {
- t.Fatal(err)
- }
- o.Write([]byte(input))
- o.Close()
- if v := result.Get("foo"); v != "bar" {
- t.Errorf("Expected %v, got %v", "bar", v)
- }
- if v := result.GetInt("answer_to_life_the_universe_and_everything"); v != 42 {
- t.Errorf("Expected %v, got %v", 42, v)
- }
- if v := result.Get("this-value-doesnt-exist"); v != "" {
- t.Errorf("Expected %v, got %v", "", v)
- }
- }
- func TestOutputAddClose(t *testing.T) {
- o := NewOutput()
- var s sentinelWriteCloser
- o.Add(&s)
- if err := o.Close(); err != nil {
- t.Fatal(err)
- }
- // Write data after the output is closed.
- // Write should succeed, but no destination should receive it.
- if _, err := o.Write([]byte("foo bar")); err != nil {
- t.Fatal(err)
- }
- if !s.calledClose {
- t.Fatal("Output.Close() didn't close the destination")
- }
- }
- func TestOutputAddPipe(t *testing.T) {
- var testInputs = []string{
- "hello, world!",
- "One\nTwo\nThree",
- "",
- "A line\nThen another nl-terminated line\n",
- "A line followed by an empty line\n\n",
- }
- for _, input := range testInputs {
- expectedOutput := input
- o := NewOutput()
- r, err := o.AddPipe()
- if err != nil {
- t.Fatal(err)
- }
- go func(o *Output) {
- if n, err := o.Write([]byte(input)); err != nil {
- t.Error(err)
- } else if n != len(input) {
- t.Errorf("Expected %d, got %d", len(input), n)
- }
- if err := o.Close(); err != nil {
- t.Error(err)
- }
- }(o)
- output, err := ioutil.ReadAll(r)
- if err != nil {
- t.Fatal(err)
- }
- if string(output) != expectedOutput {
- t.Errorf("Last line is not stored as return string.\nExpected: '%s'\nGot: '%s'", expectedOutput, output)
- }
- }
- }
- func TestTail(t *testing.T) {
- var tests = make(map[string][]string)
- tests["hello, world!"] = []string{
- "",
- "hello, world!",
- "hello, world!",
- "hello, world!",
- }
- tests["One\nTwo\nThree"] = []string{
- "",
- "Three",
- "Two\nThree",
- "One\nTwo\nThree",
- }
- for input, outputs := range tests {
- for n, expectedOutput := range outputs {
- output := Tail(bytes.NewBufferString(input), n)
- if output != expectedOutput {
- t.Errorf("Tail n=%d returned wrong result.\nExpected: '%s'\nGot : '%s'", n, expectedOutput, output)
- }
- }
- }
- }
- func lastLine(txt string) string {
- scanner := bufio.NewScanner(strings.NewReader(txt))
- var lastLine string
- for scanner.Scan() {
- lastLine = scanner.Text()
- }
- return lastLine
- }
- func TestOutputAdd(t *testing.T) {
- o := NewOutput()
- b := &bytes.Buffer{}
- o.Add(b)
- input := "hello, world!"
- if n, err := o.Write([]byte(input)); err != nil {
- t.Fatal(err)
- } else if n != len(input) {
- t.Fatalf("Expected %d, got %d", len(input), n)
- }
- if output := b.String(); output != input {
- t.Fatalf("Received wrong data from Add.\nExpected: '%s'\nGot: '%s'", input, output)
- }
- }
- func TestOutputWriteError(t *testing.T) {
- o := NewOutput()
- buf := &bytes.Buffer{}
- o.Add(buf)
- r, w := io.Pipe()
- input := "Hello there"
- expectedErr := fmt.Errorf("This is an error")
- r.CloseWithError(expectedErr)
- o.Add(w)
- n, err := o.Write([]byte(input))
- if err != expectedErr {
- t.Fatalf("Output.Write() should return the first error encountered, if any")
- }
- if buf.String() != input {
- t.Fatalf("Output.Write() should attempt write on all destinations, even after encountering an error")
- }
- if n != len(input) {
- t.Fatalf("Output.Write() should return the size of the input if it successfully writes to at least one destination")
- }
- }
- func TestInputAddEmpty(t *testing.T) {
- i := NewInput()
- var b bytes.Buffer
- if err := i.Add(&b); err != nil {
- t.Fatal(err)
- }
- data, err := ioutil.ReadAll(i)
- if err != nil {
- t.Fatal(err)
- }
- if len(data) > 0 {
- t.Fatalf("Read from empty input shoul yield no data")
- }
- }
- func TestInputAddTwo(t *testing.T) {
- i := NewInput()
- var b1 bytes.Buffer
- // First add should succeed
- if err := i.Add(&b1); err != nil {
- t.Fatal(err)
- }
- var b2 bytes.Buffer
- // Second add should fail
- if err := i.Add(&b2); err == nil {
- t.Fatalf("Adding a second source should return an error")
- }
- }
- func TestInputAddNotEmpty(t *testing.T) {
- i := NewInput()
- b := bytes.NewBufferString("hello world\nabc")
- expectedResult := b.String()
- i.Add(b)
- result, err := ioutil.ReadAll(i)
- if err != nil {
- t.Fatal(err)
- }
- if string(result) != expectedResult {
- t.Fatalf("Expected: %v\nReceived: %v", expectedResult, result)
- }
- }
|