2018-02-05 21:05:59 +00:00
|
|
|
package ioutils // import "github.com/docker/docker/pkg/ioutils"
|
2014-08-12 16:10:43 +00:00
|
|
|
|
|
|
|
import (
|
2018-04-19 22:30:59 +00:00
|
|
|
"context"
|
2023-07-12 22:26:11 +00:00
|
|
|
"errors"
|
2021-08-24 10:10:50 +00:00
|
|
|
"io"
|
2015-05-04 17:56:10 +00:00
|
|
|
"strings"
|
2014-08-12 16:10:43 +00:00
|
|
|
"testing"
|
2023-07-12 22:26:11 +00:00
|
|
|
"testing/iotest"
|
2015-11-14 00:59:01 +00:00
|
|
|
"time"
|
2014-08-12 16:10:43 +00:00
|
|
|
)
|
|
|
|
|
2015-05-04 17:56:10 +00:00
|
|
|
func TestReadCloserWrapperClose(t *testing.T) {
|
2023-07-12 22:26:11 +00:00
|
|
|
const text = "hello world"
|
|
|
|
testErr := errors.New("this will be called when closing")
|
|
|
|
wrapper := NewReadCloserWrapper(strings.NewReader(text), func() error {
|
|
|
|
return testErr
|
2015-05-04 17:56:10 +00:00
|
|
|
})
|
2023-07-12 22:26:11 +00:00
|
|
|
|
|
|
|
buf, err := io.ReadAll(wrapper)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("io.ReadAll(wrapper) err = %v", err)
|
|
|
|
}
|
|
|
|
if string(buf) != text {
|
|
|
|
t.Errorf("expected %v, got: %v", text, string(buf))
|
|
|
|
}
|
|
|
|
err = wrapper.Close()
|
|
|
|
if !errors.Is(err, testErr) {
|
|
|
|
// readCloserWrapper should have called the anonymous func and thus, fail
|
|
|
|
t.Errorf("expected %v, got: %v", testErr, err)
|
2015-05-04 17:56:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReaderErrWrapperReadOnError(t *testing.T) {
|
|
|
|
called := false
|
2023-07-12 22:26:11 +00:00
|
|
|
expectedErr := errors.New("error reader always fail")
|
|
|
|
wrapper := NewReaderErrWrapper(iotest.ErrReader(expectedErr), func() {
|
2015-05-04 17:56:10 +00:00
|
|
|
called = true
|
|
|
|
})
|
|
|
|
_, err := wrapper.Read([]byte{})
|
2023-07-12 22:26:11 +00:00
|
|
|
if !errors.Is(err, expectedErr) {
|
|
|
|
t.Errorf("expected %v, got: %v", expectedErr, err)
|
|
|
|
}
|
2015-05-04 17:56:10 +00:00
|
|
|
if !called {
|
2023-07-12 22:26:11 +00:00
|
|
|
t.Fatalf("readErrWrapper should have called the anonymous function on failure")
|
2015-05-04 17:56:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReaderErrWrapperRead(t *testing.T) {
|
2023-07-12 22:26:11 +00:00
|
|
|
const text = "hello world"
|
|
|
|
wrapper := NewReaderErrWrapper(strings.NewReader(text), func() {
|
2015-07-09 23:23:03 +00:00
|
|
|
t.Fatalf("readErrWrapper should not have called the anonymous function")
|
2015-05-04 17:56:10 +00:00
|
|
|
})
|
2023-07-12 22:26:11 +00:00
|
|
|
num, err := wrapper.Read(make([]byte, len(text)+10))
|
2015-05-04 17:56:10 +00:00
|
|
|
if err != nil {
|
2023-07-12 22:26:11 +00:00
|
|
|
t.Error(err)
|
2015-05-04 17:56:10 +00:00
|
|
|
}
|
2023-07-12 22:26:11 +00:00
|
|
|
if expected := len(text); num != expected {
|
|
|
|
t.Errorf("readerErrWrapper should have read %d byte, but read %d", expected, num)
|
2015-05-04 17:56:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-14 00:59:01 +00: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 22:51:35 +00:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
|
|
defer cancel()
|
2023-07-12 22:26:11 +00:00
|
|
|
crc := NewCancelReadCloser(ctx, io.NopCloser(&perpetualReader{}))
|
2015-11-14 00:59:01 +00:00
|
|
|
for {
|
|
|
|
var buf [128]byte
|
2023-07-12 22:26:11 +00:00
|
|
|
_, err := crc.Read(buf[:])
|
2015-11-14 00:59:01 +00:00
|
|
|
if err == context.DeadlineExceeded {
|
|
|
|
break
|
|
|
|
} else if err != nil {
|
|
|
|
t.Fatalf("got unexpected error: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|