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