From abfeec5eb0356d1ac91a097d2124a6b7c8cfccd4 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 16 Aug 2020 21:58:40 +0000 Subject: testing/iotest: add ErrReader Adds an io.Reader that always returns 0 and a non-nil error. Fixes #38781 Change-Id: I56bd124de07bc8809e77c6cfaab33a1e32cfe2ee GitHub-Last-Rev: 4e232b17e9120405d4ea4743350ee361a3505043 GitHub-Pull-Request: golang/go#34741 Reviewed-on: https://go-review.googlesource.com/c/go/+/199501 Run-TryBot: Emmanuel Odeke TryBot-Result: Gobot Gobot Reviewed-by: Emmanuel Odeke --- src/testing/iotest/reader.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/testing/iotest/reader.go') diff --git a/src/testing/iotest/reader.go b/src/testing/iotest/reader.go index 8d82018fd6..b18e912f27 100644 --- a/src/testing/iotest/reader.go +++ b/src/testing/iotest/reader.go @@ -68,6 +68,7 @@ func (r *dataErrReader) Read(p []byte) (n int, err error) { return } +// ErrTimeout is a fake timeout error. var ErrTimeout = errors.New("timeout") // TimeoutReader returns ErrTimeout on the second read @@ -86,3 +87,17 @@ func (r *timeoutReader) Read(p []byte) (int, error) { } return r.r.Read(p) } + +// ErrIO is a fake IO error. +var ErrIO = errors.New("io") + +// ErrReader returns a fake error every time it is read from. +func ErrReader() io.Reader { + return errReader(0) +} + +type errReader int + +func (r errReader) Read(p []byte) (int, error) { + return 0, ErrIO +} -- cgit v1.3-5-g9baa From db4cda2ec0955854c8ff556ac19ec5e67d48d090 Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Mon, 17 Aug 2020 12:25:49 -0700 Subject: testing/iotest: correct ErrReader signature and remove exported error Corrects ErrReader's signature to what was accepted in the approved proposal, and also removes an exported ErrIO which wasn't part of the proposal and is unnecessary. The new signature allows users to customize their own errors. While here, started examples, with ErrReader leading the way. Updates #38781 Change-Id: Ia7f84721f11061343cfef8b1adc2b7b69bc3f43c Reviewed-on: https://go-review.googlesource.com/c/go/+/248898 Run-TryBot: Emmanuel Odeke Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/testing/iotest/example_test.go | 22 ++++++++++++++++++++++ src/testing/iotest/logger_test.go | 4 ++-- src/testing/iotest/reader.go | 17 ++++++++--------- src/testing/iotest/reader_test.go | 27 +++++++++++++++++++++------ 4 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 src/testing/iotest/example_test.go (limited to 'src/testing/iotest/reader.go') diff --git a/src/testing/iotest/example_test.go b/src/testing/iotest/example_test.go new file mode 100644 index 0000000000..10f6bd38f7 --- /dev/null +++ b/src/testing/iotest/example_test.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iotest_test + +import ( + "errors" + "fmt" + "testing/iotest" +) + +func ExampleErrReader() { + // A reader that always returns a custom error. + r := iotest.ErrReader(errors.New("custom error")) + n, err := r.Read(nil) + fmt.Printf("n: %d\nerr: %q\n", n, err) + + // Output: + // n: 0 + // err: "custom error" +} diff --git a/src/testing/iotest/logger_test.go b/src/testing/iotest/logger_test.go index 575f37e05c..fec4467cc6 100644 --- a/src/testing/iotest/logger_test.go +++ b/src/testing/iotest/logger_test.go @@ -138,14 +138,14 @@ func TestReadLogger_errorOnRead(t *testing.T) { data := []byte("Hello, World!") p := make([]byte, len(data)) - lr := ErrReader() + lr := ErrReader(errors.New("io failure")) rl := NewReadLogger("read", lr) n, err := rl.Read(p) if err == nil { t.Fatalf("Unexpectedly succeeded to read: %v", err) } - wantLogWithHex := fmt.Sprintf("lr: read %x: %v\n", p[:n], "io") + wantLogWithHex := fmt.Sprintf("lr: read %x: io failure\n", p[:n]) if g, w := lOut.String(), wantLogWithHex; g != w { t.Errorf("ReadLogger mismatch\n\tgot: %q\n\twant: %q", g, w) } diff --git a/src/testing/iotest/reader.go b/src/testing/iotest/reader.go index b18e912f27..bc2f72a911 100644 --- a/src/testing/iotest/reader.go +++ b/src/testing/iotest/reader.go @@ -88,16 +88,15 @@ func (r *timeoutReader) Read(p []byte) (int, error) { return r.r.Read(p) } -// ErrIO is a fake IO error. -var ErrIO = errors.New("io") - -// ErrReader returns a fake error every time it is read from. -func ErrReader() io.Reader { - return errReader(0) +// ErrReader returns an io.Reader that returns 0, err from all Read calls. +func ErrReader(err error) io.Reader { + return &alwaysErrReader{err: err} } -type errReader int +type alwaysErrReader struct { + err error +} -func (r errReader) Read(p []byte) (int, error) { - return 0, ErrIO +func (aer *alwaysErrReader) Read(p []byte) (int, error) { + return 0, aer.err } diff --git a/src/testing/iotest/reader_test.go b/src/testing/iotest/reader_test.go index ccba22ee29..6004e841e5 100644 --- a/src/testing/iotest/reader_test.go +++ b/src/testing/iotest/reader_test.go @@ -6,6 +6,7 @@ package iotest import ( "bytes" + "errors" "io" "testing" ) @@ -226,11 +227,25 @@ func TestDataErrReader_emptyReader(t *testing.T) { } func TestErrReader(t *testing.T) { - n, err := ErrReader().Read([]byte{}) - if err != ErrIO { - t.Errorf("ErrReader.Read(any) should have returned ErrIO, returned %v", err) - } - if n != 0 { - t.Errorf("ErrReader.Read(any) should have read 0 bytes, read %v", n) + cases := []struct { + name string + err error + }{ + {"nil error", nil}, + {"non-nil error", errors.New("io failure")}, + {"io.EOF", io.EOF}, + } + + for _, tt := range cases { + tt := tt + t.Run(tt.name, func(t *testing.T) { + n, err := ErrReader(tt.err).Read(nil) + if err != tt.err { + t.Fatalf("Error mismatch\nGot: %v\nWant: %v", err, tt.err) + } + if n != 0 { + t.Fatalf("Byte count mismatch: got %d want 0", n) + } + }) } } -- cgit v1.3-5-g9baa