diff --git a/internal/ztest/writer.go b/internal/ztest/writer.go index 9fdd5805e..b9a1928dc 100644 --- a/internal/ztest/writer.go +++ b/internal/ztest/writer.go @@ -25,6 +25,7 @@ import ( "errors" "io/ioutil" "strings" + "sync" ) // A Syncer is a spy for the Sync portion of zapcore.WriteSyncer. @@ -94,3 +95,28 @@ func (b *Buffer) Lines() []string { func (b *Buffer) Stripped() string { return strings.TrimRight(b.String(), "\n") } + +// SyncBuffer is an implementation of bytes.Buffer which is goroutine safe. +type SyncBuffer struct { + sync.RWMutex + + buf bytes.Buffer +} + +// Write appends the contents of p to the buffer, growing the buffer as +// needed. +func (b *SyncBuffer) Write(p []byte) (n int, err error) { + b.Lock() + defer b.Unlock() + + return b.buf.Write(p) +} + +// String returns the contents of the unread portion of the buffer +// as a string. +func (b *SyncBuffer) String() string { + b.RLock() + defer b.RUnlock() + + return b.buf.String() +} diff --git a/zapcore/write_syncer_test.go b/zapcore/write_syncer_test.go index 98d62ff75..e41ae2369 100644 --- a/zapcore/write_syncer_test.go +++ b/zapcore/write_syncer_test.go @@ -122,7 +122,7 @@ func TestBufferWriter(t *testing.T) { }) t.Run("flush timer", func(t *testing.T) { - buf := &bytes.Buffer{} + buf := &ztest.SyncBuffer{} ws, close := Buffer(AddSync(buf), 6, time.Microsecond) defer close() requireWriteWorks(t, ws)