diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-21 07:03:38 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-21 07:03:38 +0000 |
commit | 79a796b7d3db5d100eedfc774954a6b44944363a (patch) | |
tree | 72455aea0286937aa08cc141e5efc800e4626577 /libgo/go/bufio/bufio_test.go | |
parent | 7224cf54b3af2b931fb83af65f9cfab5c1df814a (diff) | |
download | gcc-79a796b7d3db5d100eedfc774954a6b44944363a.tar.gz |
libgo: Update to current version of master library.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193688 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/bufio/bufio_test.go')
-rw-r--r-- | libgo/go/bufio/bufio_test.go | 173 |
1 files changed, 163 insertions, 10 deletions
diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go index 4e10207efbd..75d9edf8b1c 100644 --- a/libgo/go/bufio/bufio_test.go +++ b/libgo/go/bufio/bufio_test.go @@ -763,8 +763,8 @@ func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) { } } -func TestReaderWriteTo(t *testing.T) { - input := make([]byte, 8192) +func createTestInput(n int) []byte { + input := make([]byte, n) for i := range input { // 101 and 251 are arbitrary prime numbers. // The idea is to create an input sequence @@ -774,7 +774,12 @@ func TestReaderWriteTo(t *testing.T) { input[i] ^= byte(i / 101) } } - r := NewReader(bytes.NewBuffer(input)) + return input +} + +func TestReaderWriteTo(t *testing.T) { + input := createTestInput(8192) + r := NewReader(onlyReader{bytes.NewBuffer(input)}) w := new(bytes.Buffer) if n, err := r.WriteTo(w); err != nil || n != int64(len(input)) { t.Fatalf("r.WriteTo(w) = %d, %v, want %d, nil", n, err, len(input)) @@ -817,12 +822,129 @@ func TestReaderWriteToErrors(t *testing.T) { } } +func TestWriterReadFrom(t *testing.T) { + ws := []func(io.Writer) io.Writer{ + func(w io.Writer) io.Writer { return onlyWriter{w} }, + func(w io.Writer) io.Writer { return w }, + } + + rs := []func(io.Reader) io.Reader{ + iotest.DataErrReader, + func(r io.Reader) io.Reader { return r }, + } + + for ri, rfunc := range rs { + for wi, wfunc := range ws { + input := createTestInput(8192) + b := new(bytes.Buffer) + w := NewWriter(wfunc(b)) + r := rfunc(bytes.NewBuffer(input)) + if n, err := w.ReadFrom(r); err != nil || n != int64(len(input)) { + t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input)) + continue + } + if got, want := b.String(), string(input); got != want { + t.Errorf("ws[%d], rs[%d]:\ngot %q\nwant %q\n", wi, ri, got, want) + } + } + } +} + +type errorReaderFromTest struct { + rn, wn int + rerr, werr error + expected error +} + +func (r errorReaderFromTest) Read(p []byte) (int, error) { + return len(p) * r.rn, r.rerr +} + +func (w errorReaderFromTest) Write(p []byte) (int, error) { + return len(p) * w.wn, w.werr +} + +var errorReaderFromTests = []errorReaderFromTest{ + {0, 1, io.EOF, nil, nil}, + {1, 1, io.EOF, nil, nil}, + {0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe}, + {0, 0, io.ErrClosedPipe, io.ErrShortWrite, io.ErrClosedPipe}, + {1, 0, nil, io.ErrShortWrite, io.ErrShortWrite}, +} + +func TestWriterReadFromErrors(t *testing.T) { + for i, rw := range errorReaderFromTests { + w := NewWriter(rw) + if _, err := w.ReadFrom(rw); err != rw.expected { + t.Errorf("w.ReadFrom(errorReaderFromTests[%d]) = _, %v, want _,%v", i, err, rw.expected) + } + } +} + +// TestWriterReadFromCounts tests that using io.Copy to copy into a +// bufio.Writer does not prematurely flush the buffer. For example, when +// buffering writes to a network socket, excessive network writes should be +// avoided. +func TestWriterReadFromCounts(t *testing.T) { + var w0 writeCountingDiscard + b0 := NewWriterSize(&w0, 1234) + b0.WriteString(strings.Repeat("x", 1000)) + if w0 != 0 { + t.Fatalf("write 1000 'x's: got %d writes, want 0", w0) + } + b0.WriteString(strings.Repeat("x", 200)) + if w0 != 0 { + t.Fatalf("write 1200 'x's: got %d writes, want 0", w0) + } + io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 30))}) + if w0 != 0 { + t.Fatalf("write 1230 'x's: got %d writes, want 0", w0) + } + io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 9))}) + if w0 != 1 { + t.Fatalf("write 1239 'x's: got %d writes, want 1", w0) + } + + var w1 writeCountingDiscard + b1 := NewWriterSize(&w1, 1234) + b1.WriteString(strings.Repeat("x", 1200)) + b1.Flush() + if w1 != 1 { + t.Fatalf("flush 1200 'x's: got %d writes, want 1", w1) + } + b1.WriteString(strings.Repeat("x", 89)) + if w1 != 1 { + t.Fatalf("write 1200 + 89 'x's: got %d writes, want 1", w1) + } + io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 700))}) + if w1 != 1 { + t.Fatalf("write 1200 + 789 'x's: got %d writes, want 1", w1) + } + io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 600))}) + if w1 != 2 { + t.Fatalf("write 1200 + 1389 'x's: got %d writes, want 2", w1) + } + b1.Flush() + if w1 != 3 { + t.Fatalf("flush 1200 + 1389 'x's: got %d writes, want 3", w1) + } +} + +// A writeCountingDiscard is like ioutil.Discard and counts the number of times +// Write is called on it. +type writeCountingDiscard int + +func (w *writeCountingDiscard) Write(p []byte) (int, error) { + *w++ + return len(p), nil +} + // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have. type onlyReader struct { r io.Reader } -func (r *onlyReader) Read(b []byte) (int, error) { +func (r onlyReader) Read(b []byte) (int, error) { return r.r.Read(b) } @@ -831,7 +953,7 @@ type onlyWriter struct { w io.Writer } -func (w *onlyWriter) Write(b []byte) (int, error) { +func (w onlyWriter) Write(b []byte) (int, error) { return w.w.Write(b) } @@ -840,7 +962,7 @@ func BenchmarkReaderCopyOptimal(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() src := NewReader(bytes.NewBuffer(make([]byte, 8192))) - dst := &onlyWriter{new(bytes.Buffer)} + dst := onlyWriter{new(bytes.Buffer)} b.StartTimer() io.Copy(dst, src) } @@ -850,8 +972,8 @@ func BenchmarkReaderCopyUnoptimal(b *testing.B) { // Unoptimal case is where the underlying reader doesn't implement io.WriterTo for i := 0; i < b.N; i++ { b.StopTimer() - src := NewReader(&onlyReader{bytes.NewBuffer(make([]byte, 8192))}) - dst := &onlyWriter{new(bytes.Buffer)} + src := NewReader(onlyReader{bytes.NewBuffer(make([]byte, 8192))}) + dst := onlyWriter{new(bytes.Buffer)} b.StartTimer() io.Copy(dst, src) } @@ -860,8 +982,39 @@ func BenchmarkReaderCopyUnoptimal(b *testing.B) { func BenchmarkReaderCopyNoWriteTo(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() - src := &onlyReader{NewReader(bytes.NewBuffer(make([]byte, 8192)))} - dst := &onlyWriter{new(bytes.Buffer)} + src := onlyReader{NewReader(bytes.NewBuffer(make([]byte, 8192)))} + dst := onlyWriter{new(bytes.Buffer)} + b.StartTimer() + io.Copy(dst, src) + } +} + +func BenchmarkWriterCopyOptimal(b *testing.B) { + // Optimal case is where the underlying writer implements io.ReaderFrom + for i := 0; i < b.N; i++ { + b.StopTimer() + src := onlyReader{bytes.NewBuffer(make([]byte, 8192))} + dst := NewWriter(new(bytes.Buffer)) + b.StartTimer() + io.Copy(dst, src) + } +} + +func BenchmarkWriterCopyUnoptimal(b *testing.B) { + for i := 0; i < b.N; i++ { + b.StopTimer() + src := onlyReader{bytes.NewBuffer(make([]byte, 8192))} + dst := NewWriter(onlyWriter{new(bytes.Buffer)}) + b.StartTimer() + io.Copy(dst, src) + } +} + +func BenchmarkWriterCopyNoReadFrom(b *testing.B) { + for i := 0; i < b.N; i++ { + b.StopTimer() + src := onlyReader{bytes.NewBuffer(make([]byte, 8192))} + dst := onlyWriter{NewWriter(new(bytes.Buffer))} b.StartTimer() io.Copy(dst, src) } |