From e671a552fe9ba75a04b65fe689d004dc64b87975 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 14 Nov 2017 14:54:10 -0500 Subject: [PATCH] io: document and test MultiWriter error behavior MultiWriter(w1, w2) only writes to w2 if w1.Write succeeds. I did not know this, and it was not documented. Document and test. Change-Id: Idec2e8444d5a7aca0b95d07814a28daa454eb1d3 Reviewed-on: https://go-review.googlesource.com/78123 Run-TryBot: Russ Cox Reviewed-by: Joe Tsai Reviewed-by: Brad Fitzpatrick --- src/io/multi.go | 4 ++++ src/io/multi_test.go | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/io/multi.go b/src/io/multi.go index c662765a3b5..65f99099ca7 100644 --- a/src/io/multi.go +++ b/src/io/multi.go @@ -95,6 +95,10 @@ func (t *multiWriter) WriteString(s string) (n int, err error) { // MultiWriter creates a writer that duplicates its writes to all the // provided writers, similar to the Unix tee(1) command. +// +// Each write is written to each listed writer, one at a time. +// If a listed writer returns an error, that overall write operation +// stops and returns the error; it does not continue down the list. func MultiWriter(writers ...Writer) Writer { allWriters := make([]Writer, 0, len(writers)) for _, w := range writers { diff --git a/src/io/multi_test.go b/src/io/multi_test.go index 83eef756fd7..9cbab4d211e 100644 --- a/src/io/multi_test.go +++ b/src/io/multi_test.go @@ -176,6 +176,21 @@ func TestMultiWriterSingleChainFlatten(t *testing.T) { } } +func TestMultiWriterError(t *testing.T) { + f1 := writerFunc(func(p []byte) (int, error) { + return len(p) / 2, ErrShortWrite + }) + f2 := writerFunc(func(p []byte) (int, error) { + t.Errorf("MultiWriter called f2.Write") + return len(p), nil + }) + w := MultiWriter(f1, f2) + n, err := w.Write(make([]byte, 100)) + if n != 50 || err != ErrShortWrite { + t.Errorf("Write = %d, %v, want 50, ErrShortWrite", n, err) + } +} + // Test that MultiReader copies the input slice and is insulated from future modification. func TestMultiReaderCopy(t *testing.T) { slice := []Reader{strings.NewReader("hello world")}