diff options
Diffstat (limited to 'src/pkg/bytes/reader_test.go')
-rw-r--r-- | src/pkg/bytes/reader_test.go | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/src/pkg/bytes/reader_test.go b/src/pkg/bytes/reader_test.go index 19f014da0..d3dce5349 100644 --- a/src/pkg/bytes/reader_test.go +++ b/src/pkg/bytes/reader_test.go @@ -10,6 +10,7 @@ import ( "io" "io/ioutil" "os" + "sync" "testing" ) @@ -26,9 +27,9 @@ func TestReader(t *testing.T) { {seek: os.SEEK_SET, off: 0, n: 20, want: "0123456789"}, {seek: os.SEEK_SET, off: 1, n: 1, want: "1"}, {seek: os.SEEK_CUR, off: 1, wantpos: 3, n: 2, want: "34"}, - {seek: os.SEEK_SET, off: -1, seekerr: "bytes: negative position"}, - {seek: os.SEEK_SET, off: 1<<31 - 1}, - {seek: os.SEEK_CUR, off: 1, seekerr: "bytes: position out of range"}, + {seek: os.SEEK_SET, off: -1, seekerr: "bytes.Reader.Seek: negative position"}, + {seek: os.SEEK_SET, off: 1 << 33, wantpos: 1 << 33}, + {seek: os.SEEK_CUR, off: 1, wantpos: 1<<33 + 1}, {seek: os.SEEK_SET, n: 5, want: "01234"}, {seek: os.SEEK_CUR, n: 5, want: "56789"}, {seek: os.SEEK_END, off: -1, n: 1, wantpos: 9, want: "9"}, @@ -60,6 +61,16 @@ func TestReader(t *testing.T) { } } +func TestReadAfterBigSeek(t *testing.T) { + r := NewReader([]byte("0123456789")) + if _, err := r.Seek(1<<31+5, os.SEEK_SET); err != nil { + t.Fatal(err) + } + if n, err := r.Read(make([]byte, 10)); n != 0 || err != io.EOF { + t.Errorf("Read = %d, %v; want 0, EOF", n, err) + } +} + func TestReaderAt(t *testing.T) { r := NewReader([]byte("0123456789")) tests := []struct { @@ -73,7 +84,7 @@ func TestReaderAt(t *testing.T) { {1, 9, "123456789", nil}, {11, 10, "", io.EOF}, {0, 0, "", nil}, - {-1, 0, "", "bytes: invalid offset"}, + {-1, 0, "", "bytes.Reader.ReadAt: negative offset"}, } for i, tt := range tests { b := make([]byte, tt.n) @@ -88,6 +99,43 @@ func TestReaderAt(t *testing.T) { } } +func TestReaderAtConcurrent(t *testing.T) { + // Test for the race detector, to verify ReadAt doesn't mutate + // any state. + r := NewReader([]byte("0123456789")) + var wg sync.WaitGroup + for i := 0; i < 5; i++ { + wg.Add(1) + go func(i int) { + defer wg.Done() + var buf [1]byte + r.ReadAt(buf[:], int64(i)) + }(i) + } + wg.Wait() +} + +func TestEmptyReaderConcurrent(t *testing.T) { + // Test for the race detector, to verify a Read that doesn't yield any bytes + // is okay to use from multiple goroutines. This was our historic behavior. + // See golang.org/issue/7856 + r := NewReader([]byte{}) + var wg sync.WaitGroup + for i := 0; i < 5; i++ { + wg.Add(2) + go func() { + defer wg.Done() + var buf [1]byte + r.Read(buf[:]) + }() + go func() { + defer wg.Done() + r.Read(nil) + }() + } + wg.Wait() +} + func TestReaderWriteTo(t *testing.T) { for i := 0; i < 30; i += 3 { var l int @@ -133,6 +181,32 @@ func TestReaderLen(t *testing.T) { } } +var UnreadRuneErrorTests = []struct { + name string + f func(*Reader) +}{ + {"Read", func(r *Reader) { r.Read([]byte{0}) }}, + {"ReadByte", func(r *Reader) { r.ReadByte() }}, + {"UnreadRune", func(r *Reader) { r.UnreadRune() }}, + {"Seek", func(r *Reader) { r.Seek(0, 1) }}, + {"WriteTo", func(r *Reader) { r.WriteTo(&Buffer{}) }}, +} + +func TestUnreadRuneError(t *testing.T) { + for _, tt := range UnreadRuneErrorTests { + reader := NewReader([]byte("0123456789")) + if _, _, err := reader.ReadRune(); err != nil { + // should not happen + t.Fatal(err) + } + tt.f(reader) + err := reader.UnreadRune() + if err == nil { + t.Errorf("Unreading after %s: expected error", tt.name) + } + } +} + func TestReaderDoubleUnreadRune(t *testing.T) { buf := NewBuffer([]byte("groucho")) if _, _, err := buf.ReadRune(); err != nil { |