streams_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package engine
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "strings"
  9. "testing"
  10. )
  11. type sentinelWriteCloser struct {
  12. calledWrite bool
  13. calledClose bool
  14. }
  15. func (w *sentinelWriteCloser) Write(p []byte) (int, error) {
  16. w.calledWrite = true
  17. return len(p), nil
  18. }
  19. func (w *sentinelWriteCloser) Close() error {
  20. w.calledClose = true
  21. return nil
  22. }
  23. func TestOutputAddEnv(t *testing.T) {
  24. input := "{\"foo\": \"bar\", \"answer_to_life_the_universe_and_everything\": 42}"
  25. o := NewOutput()
  26. result, err := o.AddEnv()
  27. if err != nil {
  28. t.Fatal(err)
  29. }
  30. o.Write([]byte(input))
  31. o.Close()
  32. if v := result.Get("foo"); v != "bar" {
  33. t.Errorf("Expected %v, got %v", "bar", v)
  34. }
  35. if v := result.GetInt("answer_to_life_the_universe_and_everything"); v != 42 {
  36. t.Errorf("Expected %v, got %v", 42, v)
  37. }
  38. if v := result.Get("this-value-doesnt-exist"); v != "" {
  39. t.Errorf("Expected %v, got %v", "", v)
  40. }
  41. }
  42. func TestOutputAddClose(t *testing.T) {
  43. o := NewOutput()
  44. var s sentinelWriteCloser
  45. o.Add(&s)
  46. if err := o.Close(); err != nil {
  47. t.Fatal(err)
  48. }
  49. // Write data after the output is closed.
  50. // Write should succeed, but no destination should receive it.
  51. if _, err := o.Write([]byte("foo bar")); err != nil {
  52. t.Fatal(err)
  53. }
  54. if !s.calledClose {
  55. t.Fatal("Output.Close() didn't close the destination")
  56. }
  57. }
  58. func TestOutputAddPipe(t *testing.T) {
  59. var testInputs = []string{
  60. "hello, world!",
  61. "One\nTwo\nThree",
  62. "",
  63. "A line\nThen another nl-terminated line\n",
  64. "A line followed by an empty line\n\n",
  65. }
  66. for _, input := range testInputs {
  67. expectedOutput := input
  68. o := NewOutput()
  69. r, err := o.AddPipe()
  70. if err != nil {
  71. t.Fatal(err)
  72. }
  73. go func(o *Output) {
  74. if n, err := o.Write([]byte(input)); err != nil {
  75. t.Error(err)
  76. } else if n != len(input) {
  77. t.Errorf("Expected %d, got %d", len(input), n)
  78. }
  79. if err := o.Close(); err != nil {
  80. t.Error(err)
  81. }
  82. }(o)
  83. output, err := ioutil.ReadAll(r)
  84. if err != nil {
  85. t.Fatal(err)
  86. }
  87. if string(output) != expectedOutput {
  88. t.Errorf("Last line is not stored as return string.\nExpected: '%s'\nGot: '%s'", expectedOutput, output)
  89. }
  90. }
  91. }
  92. func TestTail(t *testing.T) {
  93. var tests = make(map[string][]string)
  94. tests["hello, world!"] = []string{
  95. "",
  96. "hello, world!",
  97. "hello, world!",
  98. "hello, world!",
  99. }
  100. tests["One\nTwo\nThree"] = []string{
  101. "",
  102. "Three",
  103. "Two\nThree",
  104. "One\nTwo\nThree",
  105. }
  106. tests["One\nTwo\n\n\n"] = []string{
  107. "",
  108. "Two",
  109. "One\nTwo",
  110. }
  111. for input, outputs := range tests {
  112. for n, expectedOutput := range outputs {
  113. output := Tail(bytes.NewBufferString(input), n)
  114. if output != expectedOutput {
  115. t.Errorf("Tail n=%d returned wrong result.\nExpected: '%s'\nGot : '%s'", n, expectedOutput, output)
  116. }
  117. }
  118. }
  119. }
  120. func lastLine(txt string) string {
  121. scanner := bufio.NewScanner(strings.NewReader(txt))
  122. var lastLine string
  123. for scanner.Scan() {
  124. lastLine = scanner.Text()
  125. }
  126. return lastLine
  127. }
  128. func TestOutputAdd(t *testing.T) {
  129. o := NewOutput()
  130. b := &bytes.Buffer{}
  131. o.Add(b)
  132. input := "hello, world!"
  133. if n, err := o.Write([]byte(input)); err != nil {
  134. t.Fatal(err)
  135. } else if n != len(input) {
  136. t.Fatalf("Expected %d, got %d", len(input), n)
  137. }
  138. if output := b.String(); output != input {
  139. t.Fatalf("Received wrong data from Add.\nExpected: '%s'\nGot: '%s'", input, output)
  140. }
  141. }
  142. func TestOutputWriteError(t *testing.T) {
  143. o := NewOutput()
  144. buf := &bytes.Buffer{}
  145. o.Add(buf)
  146. r, w := io.Pipe()
  147. input := "Hello there"
  148. expectedErr := fmt.Errorf("This is an error")
  149. r.CloseWithError(expectedErr)
  150. o.Add(w)
  151. n, err := o.Write([]byte(input))
  152. if err != expectedErr {
  153. t.Fatalf("Output.Write() should return the first error encountered, if any")
  154. }
  155. if buf.String() != input {
  156. t.Fatalf("Output.Write() should attempt write on all destinations, even after encountering an error")
  157. }
  158. if n != len(input) {
  159. t.Fatalf("Output.Write() should return the size of the input if it successfully writes to at least one destination")
  160. }
  161. }
  162. func TestInputAddEmpty(t *testing.T) {
  163. i := NewInput()
  164. var b bytes.Buffer
  165. if err := i.Add(&b); err != nil {
  166. t.Fatal(err)
  167. }
  168. data, err := ioutil.ReadAll(i)
  169. if err != nil {
  170. t.Fatal(err)
  171. }
  172. if len(data) > 0 {
  173. t.Fatalf("Read from empty input should yield no data")
  174. }
  175. }
  176. func TestInputAddTwo(t *testing.T) {
  177. i := NewInput()
  178. var b1 bytes.Buffer
  179. // First add should succeed
  180. if err := i.Add(&b1); err != nil {
  181. t.Fatal(err)
  182. }
  183. var b2 bytes.Buffer
  184. // Second add should fail
  185. if err := i.Add(&b2); err == nil {
  186. t.Fatalf("Adding a second source should return an error")
  187. }
  188. }
  189. func TestInputAddNotEmpty(t *testing.T) {
  190. i := NewInput()
  191. b := bytes.NewBufferString("hello world\nabc")
  192. expectedResult := b.String()
  193. i.Add(b)
  194. result, err := ioutil.ReadAll(i)
  195. if err != nil {
  196. t.Fatal(err)
  197. }
  198. if string(result) != expectedResult {
  199. t.Fatalf("Expected: %v\nReceived: %v", expectedResult, result)
  200. }
  201. }