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  }