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