github.com/codemac/docker@v1.2.1-0.20150518222241-6a18412d5b9c/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  	called := false
    47  	reader := strings.NewReader("a string reader.")
    48  	wrapper := NewReaderErrWrapper(reader, func() {
    49  		called = true // Should not be called
    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 := bytes.Buffer{}
    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  	<-done
    81  
    82  	output, err := ioutil.ReadAll(bufreader)
    83  	if err != nil {
    84  		t.Fatal(err)
    85  	}
    86  	if !bytes.Equal(output, []byte("hello world")) {
    87  		t.Error(string(output))
    88  	}
    89  }
    90  
    91  func TestBufReader(t *testing.T) {
    92  	reader, writer := io.Pipe()
    93  	bufreader := NewBufReader(reader)
    94  
    95  	// Write everything down to a Pipe
    96  	// Usually, a pipe should block but because of the buffered reader,
    97  	// the writes will go through
    98  	done := make(chan bool)
    99  	go func() {
   100  		writer.Write([]byte("hello world"))
   101  		writer.Close()
   102  		done <- true
   103  	}()
   104  
   105  	// Drain the reader *after* everything has been written, just to verify
   106  	// it is indeed buffering
   107  	<-done
   108  	output, err := ioutil.ReadAll(bufreader)
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  	if !bytes.Equal(output, []byte("hello world")) {
   113  		t.Error(string(output))
   114  	}
   115  }
   116  
   117  func TestBufReaderCloseWithNonReaderCloser(t *testing.T) {
   118  	reader := strings.NewReader("buffer")
   119  	bufreader := NewBufReader(reader)
   120  
   121  	if err := bufreader.Close(); err != nil {
   122  		t.Fatal(err)
   123  	}
   124  
   125  }
   126  
   127  // implements io.ReadCloser
   128  type simpleReaderCloser struct{}
   129  
   130  func (r *simpleReaderCloser) Read(p []byte) (n int, err error) {
   131  	return 0, nil
   132  }
   133  
   134  func (r *simpleReaderCloser) Close() error {
   135  	return nil
   136  }
   137  
   138  func TestBufReaderCloseWithReaderCloser(t *testing.T) {
   139  	reader := &simpleReaderCloser{}
   140  	bufreader := NewBufReader(reader)
   141  
   142  	err := bufreader.Close()
   143  	if err != nil {
   144  		t.Fatal(err)
   145  	}
   146  
   147  }
   148  
   149  func TestHashData(t *testing.T) {
   150  	reader := strings.NewReader("hash-me")
   151  	actual, err := HashData(reader)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	expected := "sha256:4d11186aed035cc624d553e10db358492c84a7cd6b9670d92123c144930450aa"
   156  	if actual != expected {
   157  		t.Fatalf("Expecting %s, got %s", expected, actual)
   158  	}
   159  }
   160  
   161  type repeatedReader struct {
   162  	readCount int
   163  	maxReads  int
   164  	data      []byte
   165  }
   166  
   167  func newRepeatedReader(max int, data []byte) *repeatedReader {
   168  	return &repeatedReader{0, max, data}
   169  }
   170  
   171  func (r *repeatedReader) Read(p []byte) (int, error) {
   172  	if r.readCount >= r.maxReads {
   173  		return 0, io.EOF
   174  	}
   175  	r.readCount++
   176  	n := copy(p, r.data)
   177  	return n, nil
   178  }
   179  
   180  func testWithData(data []byte, reads int) {
   181  	reader := newRepeatedReader(reads, data)
   182  	bufReader := NewBufReader(reader)
   183  	io.Copy(ioutil.Discard, bufReader)
   184  }
   185  
   186  func Benchmark1M10BytesReads(b *testing.B) {
   187  	reads := 1000000
   188  	readSize := int64(10)
   189  	data := make([]byte, readSize)
   190  	b.SetBytes(readSize * int64(reads))
   191  	b.ResetTimer()
   192  	for i := 0; i < b.N; i++ {
   193  		testWithData(data, reads)
   194  	}
   195  }
   196  
   197  func Benchmark1M1024BytesReads(b *testing.B) {
   198  	reads := 1000000
   199  	readSize := int64(1024)
   200  	data := make([]byte, readSize)
   201  	b.SetBytes(readSize * int64(reads))
   202  	b.ResetTimer()
   203  	for i := 0; i < b.N; i++ {
   204  		testWithData(data, reads)
   205  	}
   206  }
   207  
   208  func Benchmark10k32KBytesReads(b *testing.B) {
   209  	reads := 10000
   210  	readSize := int64(32 * 1024)
   211  	data := make([]byte, readSize)
   212  	b.SetBytes(readSize * int64(reads))
   213  	b.ResetTimer()
   214  	for i := 0; i < b.N; i++ {
   215  		testWithData(data, reads)
   216  	}
   217  }