github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/pkg/stdcopy/stdcopy_test.go (about) 1 package stdcopy 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 "io/ioutil" 8 "strings" 9 "testing" 10 ) 11 12 func TestNewStdWriter(t *testing.T) { 13 writer := NewStdWriter(ioutil.Discard, Stdout) 14 if writer == nil { 15 t.Fatalf("NewStdWriter with an invalid StdType should not return nil.") 16 } 17 } 18 19 func TestWriteWithUnitializedStdWriter(t *testing.T) { 20 writer := StdWriter{ 21 Writer: nil, 22 prefix: Stdout, 23 sizeBuf: make([]byte, 4), 24 } 25 n, err := writer.Write([]byte("Something here")) 26 if n != 0 || err == nil { 27 t.Fatalf("Should fail when given an uncomplete or uninitialized StdWriter") 28 } 29 } 30 31 func TestWriteWithNilBytes(t *testing.T) { 32 writer := NewStdWriter(ioutil.Discard, Stdout) 33 n, err := writer.Write(nil) 34 if err != nil { 35 t.Fatalf("Shouldn't have fail when given no data") 36 } 37 if n > 0 { 38 t.Fatalf("Write should have written 0 byte, but has written %d", n) 39 } 40 } 41 42 func TestWrite(t *testing.T) { 43 writer := NewStdWriter(ioutil.Discard, Stdout) 44 data := []byte("Test StdWrite.Write") 45 n, err := writer.Write(data) 46 if err != nil { 47 t.Fatalf("Error while writing with StdWrite") 48 } 49 if n != len(data) { 50 t.Fatalf("Write should have written %d byte but wrote %d.", len(data), n) 51 } 52 } 53 54 type errWriter struct { 55 n int 56 err error 57 } 58 59 func (f *errWriter) Write(buf []byte) (int, error) { 60 return f.n, f.err 61 } 62 63 func TestWriteWithWriterError(t *testing.T) { 64 expectedError := errors.New("expected") 65 expectedReturnedBytes := 10 66 writer := NewStdWriter(&errWriter{ 67 n: stdWriterPrefixLen + expectedReturnedBytes, 68 err: expectedError}, Stdout) 69 data := []byte("This won't get written, sigh") 70 n, err := writer.Write(data) 71 if err != expectedError { 72 t.Fatalf("Didn't get expected error.") 73 } 74 if n != expectedReturnedBytes { 75 t.Fatalf("Didn't get expected writen bytes %d, got %d.", 76 expectedReturnedBytes, n) 77 } 78 } 79 80 func TestWriteDoesNotReturnNegativeWrittenBytes(t *testing.T) { 81 writer := NewStdWriter(&errWriter{n: -1}, Stdout) 82 data := []byte("This won't get written, sigh") 83 actual, _ := writer.Write(data) 84 if actual != 0 { 85 t.Fatalf("Expected returned written bytes equal to 0, got %d", actual) 86 } 87 } 88 89 func getSrcBuffer(stdOutBytes, stdErrBytes []byte) (buffer *bytes.Buffer, err error) { 90 buffer = new(bytes.Buffer) 91 dstOut := NewStdWriter(buffer, Stdout) 92 _, err = dstOut.Write(stdOutBytes) 93 if err != nil { 94 return 95 } 96 dstErr := NewStdWriter(buffer, Stderr) 97 _, err = dstErr.Write(stdErrBytes) 98 return 99 } 100 101 func TestStdCopyWriteAndRead(t *testing.T) { 102 stdOutBytes := []byte(strings.Repeat("o", startingBufLen)) 103 stdErrBytes := []byte(strings.Repeat("e", startingBufLen)) 104 buffer, err := getSrcBuffer(stdOutBytes, stdErrBytes) 105 if err != nil { 106 t.Fatal(err) 107 } 108 written, err := StdCopy(ioutil.Discard, ioutil.Discard, buffer) 109 if err != nil { 110 t.Fatal(err) 111 } 112 expectedTotalWritten := len(stdOutBytes) + len(stdErrBytes) 113 if written != int64(expectedTotalWritten) { 114 t.Fatalf("Expected to have total of %d bytes written, got %d", expectedTotalWritten, written) 115 } 116 } 117 118 type customReader struct { 119 n int 120 err error 121 totalCalls int 122 correctCalls int 123 src *bytes.Buffer 124 } 125 126 func (f *customReader) Read(buf []byte) (int, error) { 127 f.totalCalls++ 128 if f.totalCalls <= f.correctCalls { 129 return f.src.Read(buf) 130 } 131 return f.n, f.err 132 } 133 134 func TestStdCopyReturnsErrorReadingHeader(t *testing.T) { 135 expectedError := errors.New("error") 136 reader := &customReader{ 137 err: expectedError} 138 written, err := StdCopy(ioutil.Discard, ioutil.Discard, reader) 139 if written != 0 { 140 t.Fatalf("Expected 0 bytes read, got %d", written) 141 } 142 if err != expectedError { 143 t.Fatalf("Didn't get expected error") 144 } 145 } 146 147 func TestStdCopyReturnsErrorReadingFrame(t *testing.T) { 148 expectedError := errors.New("error") 149 stdOutBytes := []byte(strings.Repeat("o", startingBufLen)) 150 stdErrBytes := []byte(strings.Repeat("e", startingBufLen)) 151 buffer, err := getSrcBuffer(stdOutBytes, stdErrBytes) 152 if err != nil { 153 t.Fatal(err) 154 } 155 reader := &customReader{ 156 correctCalls: 1, 157 n: stdWriterPrefixLen + 1, 158 err: expectedError, 159 src: buffer} 160 written, err := StdCopy(ioutil.Discard, ioutil.Discard, reader) 161 if written != 0 { 162 t.Fatalf("Expected 0 bytes read, got %d", written) 163 } 164 if err != expectedError { 165 t.Fatalf("Didn't get expected error") 166 } 167 } 168 169 func TestStdCopyDetectsCorruptedFrame(t *testing.T) { 170 stdOutBytes := []byte(strings.Repeat("o", startingBufLen)) 171 stdErrBytes := []byte(strings.Repeat("e", startingBufLen)) 172 buffer, err := getSrcBuffer(stdOutBytes, stdErrBytes) 173 if err != nil { 174 t.Fatal(err) 175 } 176 reader := &customReader{ 177 correctCalls: 1, 178 n: stdWriterPrefixLen + 1, 179 err: io.EOF, 180 src: buffer} 181 written, err := StdCopy(ioutil.Discard, ioutil.Discard, reader) 182 if written != startingBufLen { 183 t.Fatalf("Expected 0 bytes read, got %d", written) 184 } 185 if err != nil { 186 t.Fatal("Didn't get nil error") 187 } 188 } 189 190 func TestStdCopyWithInvalidInputHeader(t *testing.T) { 191 dstOut := NewStdWriter(ioutil.Discard, Stdout) 192 dstErr := NewStdWriter(ioutil.Discard, Stderr) 193 src := strings.NewReader("Invalid input") 194 _, err := StdCopy(dstOut, dstErr, src) 195 if err == nil { 196 t.Fatal("StdCopy with invalid input header should fail.") 197 } 198 } 199 200 func TestStdCopyWithCorruptedPrefix(t *testing.T) { 201 data := []byte{0x01, 0x02, 0x03} 202 src := bytes.NewReader(data) 203 written, err := StdCopy(nil, nil, src) 204 if err != nil { 205 t.Fatalf("StdCopy should not return an error with corrupted prefix.") 206 } 207 if written != 0 { 208 t.Fatalf("StdCopy should have written 0, but has written %d", written) 209 } 210 } 211 212 func TestStdCopyReturnsWriteErrors(t *testing.T) { 213 stdOutBytes := []byte(strings.Repeat("o", startingBufLen)) 214 stdErrBytes := []byte(strings.Repeat("e", startingBufLen)) 215 buffer, err := getSrcBuffer(stdOutBytes, stdErrBytes) 216 if err != nil { 217 t.Fatal(err) 218 } 219 expectedError := errors.New("expected") 220 221 dstOut := &errWriter{err: expectedError} 222 223 written, err := StdCopy(dstOut, ioutil.Discard, buffer) 224 if written != 0 { 225 t.Fatalf("StdCopy should have written 0, but has written %d", written) 226 } 227 if err != expectedError { 228 t.Fatalf("Didn't get expected error, got %v", err) 229 } 230 } 231 232 func TestStdCopyDetectsNotFullyWrittenFrames(t *testing.T) { 233 stdOutBytes := []byte(strings.Repeat("o", startingBufLen)) 234 stdErrBytes := []byte(strings.Repeat("e", startingBufLen)) 235 buffer, err := getSrcBuffer(stdOutBytes, stdErrBytes) 236 if err != nil { 237 t.Fatal(err) 238 } 239 dstOut := &errWriter{n: startingBufLen - 10} 240 241 written, err := StdCopy(dstOut, ioutil.Discard, buffer) 242 if written != 0 { 243 t.Fatalf("StdCopy should have return 0 written bytes, but returned %d", written) 244 } 245 if err != io.ErrShortWrite { 246 t.Fatalf("Didn't get expected io.ErrShortWrite error") 247 } 248 } 249 250 func BenchmarkWrite(b *testing.B) { 251 w := NewStdWriter(ioutil.Discard, Stdout) 252 data := []byte("Test line for testing stdwriter performance\n") 253 data = bytes.Repeat(data, 100) 254 b.SetBytes(int64(len(data))) 255 b.ResetTimer() 256 for i := 0; i < b.N; i++ { 257 if _, err := w.Write(data); err != nil { 258 b.Fatal(err) 259 } 260 } 261 }