1
16
17 package io
18
19 import (
20 "fmt"
21 "io/ioutil"
22 "os"
23 "path/filepath"
24 "strings"
25 "syscall"
26 "testing"
27 )
28
29 func writeToPipe(namedPipe string, flaky bool, i int) {
30 pipe, err := os.OpenFile(namedPipe, os.O_WRONLY, 0600)
31 if err != nil {
32 return
33 }
34
35
36
37 outstr := fmt.Sprintf("Foobar %t", (i <= 0))
38
39 if flaky {
40 outstr = fmt.Sprintf("Foobar %d", i)
41 }
42
43 pipe.Write([]byte(outstr))
44 pipe.Close()
45 }
46
47 func makePipe(t *testing.T) string {
48 tmp, err := ioutil.TempDir("", "pipe-test")
49 if err != nil {
50 t.Fatal(err)
51 }
52
53 pipe := filepath.Join(tmp, "pipe")
54 syscall.Mkfifo(pipe, 0600)
55
56 return pipe
57 }
58
59 func writer(namedPipe string, flaky bool, c <-chan int, d <-chan bool) {
60
61
62 writeToPipe(namedPipe, flaky, -1)
63
64 for {
65 select {
66 case i := <-c:
67 writeToPipe(namedPipe, flaky, i)
68 case <-d:
69 os.RemoveAll(namedPipe)
70 return
71 }
72 }
73 }
74
75 func TestConsistentRead(t *testing.T) {
76 pipe := makePipe(t)
77 prog, done := make(chan int), make(chan bool)
78 go writer(pipe, false, prog, done)
79
80 if _, err := consistentReadSync(pipe, 3, func(i int) { prog <- i }); err != nil {
81 t.Fatal(err)
82 }
83
84 done <- true
85 }
86
87 func TestConsistentReadFlakyReader(t *testing.T) {
88 pipe := makePipe(t)
89 prog, done := make(chan int), make(chan bool)
90 go writer(pipe, true, prog, done)
91
92 var err error
93 if _, err = consistentReadSync(pipe, 3, func(i int) { prog <- i }); err == nil {
94 t.Fatal("flaky reader returned consistent results")
95 }
96 if !IsInconsistentReadError(err) {
97 t.Errorf("Unexpected error returned, expected InconsistentReadError, got: %T / %q", err, err)
98 }
99 }
100
101 func TestReadAtMost(t *testing.T) {
102 testCases := []struct {
103 limit int64
104 data string
105 errMsg string
106 }{
107 {4, "hell", "the read limit is reached"},
108 {5, "hello", "the read limit is reached"},
109 {6, "hello", ""},
110 }
111
112 for _, tc := range testCases {
113 r := strings.NewReader("hello")
114 data, err := ReadAtMost(r, tc.limit)
115 if string(data) != tc.data {
116 t.Errorf("Read limit %d: expected \"%s\", got \"%s\"", tc.limit, tc.data, string(data))
117 }
118
119 if err == nil && tc.errMsg != "" {
120 t.Errorf("Read limit %d: expected error with message \"%s\", got no error", tc.limit, tc.errMsg)
121 }
122
123 if err != nil && err.Error() != tc.errMsg {
124 t.Errorf("Read limit %d: expected error with message \"%s\", got error with message \"%s\"", tc.limit, tc.errMsg, err.Error())
125 }
126 }
127 }
128
View as plain text