...

Source file src/io/io_test.go

Documentation: io

		 1  // Copyright 2009 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package io_test
		 6  
		 7  import (
		 8  	"bytes"
		 9  	"errors"
		10  	"fmt"
		11  	. "io"
		12  	"strings"
		13  	"testing"
		14  )
		15  
		16  // A version of bytes.Buffer without ReadFrom and WriteTo
		17  type Buffer struct {
		18  	bytes.Buffer
		19  	ReaderFrom // conflicts with and hides bytes.Buffer's ReaderFrom.
		20  	WriterTo	 // conflicts with and hides bytes.Buffer's WriterTo.
		21  }
		22  
		23  // Simple tests, primarily to verify the ReadFrom and WriteTo callouts inside Copy, CopyBuffer and CopyN.
		24  
		25  func TestCopy(t *testing.T) {
		26  	rb := new(Buffer)
		27  	wb := new(Buffer)
		28  	rb.WriteString("hello, world.")
		29  	Copy(wb, rb)
		30  	if wb.String() != "hello, world." {
		31  		t.Errorf("Copy did not work properly")
		32  	}
		33  }
		34  
		35  func TestCopyNegative(t *testing.T) {
		36  	rb := new(Buffer)
		37  	wb := new(Buffer)
		38  	rb.WriteString("hello")
		39  	Copy(wb, &LimitedReader{R: rb, N: -1})
		40  	if wb.String() != "" {
		41  		t.Errorf("Copy on LimitedReader with N<0 copied data")
		42  	}
		43  
		44  	CopyN(wb, rb, -1)
		45  	if wb.String() != "" {
		46  		t.Errorf("CopyN with N<0 copied data")
		47  	}
		48  }
		49  
		50  func TestCopyBuffer(t *testing.T) {
		51  	rb := new(Buffer)
		52  	wb := new(Buffer)
		53  	rb.WriteString("hello, world.")
		54  	CopyBuffer(wb, rb, make([]byte, 1)) // Tiny buffer to keep it honest.
		55  	if wb.String() != "hello, world." {
		56  		t.Errorf("CopyBuffer did not work properly")
		57  	}
		58  }
		59  
		60  func TestCopyBufferNil(t *testing.T) {
		61  	rb := new(Buffer)
		62  	wb := new(Buffer)
		63  	rb.WriteString("hello, world.")
		64  	CopyBuffer(wb, rb, nil) // Should allocate a buffer.
		65  	if wb.String() != "hello, world." {
		66  		t.Errorf("CopyBuffer did not work properly")
		67  	}
		68  }
		69  
		70  func TestCopyReadFrom(t *testing.T) {
		71  	rb := new(Buffer)
		72  	wb := new(bytes.Buffer) // implements ReadFrom.
		73  	rb.WriteString("hello, world.")
		74  	Copy(wb, rb)
		75  	if wb.String() != "hello, world." {
		76  		t.Errorf("Copy did not work properly")
		77  	}
		78  }
		79  
		80  func TestCopyWriteTo(t *testing.T) {
		81  	rb := new(bytes.Buffer) // implements WriteTo.
		82  	wb := new(Buffer)
		83  	rb.WriteString("hello, world.")
		84  	Copy(wb, rb)
		85  	if wb.String() != "hello, world." {
		86  		t.Errorf("Copy did not work properly")
		87  	}
		88  }
		89  
		90  // Version of bytes.Buffer that checks whether WriteTo was called or not
		91  type writeToChecker struct {
		92  	bytes.Buffer
		93  	writeToCalled bool
		94  }
		95  
		96  func (wt *writeToChecker) WriteTo(w Writer) (int64, error) {
		97  	wt.writeToCalled = true
		98  	return wt.Buffer.WriteTo(w)
		99  }
	 100  
	 101  // It's preferable to choose WriterTo over ReaderFrom, since a WriterTo can issue one large write,
	 102  // while the ReaderFrom must read until EOF, potentially allocating when running out of buffer.
	 103  // Make sure that we choose WriterTo when both are implemented.
	 104  func TestCopyPriority(t *testing.T) {
	 105  	rb := new(writeToChecker)
	 106  	wb := new(bytes.Buffer)
	 107  	rb.WriteString("hello, world.")
	 108  	Copy(wb, rb)
	 109  	if wb.String() != "hello, world." {
	 110  		t.Errorf("Copy did not work properly")
	 111  	} else if !rb.writeToCalled {
	 112  		t.Errorf("WriteTo was not prioritized over ReadFrom")
	 113  	}
	 114  }
	 115  
	 116  type zeroErrReader struct {
	 117  	err error
	 118  }
	 119  
	 120  func (r zeroErrReader) Read(p []byte) (int, error) {
	 121  	return copy(p, []byte{0}), r.err
	 122  }
	 123  
	 124  type errWriter struct {
	 125  	err error
	 126  }
	 127  
	 128  func (w errWriter) Write([]byte) (int, error) {
	 129  	return 0, w.err
	 130  }
	 131  
	 132  // In case a Read results in an error with non-zero bytes read, and
	 133  // the subsequent Write also results in an error, the error from Write
	 134  // is returned, as it is the one that prevented progressing further.
	 135  func TestCopyReadErrWriteErr(t *testing.T) {
	 136  	er, ew := errors.New("readError"), errors.New("writeError")
	 137  	r, w := zeroErrReader{err: er}, errWriter{err: ew}
	 138  	n, err := Copy(w, r)
	 139  	if n != 0 || err != ew {
	 140  		t.Errorf("Copy(zeroErrReader, errWriter) = %d, %v; want 0, writeError", n, err)
	 141  	}
	 142  }
	 143  
	 144  func TestCopyN(t *testing.T) {
	 145  	rb := new(Buffer)
	 146  	wb := new(Buffer)
	 147  	rb.WriteString("hello, world.")
	 148  	CopyN(wb, rb, 5)
	 149  	if wb.String() != "hello" {
	 150  		t.Errorf("CopyN did not work properly")
	 151  	}
	 152  }
	 153  
	 154  func TestCopyNReadFrom(t *testing.T) {
	 155  	rb := new(Buffer)
	 156  	wb := new(bytes.Buffer) // implements ReadFrom.
	 157  	rb.WriteString("hello")
	 158  	CopyN(wb, rb, 5)
	 159  	if wb.String() != "hello" {
	 160  		t.Errorf("CopyN did not work properly")
	 161  	}
	 162  }
	 163  
	 164  func TestCopyNWriteTo(t *testing.T) {
	 165  	rb := new(bytes.Buffer) // implements WriteTo.
	 166  	wb := new(Buffer)
	 167  	rb.WriteString("hello, world.")
	 168  	CopyN(wb, rb, 5)
	 169  	if wb.String() != "hello" {
	 170  		t.Errorf("CopyN did not work properly")
	 171  	}
	 172  }
	 173  
	 174  func BenchmarkCopyNSmall(b *testing.B) {
	 175  	bs := bytes.Repeat([]byte{0}, 512+1)
	 176  	rd := bytes.NewReader(bs)
	 177  	buf := new(Buffer)
	 178  	b.ResetTimer()
	 179  
	 180  	for i := 0; i < b.N; i++ {
	 181  		CopyN(buf, rd, 512)
	 182  		rd.Reset(bs)
	 183  	}
	 184  }
	 185  
	 186  func BenchmarkCopyNLarge(b *testing.B) {
	 187  	bs := bytes.Repeat([]byte{0}, (32*1024)+1)
	 188  	rd := bytes.NewReader(bs)
	 189  	buf := new(Buffer)
	 190  	b.ResetTimer()
	 191  
	 192  	for i := 0; i < b.N; i++ {
	 193  		CopyN(buf, rd, 32*1024)
	 194  		rd.Reset(bs)
	 195  	}
	 196  }
	 197  
	 198  type noReadFrom struct {
	 199  	w Writer
	 200  }
	 201  
	 202  func (w *noReadFrom) Write(p []byte) (n int, err error) {
	 203  	return w.w.Write(p)
	 204  }
	 205  
	 206  type wantedAndErrReader struct{}
	 207  
	 208  func (wantedAndErrReader) Read(p []byte) (int, error) {
	 209  	return len(p), errors.New("wantedAndErrReader error")
	 210  }
	 211  
	 212  func TestCopyNEOF(t *testing.T) {
	 213  	// Test that EOF behavior is the same regardless of whether
	 214  	// argument to CopyN has ReadFrom.
	 215  
	 216  	b := new(bytes.Buffer)
	 217  
	 218  	n, err := CopyN(&noReadFrom{b}, strings.NewReader("foo"), 3)
	 219  	if n != 3 || err != nil {
	 220  		t.Errorf("CopyN(noReadFrom, foo, 3) = %d, %v; want 3, nil", n, err)
	 221  	}
	 222  
	 223  	n, err = CopyN(&noReadFrom{b}, strings.NewReader("foo"), 4)
	 224  	if n != 3 || err != EOF {
	 225  		t.Errorf("CopyN(noReadFrom, foo, 4) = %d, %v; want 3, EOF", n, err)
	 226  	}
	 227  
	 228  	n, err = CopyN(b, strings.NewReader("foo"), 3) // b has read from
	 229  	if n != 3 || err != nil {
	 230  		t.Errorf("CopyN(bytes.Buffer, foo, 3) = %d, %v; want 3, nil", n, err)
	 231  	}
	 232  
	 233  	n, err = CopyN(b, strings.NewReader("foo"), 4) // b has read from
	 234  	if n != 3 || err != EOF {
	 235  		t.Errorf("CopyN(bytes.Buffer, foo, 4) = %d, %v; want 3, EOF", n, err)
	 236  	}
	 237  
	 238  	n, err = CopyN(b, wantedAndErrReader{}, 5)
	 239  	if n != 5 || err != nil {
	 240  		t.Errorf("CopyN(bytes.Buffer, wantedAndErrReader, 5) = %d, %v; want 5, nil", n, err)
	 241  	}
	 242  
	 243  	n, err = CopyN(&noReadFrom{b}, wantedAndErrReader{}, 5)
	 244  	if n != 5 || err != nil {
	 245  		t.Errorf("CopyN(noReadFrom, wantedAndErrReader, 5) = %d, %v; want 5, nil", n, err)
	 246  	}
	 247  }
	 248  
	 249  func TestReadAtLeast(t *testing.T) {
	 250  	var rb bytes.Buffer
	 251  	testReadAtLeast(t, &rb)
	 252  }
	 253  
	 254  // A version of bytes.Buffer that returns n > 0, err on Read
	 255  // when the input is exhausted.
	 256  type dataAndErrorBuffer struct {
	 257  	err error
	 258  	bytes.Buffer
	 259  }
	 260  
	 261  func (r *dataAndErrorBuffer) Read(p []byte) (n int, err error) {
	 262  	n, err = r.Buffer.Read(p)
	 263  	if n > 0 && r.Buffer.Len() == 0 && err == nil {
	 264  		err = r.err
	 265  	}
	 266  	return
	 267  }
	 268  
	 269  func TestReadAtLeastWithDataAndEOF(t *testing.T) {
	 270  	var rb dataAndErrorBuffer
	 271  	rb.err = EOF
	 272  	testReadAtLeast(t, &rb)
	 273  }
	 274  
	 275  func TestReadAtLeastWithDataAndError(t *testing.T) {
	 276  	var rb dataAndErrorBuffer
	 277  	rb.err = fmt.Errorf("fake error")
	 278  	testReadAtLeast(t, &rb)
	 279  }
	 280  
	 281  func testReadAtLeast(t *testing.T, rb ReadWriter) {
	 282  	rb.Write([]byte("0123"))
	 283  	buf := make([]byte, 2)
	 284  	n, err := ReadAtLeast(rb, buf, 2)
	 285  	if err != nil {
	 286  		t.Error(err)
	 287  	}
	 288  	if n != 2 {
	 289  		t.Errorf("expected to have read 2 bytes, got %v", n)
	 290  	}
	 291  	n, err = ReadAtLeast(rb, buf, 4)
	 292  	if err != ErrShortBuffer {
	 293  		t.Errorf("expected ErrShortBuffer got %v", err)
	 294  	}
	 295  	if n != 0 {
	 296  		t.Errorf("expected to have read 0 bytes, got %v", n)
	 297  	}
	 298  	n, err = ReadAtLeast(rb, buf, 1)
	 299  	if err != nil {
	 300  		t.Error(err)
	 301  	}
	 302  	if n != 2 {
	 303  		t.Errorf("expected to have read 2 bytes, got %v", n)
	 304  	}
	 305  	n, err = ReadAtLeast(rb, buf, 2)
	 306  	if err != EOF {
	 307  		t.Errorf("expected EOF, got %v", err)
	 308  	}
	 309  	if n != 0 {
	 310  		t.Errorf("expected to have read 0 bytes, got %v", n)
	 311  	}
	 312  	rb.Write([]byte("4"))
	 313  	n, err = ReadAtLeast(rb, buf, 2)
	 314  	want := ErrUnexpectedEOF
	 315  	if rb, ok := rb.(*dataAndErrorBuffer); ok && rb.err != EOF {
	 316  		want = rb.err
	 317  	}
	 318  	if err != want {
	 319  		t.Errorf("expected %v, got %v", want, err)
	 320  	}
	 321  	if n != 1 {
	 322  		t.Errorf("expected to have read 1 bytes, got %v", n)
	 323  	}
	 324  }
	 325  
	 326  func TestTeeReader(t *testing.T) {
	 327  	src := []byte("hello, world")
	 328  	dst := make([]byte, len(src))
	 329  	rb := bytes.NewBuffer(src)
	 330  	wb := new(bytes.Buffer)
	 331  	r := TeeReader(rb, wb)
	 332  	if n, err := ReadFull(r, dst); err != nil || n != len(src) {
	 333  		t.Fatalf("ReadFull(r, dst) = %d, %v; want %d, nil", n, err, len(src))
	 334  	}
	 335  	if !bytes.Equal(dst, src) {
	 336  		t.Errorf("bytes read = %q want %q", dst, src)
	 337  	}
	 338  	if !bytes.Equal(wb.Bytes(), src) {
	 339  		t.Errorf("bytes written = %q want %q", wb.Bytes(), src)
	 340  	}
	 341  	if n, err := r.Read(dst); n != 0 || err != EOF {
	 342  		t.Errorf("r.Read at EOF = %d, %v want 0, EOF", n, err)
	 343  	}
	 344  	rb = bytes.NewBuffer(src)
	 345  	pr, pw := Pipe()
	 346  	pr.Close()
	 347  	r = TeeReader(rb, pw)
	 348  	if n, err := ReadFull(r, dst); n != 0 || err != ErrClosedPipe {
	 349  		t.Errorf("closed tee: ReadFull(r, dst) = %d, %v; want 0, EPIPE", n, err)
	 350  	}
	 351  }
	 352  
	 353  func TestSectionReader_ReadAt(t *testing.T) {
	 354  	dat := "a long sample data, 1234567890"
	 355  	tests := []struct {
	 356  		data	 string
	 357  		off		int
	 358  		n			int
	 359  		bufLen int
	 360  		at		 int
	 361  		exp		string
	 362  		err		error
	 363  	}{
	 364  		{data: "", off: 0, n: 10, bufLen: 2, at: 0, exp: "", err: EOF},
	 365  		{data: dat, off: 0, n: len(dat), bufLen: 0, at: 0, exp: "", err: nil},
	 366  		{data: dat, off: len(dat), n: 1, bufLen: 1, at: 0, exp: "", err: EOF},
	 367  		{data: dat, off: 0, n: len(dat) + 2, bufLen: len(dat), at: 0, exp: dat, err: nil},
	 368  		{data: dat, off: 0, n: len(dat), bufLen: len(dat) / 2, at: 0, exp: dat[:len(dat)/2], err: nil},
	 369  		{data: dat, off: 0, n: len(dat), bufLen: len(dat), at: 0, exp: dat, err: nil},
	 370  		{data: dat, off: 0, n: len(dat), bufLen: len(dat) / 2, at: 2, exp: dat[2 : 2+len(dat)/2], err: nil},
	 371  		{data: dat, off: 3, n: len(dat), bufLen: len(dat) / 2, at: 2, exp: dat[5 : 5+len(dat)/2], err: nil},
	 372  		{data: dat, off: 3, n: len(dat) / 2, bufLen: len(dat)/2 - 2, at: 2, exp: dat[5 : 5+len(dat)/2-2], err: nil},
	 373  		{data: dat, off: 3, n: len(dat) / 2, bufLen: len(dat)/2 + 2, at: 2, exp: dat[5 : 5+len(dat)/2-2], err: EOF},
	 374  		{data: dat, off: 0, n: 0, bufLen: 0, at: -1, exp: "", err: EOF},
	 375  		{data: dat, off: 0, n: 0, bufLen: 0, at: 1, exp: "", err: EOF},
	 376  	}
	 377  	for i, tt := range tests {
	 378  		r := strings.NewReader(tt.data)
	 379  		s := NewSectionReader(r, int64(tt.off), int64(tt.n))
	 380  		buf := make([]byte, tt.bufLen)
	 381  		if n, err := s.ReadAt(buf, int64(tt.at)); n != len(tt.exp) || string(buf[:n]) != tt.exp || err != tt.err {
	 382  			t.Fatalf("%d: ReadAt(%d) = %q, %v; expected %q, %v", i, tt.at, buf[:n], err, tt.exp, tt.err)
	 383  		}
	 384  	}
	 385  }
	 386  
	 387  func TestSectionReader_Seek(t *testing.T) {
	 388  	// Verifies that NewSectionReader's Seeker behaves like bytes.NewReader (which is like strings.NewReader)
	 389  	br := bytes.NewReader([]byte("foo"))
	 390  	sr := NewSectionReader(br, 0, int64(len("foo")))
	 391  
	 392  	for _, whence := range []int{SeekStart, SeekCurrent, SeekEnd} {
	 393  		for offset := int64(-3); offset <= 4; offset++ {
	 394  			brOff, brErr := br.Seek(offset, whence)
	 395  			srOff, srErr := sr.Seek(offset, whence)
	 396  			if (brErr != nil) != (srErr != nil) || brOff != srOff {
	 397  				t.Errorf("For whence %d, offset %d: bytes.Reader.Seek = (%v, %v) != SectionReader.Seek = (%v, %v)",
	 398  					whence, offset, brOff, brErr, srErr, srOff)
	 399  			}
	 400  		}
	 401  	}
	 402  
	 403  	// And verify we can just seek past the end and get an EOF
	 404  	got, err := sr.Seek(100, SeekStart)
	 405  	if err != nil || got != 100 {
	 406  		t.Errorf("Seek = %v, %v; want 100, nil", got, err)
	 407  	}
	 408  
	 409  	n, err := sr.Read(make([]byte, 10))
	 410  	if n != 0 || err != EOF {
	 411  		t.Errorf("Read = %v, %v; want 0, EOF", n, err)
	 412  	}
	 413  }
	 414  
	 415  func TestSectionReader_Size(t *testing.T) {
	 416  	tests := []struct {
	 417  		data string
	 418  		want int64
	 419  	}{
	 420  		{"a long sample data, 1234567890", 30},
	 421  		{"", 0},
	 422  	}
	 423  
	 424  	for _, tt := range tests {
	 425  		r := strings.NewReader(tt.data)
	 426  		sr := NewSectionReader(r, 0, int64(len(tt.data)))
	 427  		if got := sr.Size(); got != tt.want {
	 428  			t.Errorf("Size = %v; want %v", got, tt.want)
	 429  		}
	 430  	}
	 431  }
	 432  
	 433  // largeWriter returns an invalid count that is larger than the number
	 434  // of bytes provided (issue 39978).
	 435  type largeWriter struct {
	 436  	err error
	 437  }
	 438  
	 439  func (w largeWriter) Write(p []byte) (int, error) {
	 440  	return len(p) + 1, w.err
	 441  }
	 442  
	 443  func TestCopyLargeWriter(t *testing.T) {
	 444  	want := ErrInvalidWrite
	 445  	rb := new(Buffer)
	 446  	wb := largeWriter{}
	 447  	rb.WriteString("hello, world.")
	 448  	if _, err := Copy(wb, rb); err != want {
	 449  		t.Errorf("Copy error: got %v, want %v", err, want)
	 450  	}
	 451  
	 452  	want = errors.New("largeWriterError")
	 453  	rb = new(Buffer)
	 454  	wb = largeWriter{err: want}
	 455  	rb.WriteString("hello, world.")
	 456  	if _, err := Copy(wb, rb); err != want {
	 457  		t.Errorf("Copy error: got %v, want %v", err, want)
	 458  	}
	 459  }
	 460  

View as plain text