github.com/torfuzx/docker@v1.8.1/pkg/ioutils/readers_test.go (about) 1 package ioutils 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "strings" 9 "testing" 10 ) 11 12 // Implement io.Reader 13 type errorReader struct{} 14 15 func (r *errorReader) Read(p []byte) (int, error) { 16 return 0, fmt.Errorf("Error reader always fail.") 17 } 18 19 func TestReadCloserWrapperClose(t *testing.T) { 20 reader := strings.NewReader("A string reader") 21 wrapper := NewReadCloserWrapper(reader, func() error { 22 return fmt.Errorf("This will be called when closing") 23 }) 24 err := wrapper.Close() 25 if err == nil || !strings.Contains(err.Error(), "This will be called when closing") { 26 t.Fatalf("readCloserWrapper should have call the anonymous func and thus, fail.") 27 } 28 } 29 30 func TestReaderErrWrapperReadOnError(t *testing.T) { 31 called := false 32 reader := &errorReader{} 33 wrapper := NewReaderErrWrapper(reader, func() { 34 called = true 35 }) 36 _, err := wrapper.Read([]byte{}) 37 if err == nil || !strings.Contains(err.Error(), "Error reader always fail.") { 38 t.Fatalf("readErrWrapper should returned an error") 39 } 40 if !called { 41 t.Fatalf("readErrWrapper should have call the anonymous function on failure") 42 } 43 } 44 45 func TestReaderErrWrapperRead(t *testing.T) { 46 reader := strings.NewReader("a string reader.") 47 wrapper := NewReaderErrWrapper(reader, func() { 48 t.Fatalf("readErrWrapper should not have called the anonymous function") 49 }) 50 // Read 20 byte (should be ok with the string above) 51 num, err := wrapper.Read(make([]byte, 20)) 52 if err != nil { 53 t.Fatal(err) 54 } 55 if num != 16 { 56 t.Fatalf("readerErrWrapper should have read 16 byte, but read %d", num) 57 } 58 } 59 60 func TestNewBufReaderWithDrainbufAndBuffer(t *testing.T) { 61 reader, writer := io.Pipe() 62 63 drainBuffer := make([]byte, 1024) 64 buffer := bytes.Buffer{} 65 bufreader := NewBufReaderWithDrainbufAndBuffer(reader, drainBuffer, &buffer) 66 67 // Write everything down to a Pipe 68 // Usually, a pipe should block but because of the buffered reader, 69 // the writes will go through 70 done := make(chan bool) 71 go func() { 72 writer.Write([]byte("hello world")) 73 writer.Close() 74 done <- true 75 }() 76 77 // Drain the reader *after* everything has been written, just to verify 78 // it is indeed buffering 79 <-done 80 81 output, err := ioutil.ReadAll(bufreader) 82 if err != nil { 83 t.Fatal(err) 84 } 85 if !bytes.Equal(output, []byte("hello world")) { 86 t.Error(string(output)) 87 } 88 } 89 90 func TestBufReader(t *testing.T) { 91 reader, writer := io.Pipe() 92 bufreader := NewBufReader(reader) 93 94 // Write everything down to a Pipe 95 // Usually, a pipe should block but because of the buffered reader, 96 // the writes will go through 97 done := make(chan bool) 98 go func() { 99 writer.Write([]byte("hello world")) 100 writer.Close() 101 done <- true 102 }() 103 104 // Drain the reader *after* everything has been written, just to verify 105 // it is indeed buffering 106 <-done 107 output, err := ioutil.ReadAll(bufreader) 108 if err != nil { 109 t.Fatal(err) 110 } 111 if !bytes.Equal(output, []byte("hello world")) { 112 t.Error(string(output)) 113 } 114 } 115 116 func TestBufReaderCloseWithNonReaderCloser(t *testing.T) { 117 reader := strings.NewReader("buffer") 118 bufreader := NewBufReader(reader) 119 120 if err := bufreader.Close(); err != nil { 121 t.Fatal(err) 122 } 123 124 } 125 126 // implements io.ReadCloser 127 type simpleReaderCloser struct{} 128 129 func (r *simpleReaderCloser) Read(p []byte) (n int, err error) { 130 return 0, nil 131 } 132 133 func (r *simpleReaderCloser) Close() error { 134 return nil 135 } 136 137 func TestBufReaderCloseWithReaderCloser(t *testing.T) { 138 reader := &simpleReaderCloser{} 139 bufreader := NewBufReader(reader) 140 141 err := bufreader.Close() 142 if err != nil { 143 t.Fatal(err) 144 } 145 146 } 147 148 func TestHashData(t *testing.T) { 149 reader := strings.NewReader("hash-me") 150 actual, err := HashData(reader) 151 if err != nil { 152 t.Fatal(err) 153 } 154 expected := "sha256:4d11186aed035cc624d553e10db358492c84a7cd6b9670d92123c144930450aa" 155 if actual != expected { 156 t.Fatalf("Expecting %s, got %s", expected, actual) 157 } 158 } 159 160 type repeatedReader struct { 161 readCount int 162 maxReads int 163 data []byte 164 } 165 166 func newRepeatedReader(max int, data []byte) *repeatedReader { 167 return &repeatedReader{0, max, data} 168 } 169 170 func (r *repeatedReader) Read(p []byte) (int, error) { 171 if r.readCount >= r.maxReads { 172 return 0, io.EOF 173 } 174 r.readCount++ 175 n := copy(p, r.data) 176 return n, nil 177 } 178 179 func testWithData(data []byte, reads int) { 180 reader := newRepeatedReader(reads, data) 181 bufReader := NewBufReader(reader) 182 io.Copy(ioutil.Discard, bufReader) 183 } 184 185 func Benchmark1M10BytesReads(b *testing.B) { 186 reads := 1000000 187 readSize := int64(10) 188 data := make([]byte, readSize) 189 b.SetBytes(readSize * int64(reads)) 190 b.ResetTimer() 191 for i := 0; i < b.N; i++ { 192 testWithData(data, reads) 193 } 194 } 195 196 func Benchmark1M1024BytesReads(b *testing.B) { 197 reads := 1000000 198 readSize := int64(1024) 199 data := make([]byte, readSize) 200 b.SetBytes(readSize * int64(reads)) 201 b.ResetTimer() 202 for i := 0; i < b.N; i++ { 203 testWithData(data, reads) 204 } 205 } 206 207 func Benchmark10k32KBytesReads(b *testing.B) { 208 reads := 10000 209 readSize := int64(32 * 1024) 210 data := make([]byte, readSize) 211 b.SetBytes(readSize * int64(reads)) 212 b.ResetTimer() 213 for i := 0; i < b.N; i++ { 214 testWithData(data, reads) 215 } 216 }