streams_test.go 6.5 KB

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