pipe_test.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package io_test
  5. import (
  6. "fmt"
  7. . "io"
  8. "testing"
  9. "time"
  10. )
  11. func checkWrite(t *testing.T, w Writer, data []byte, c chan int) {
  12. n, err := w.Write(data)
  13. if err != nil {
  14. t.Errorf("write: %v", err)
  15. }
  16. if n != len(data) {
  17. t.Errorf("short write: %d != %d", n, len(data))
  18. }
  19. c <- 0
  20. }
  21. // Test a single read/write pair.
  22. func TestPipe1(t *testing.T) {
  23. c := make(chan int)
  24. r, w := Pipe()
  25. var buf = make([]byte, 64)
  26. go checkWrite(t, w, []byte("hello, world"), c)
  27. n, err := r.Read(buf)
  28. if err != nil {
  29. t.Errorf("read: %v", err)
  30. } else if n != 12 || string(buf[0:12]) != "hello, world" {
  31. t.Errorf("bad read: got %q", buf[0:n])
  32. }
  33. <-c
  34. r.Close()
  35. w.Close()
  36. }
  37. func reader(t *testing.T, r Reader, c chan int) {
  38. var buf = make([]byte, 64)
  39. for {
  40. n, err := r.Read(buf)
  41. if err == EOF {
  42. c <- 0
  43. break
  44. }
  45. if err != nil {
  46. t.Errorf("read: %v", err)
  47. }
  48. c <- n
  49. }
  50. }
  51. // Test a sequence of read/write pairs.
  52. func TestPipe2(t *testing.T) {
  53. c := make(chan int)
  54. r, w := Pipe()
  55. go reader(t, r, c)
  56. var buf = make([]byte, 64)
  57. for i := 0; i < 5; i++ {
  58. p := buf[0 : 5+i*10]
  59. n, err := w.Write(p)
  60. if n != len(p) {
  61. t.Errorf("wrote %d, got %d", len(p), n)
  62. }
  63. if err != nil {
  64. t.Errorf("write: %v", err)
  65. }
  66. nn := <-c
  67. if nn != n {
  68. t.Errorf("wrote %d, read got %d", n, nn)
  69. }
  70. }
  71. w.Close()
  72. nn := <-c
  73. if nn != 0 {
  74. t.Errorf("final read got %d", nn)
  75. }
  76. }
  77. type pipeReturn struct {
  78. n int
  79. err error
  80. }
  81. // Test a large write that requires multiple reads to satisfy.
  82. func writer(w WriteCloser, buf []byte, c chan pipeReturn) {
  83. n, err := w.Write(buf)
  84. w.Close()
  85. c <- pipeReturn{n, err}
  86. }
  87. func TestPipe3(t *testing.T) {
  88. c := make(chan pipeReturn)
  89. r, w := Pipe()
  90. var wdat = make([]byte, 128)
  91. for i := 0; i < len(wdat); i++ {
  92. wdat[i] = byte(i)
  93. }
  94. go writer(w, wdat, c)
  95. var rdat = make([]byte, 1024)
  96. tot := 0
  97. for n := 1; n <= 256; n *= 2 {
  98. nn, err := r.Read(rdat[tot : tot+n])
  99. if err != nil && err != EOF {
  100. t.Fatalf("read: %v", err)
  101. }
  102. // only final two reads should be short - 1 byte, then 0
  103. expect := n
  104. if n == 128 {
  105. expect = 1
  106. } else if n == 256 {
  107. expect = 0
  108. if err != EOF {
  109. t.Fatalf("read at end: %v", err)
  110. }
  111. }
  112. if nn != expect {
  113. t.Fatalf("read %d, expected %d, got %d", n, expect, nn)
  114. }
  115. tot += nn
  116. }
  117. pr := <-c
  118. if pr.n != 128 || pr.err != nil {
  119. t.Fatalf("write 128: %d, %v", pr.n, pr.err)
  120. }
  121. if tot != 128 {
  122. t.Fatalf("total read %d != 128", tot)
  123. }
  124. for i := 0; i < 128; i++ {
  125. if rdat[i] != byte(i) {
  126. t.Fatalf("rdat[%d] = %d", i, rdat[i])
  127. }
  128. }
  129. }
  130. // Test read after/before writer close.
  131. type closer interface {
  132. CloseWithError(error) error
  133. Close() error
  134. }
  135. type pipeTest struct {
  136. async bool
  137. err error
  138. closeWithError bool
  139. }
  140. func (p pipeTest) String() string {
  141. return fmt.Sprintf("async=%v err=%v closeWithError=%v", p.async, p.err, p.closeWithError)
  142. }
  143. var pipeTests = []pipeTest{
  144. {true, nil, false},
  145. {true, nil, true},
  146. {true, ErrShortWrite, true},
  147. {false, nil, false},
  148. {false, nil, true},
  149. {false, ErrShortWrite, true},
  150. }
  151. func delayClose(t *testing.T, cl closer, ch chan int, tt pipeTest) {
  152. time.Sleep(1 * time.Millisecond)
  153. var err error
  154. if tt.closeWithError {
  155. err = cl.CloseWithError(tt.err)
  156. } else {
  157. err = cl.Close()
  158. }
  159. if err != nil {
  160. t.Errorf("delayClose: %v", err)
  161. }
  162. ch <- 0
  163. }
  164. func TestPipeReadClose(t *testing.T) {
  165. for _, tt := range pipeTests {
  166. c := make(chan int, 1)
  167. r, w := Pipe()
  168. if tt.async {
  169. go delayClose(t, w, c, tt)
  170. } else {
  171. delayClose(t, w, c, tt)
  172. }
  173. var buf = make([]byte, 64)
  174. n, err := r.Read(buf)
  175. <-c
  176. want := tt.err
  177. if want == nil {
  178. want = EOF
  179. }
  180. if err != want {
  181. t.Errorf("read from closed pipe: %v want %v", err, want)
  182. }
  183. if n != 0 {
  184. t.Errorf("read on closed pipe returned %d", n)
  185. }
  186. if err = r.Close(); err != nil {
  187. t.Errorf("r.Close: %v", err)
  188. }
  189. }
  190. }
  191. // Test close on Read side during Read.
  192. func TestPipeReadClose2(t *testing.T) {
  193. c := make(chan int, 1)
  194. r, _ := Pipe()
  195. go delayClose(t, r, c, pipeTest{})
  196. n, err := r.Read(make([]byte, 64))
  197. <-c
  198. if n != 0 || err != ErrClosedPipe {
  199. t.Errorf("read from closed pipe: %v, %v want %v, %v", n, err, 0, ErrClosedPipe)
  200. }
  201. }
  202. // Test write after/before reader close.
  203. func TestPipeWriteClose(t *testing.T) {
  204. for _, tt := range pipeTests {
  205. c := make(chan int, 1)
  206. r, w := Pipe()
  207. if tt.async {
  208. go delayClose(t, r, c, tt)
  209. } else {
  210. delayClose(t, r, c, tt)
  211. }
  212. n, err := WriteString(w, "hello, world")
  213. <-c
  214. expect := tt.err
  215. if expect == nil {
  216. expect = ErrClosedPipe
  217. }
  218. if err != expect {
  219. t.Errorf("write on closed pipe: %v want %v", err, expect)
  220. }
  221. if n != 0 {
  222. t.Errorf("write on closed pipe returned %d", n)
  223. }
  224. if err = w.Close(); err != nil {
  225. t.Errorf("w.Close: %v", err)
  226. }
  227. }
  228. }
  229. func TestWriteEmpty(t *testing.T) {
  230. r, w := Pipe()
  231. go func() {
  232. w.Write([]byte{})
  233. w.Close()
  234. }()
  235. var b [2]byte
  236. ReadFull(r, b[0:2])
  237. r.Close()
  238. }
  239. func TestWriteNil(t *testing.T) {
  240. r, w := Pipe()
  241. go func() {
  242. w.Write(nil)
  243. w.Close()
  244. }()
  245. var b [2]byte
  246. ReadFull(r, b[0:2])
  247. r.Close()
  248. }
  249. func TestWriteAfterWriterClose(t *testing.T) {
  250. r, w := Pipe()
  251. done := make(chan bool)
  252. var writeErr error
  253. go func() {
  254. _, err := w.Write([]byte("hello"))
  255. if err != nil {
  256. t.Errorf("got error: %q; expected none", err)
  257. }
  258. w.Close()
  259. _, writeErr = w.Write([]byte("world"))
  260. done <- true
  261. }()
  262. buf := make([]byte, 100)
  263. var result string
  264. n, err := ReadFull(r, buf)
  265. if err != nil && err != ErrUnexpectedEOF {
  266. t.Fatalf("got: %q; want: %q", err, ErrUnexpectedEOF)
  267. }
  268. result = string(buf[0:n])
  269. <-done
  270. if result != "hello" {
  271. t.Errorf("got: %q; want: %q", result, "hello")
  272. }
  273. if writeErr != ErrClosedPipe {
  274. t.Errorf("got: %q; want: %q", writeErr, ErrClosedPipe)
  275. }
  276. }