package pools // import "github.com/docker/docker/pkg/pools" import ( "bufio" "bytes" "io" "strings" "testing" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) func TestBufioReaderPoolGetWithNoReaderShouldCreateOne(t *testing.T) { reader := BufioReader32KPool.Get(nil) if reader == nil { t.Fatalf("BufioReaderPool should have create a bufio.Reader but did not.") } } func TestBufioReaderPoolPutAndGet(t *testing.T) { sr := bufio.NewReader(strings.NewReader("foobar")) reader := BufioReader32KPool.Get(sr) if reader == nil { t.Fatalf("BufioReaderPool should not return a nil reader.") } // verify the first 3 byte buf1 := make([]byte, 3) _, err := reader.Read(buf1) if err != nil { t.Fatal(err) } if actual := string(buf1); actual != "foo" { t.Fatalf("The first letter should have been 'foo' but was %v", actual) } BufioReader32KPool.Put(reader) // Try to read the next 3 bytes _, err = sr.Read(make([]byte, 3)) if err == nil || err != io.EOF { t.Fatalf("The buffer should have been empty, issue an EOF error.") } } type simpleReaderCloser struct { io.Reader closed bool } func (r *simpleReaderCloser) Close() error { r.closed = true return nil } func TestNewReadCloserWrapperWithAReadCloser(t *testing.T) { br := bufio.NewReader(strings.NewReader("")) sr := &simpleReaderCloser{ Reader: strings.NewReader("foobar"), closed: false, } reader := BufioReader32KPool.NewReadCloserWrapper(br, sr) if reader == nil { t.Fatalf("NewReadCloserWrapper should not return a nil reader.") } // Verify the content of reader buf := make([]byte, 3) _, err := reader.Read(buf) if err != nil { t.Fatal(err) } if actual := string(buf); actual != "foo" { t.Fatalf("The first 3 letter should have been 'foo' but were %v", actual) } reader.Close() // Read 3 more bytes "bar" _, err = reader.Read(buf) if err != nil { t.Fatal(err) } if actual := string(buf); actual != "bar" { t.Fatalf("The first 3 letter should have been 'bar' but were %v", actual) } if !sr.closed { t.Fatalf("The ReaderCloser should have been closed, it is not.") } } func TestBufioWriterPoolGetWithNoReaderShouldCreateOne(t *testing.T) { writer := BufioWriter32KPool.Get(nil) if writer == nil { t.Fatalf("BufioWriterPool should have create a bufio.Writer but did not.") } } func TestBufioWriterPoolPutAndGet(t *testing.T) { buf := new(bytes.Buffer) bw := bufio.NewWriter(buf) writer := BufioWriter32KPool.Get(bw) assert.Assert(t, writer != nil) written, err := writer.Write([]byte("foobar")) assert.NilError(t, err) assert.Check(t, is.Equal(6, written)) // Make sure we Flush all the way ? writer.Flush() bw.Flush() assert.Check(t, is.Len(buf.Bytes(), 6)) // Reset the buffer buf.Reset() BufioWriter32KPool.Put(writer) // Try to write something if _, err = writer.Write([]byte("barfoo")); err != nil { t.Fatal(err) } // If we now try to flush it, it should panic (the writer is nil) // recover it defer func() { if r := recover(); r == nil { t.Fatal("Trying to flush the writter should have 'paniced', did not.") } }() writer.Flush() } type simpleWriterCloser struct { io.Writer closed bool } func (r *simpleWriterCloser) Close() error { r.closed = true return nil } func TestNewWriteCloserWrapperWithAWriteCloser(t *testing.T) { buf := new(bytes.Buffer) bw := bufio.NewWriter(buf) sw := &simpleWriterCloser{ Writer: new(bytes.Buffer), closed: false, } bw.Flush() writer := BufioWriter32KPool.NewWriteCloserWrapper(bw, sw) if writer == nil { t.Fatalf("BufioReaderPool should not return a nil writer.") } written, err := writer.Write([]byte("foobar")) if err != nil { t.Fatal(err) } if written != 6 { t.Fatalf("Should have written 6 bytes, but wrote %v bytes", written) } writer.Close() if !sw.closed { t.Fatalf("The ReaderCloser should have been closed, it is not.") } } func TestBufferPoolPutAndGet(t *testing.T) { buf := buffer32KPool.Get() buffer32KPool.Put(buf) }