2018-02-05 16:05:59 -05:00
|
|
|
package ioutils // import "github.com/docker/docker/pkg/ioutils"
|
2014-08-12 12:10:43 -04:00
|
|
|
|
|
|
|
import (
|
2018-04-19 18:30:59 -04:00
|
|
|
"context"
|
2015-05-04 13:56:10 -04:00
|
|
|
"fmt"
|
2015-11-13 19:59:01 -05:00
|
|
|
"io/ioutil"
|
2015-05-04 13:56:10 -04:00
|
|
|
"strings"
|
2014-08-12 12:10:43 -04:00
|
|
|
"testing"
|
2015-11-13 19:59:01 -05:00
|
|
|
"time"
|
|
|
|
|
2020-02-07 08:39:24 -05:00
|
|
|
"gotest.tools/v3/assert"
|
|
|
|
is "gotest.tools/v3/assert/cmp"
|
2014-08-12 12:10:43 -04:00
|
|
|
)
|
|
|
|
|
2015-05-04 13:56:10 -04:00
|
|
|
// Implement io.Reader
|
|
|
|
type errorReader struct{}
|
|
|
|
|
|
|
|
func (r *errorReader) Read(p []byte) (int, error) {
|
2017-08-17 15:16:30 -04:00
|
|
|
return 0, fmt.Errorf("error reader always fail")
|
2015-05-04 13:56:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestReadCloserWrapperClose(t *testing.T) {
|
|
|
|
reader := strings.NewReader("A string reader")
|
|
|
|
wrapper := NewReadCloserWrapper(reader, func() error {
|
|
|
|
return fmt.Errorf("This will be called when closing")
|
|
|
|
})
|
|
|
|
err := wrapper.Close()
|
|
|
|
if err == nil || !strings.Contains(err.Error(), "This will be called when closing") {
|
|
|
|
t.Fatalf("readCloserWrapper should have call the anonymous func and thus, fail.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReaderErrWrapperReadOnError(t *testing.T) {
|
|
|
|
called := false
|
|
|
|
reader := &errorReader{}
|
|
|
|
wrapper := NewReaderErrWrapper(reader, func() {
|
|
|
|
called = true
|
|
|
|
})
|
|
|
|
_, err := wrapper.Read([]byte{})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, is.Error(err, "error reader always fail"))
|
2015-05-04 13:56:10 -04:00
|
|
|
if !called {
|
|
|
|
t.Fatalf("readErrWrapper should have call the anonymous function on failure")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReaderErrWrapperRead(t *testing.T) {
|
|
|
|
reader := strings.NewReader("a string reader.")
|
|
|
|
wrapper := NewReaderErrWrapper(reader, func() {
|
2015-07-09 19:23:03 -04:00
|
|
|
t.Fatalf("readErrWrapper should not have called the anonymous function")
|
2015-05-04 13:56:10 -04:00
|
|
|
})
|
|
|
|
// Read 20 byte (should be ok with the string above)
|
|
|
|
num, err := wrapper.Read(make([]byte, 20))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if num != 16 {
|
|
|
|
t.Fatalf("readerErrWrapper should have read 16 byte, but read %d", num)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHashData(t *testing.T) {
|
|
|
|
reader := strings.NewReader("hash-me")
|
|
|
|
actual, err := HashData(reader)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
expected := "sha256:4d11186aed035cc624d553e10db358492c84a7cd6b9670d92123c144930450aa"
|
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("Expecting %s, got %s", expected, actual)
|
|
|
|
}
|
|
|
|
}
|
2015-11-13 19:59:01 -05:00
|
|
|
|
|
|
|
type perpetualReader struct{}
|
|
|
|
|
|
|
|
func (p *perpetualReader) Read(buf []byte) (n int, err error) {
|
|
|
|
for i := 0; i != len(buf); i++ {
|
|
|
|
buf[i] = 'a'
|
|
|
|
}
|
|
|
|
return len(buf), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCancelReadCloser(t *testing.T) {
|
2018-04-19 18:51:35 -04:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
|
|
defer cancel()
|
2015-11-13 19:59:01 -05:00
|
|
|
cancelReadCloser := NewCancelReadCloser(ctx, ioutil.NopCloser(&perpetualReader{}))
|
|
|
|
for {
|
|
|
|
var buf [128]byte
|
|
|
|
_, err := cancelReadCloser.Read(buf[:])
|
|
|
|
if err == context.DeadlineExceeded {
|
|
|
|
break
|
|
|
|
} else if err != nil {
|
|
|
|
t.Fatalf("got unexpected error: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|