github.com/uriddle/docker@v0.0.0-20210926094723-4072e6aeb013/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  }