...

Source file src/go.uber.org/zap/zapcore/write_syncer_test.go

Documentation: go.uber.org/zap/zapcore

     1  // Copyright (c) 2016 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package zapcore
    22  
    23  import (
    24  	"bytes"
    25  	"errors"
    26  	"io"
    27  	"testing"
    28  
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/require"
    31  	"go.uber.org/zap/internal/ztest"
    32  )
    33  
    34  type writeSyncSpy struct {
    35  	io.Writer
    36  	ztest.Syncer
    37  }
    38  
    39  func requireWriteWorks(t testing.TB, ws WriteSyncer) {
    40  	n, err := ws.Write([]byte("foo"))
    41  	require.NoError(t, err, "Unexpected error writing to WriteSyncer.")
    42  	require.Equal(t, 3, n, "Wrote an unexpected number of bytes.")
    43  }
    44  
    45  func TestAddSyncWriteSyncer(t *testing.T) {
    46  	buf := &bytes.Buffer{}
    47  	concrete := &writeSyncSpy{Writer: buf}
    48  	ws := AddSync(concrete)
    49  	requireWriteWorks(t, ws)
    50  
    51  	require.NoError(t, ws.Sync(), "Unexpected error syncing a WriteSyncer.")
    52  	require.True(t, concrete.Called(), "Expected to dispatch to concrete type's Sync method.")
    53  
    54  	concrete.SetError(errors.New("fail"))
    55  	assert.Error(t, ws.Sync(), "Expected to propagate errors from concrete type's Sync method.")
    56  }
    57  
    58  func TestAddSyncWriter(t *testing.T) {
    59  	// If we pass a plain io.Writer, make sure that we still get a WriteSyncer
    60  	// with a no-op Sync.
    61  	buf := &bytes.Buffer{}
    62  	ws := AddSync(buf)
    63  	requireWriteWorks(t, ws)
    64  	assert.NoError(t, ws.Sync(), "Unexpected error calling a no-op Sync method.")
    65  }
    66  
    67  func TestNewMultiWriteSyncerWorksForSingleWriter(t *testing.T) {
    68  	w := &ztest.Buffer{}
    69  
    70  	ws := NewMultiWriteSyncer(w)
    71  	assert.Equal(t, w, ws, "Expected NewMultiWriteSyncer to return the same WriteSyncer object for a single argument.")
    72  
    73  	assert.NoError(t, ws.Sync(), "Expected Sync to succeed.")
    74  	assert.True(t, w.Called(), "Expected Sync to be called on the created WriteSyncer")
    75  }
    76  
    77  func TestMultiWriteSyncerWritesBoth(t *testing.T) {
    78  	first := &bytes.Buffer{}
    79  	second := &bytes.Buffer{}
    80  	ws := NewMultiWriteSyncer(AddSync(first), AddSync(second))
    81  
    82  	msg := []byte("dumbledore")
    83  	n, err := ws.Write(msg)
    84  	require.NoError(t, err, "Expected successful buffer write")
    85  	assert.Equal(t, len(msg), n)
    86  
    87  	assert.Equal(t, msg, first.Bytes())
    88  	assert.Equal(t, msg, second.Bytes())
    89  }
    90  
    91  func TestMultiWriteSyncerFailsWrite(t *testing.T) {
    92  	ws := NewMultiWriteSyncer(AddSync(&ztest.FailWriter{}))
    93  	_, err := ws.Write([]byte("test"))
    94  	assert.Error(t, err, "Write error should propagate")
    95  }
    96  
    97  func TestMultiWriteSyncerFailsShortWrite(t *testing.T) {
    98  	ws := NewMultiWriteSyncer(AddSync(&ztest.ShortWriter{}))
    99  	n, err := ws.Write([]byte("test"))
   100  	assert.NoError(t, err, "Expected fake-success from short write")
   101  	assert.Equal(t, 3, n, "Expected byte count to return from underlying writer")
   102  }
   103  
   104  func TestWritestoAllSyncs_EvenIfFirstErrors(t *testing.T) {
   105  	failer := &ztest.FailWriter{}
   106  	second := &bytes.Buffer{}
   107  	ws := NewMultiWriteSyncer(AddSync(failer), AddSync(second))
   108  
   109  	_, err := ws.Write([]byte("fail"))
   110  	assert.Error(t, err, "Expected error from call to a writer that failed")
   111  	assert.Equal(t, []byte("fail"), second.Bytes(), "Expected second sink to be written after first error")
   112  }
   113  
   114  func TestMultiWriteSyncerSync_PropagatesErrors(t *testing.T) {
   115  	badsink := &ztest.Buffer{}
   116  	badsink.SetError(errors.New("sink is full"))
   117  	ws := NewMultiWriteSyncer(&ztest.Discarder{}, badsink)
   118  
   119  	assert.Error(t, ws.Sync(), "Expected sync error to propagate")
   120  }
   121  
   122  func TestMultiWriteSyncerSync_NoErrorsOnDiscard(t *testing.T) {
   123  	ws := NewMultiWriteSyncer(&ztest.Discarder{})
   124  	assert.NoError(t, ws.Sync(), "Expected error-free sync to /dev/null")
   125  }
   126  
   127  func TestMultiWriteSyncerSync_AllCalled(t *testing.T) {
   128  	failed, second := &ztest.Buffer{}, &ztest.Buffer{}
   129  
   130  	failed.SetError(errors.New("disposal broken"))
   131  	ws := NewMultiWriteSyncer(failed, second)
   132  
   133  	assert.Error(t, ws.Sync(), "Expected first sink to fail")
   134  	assert.True(t, failed.Called(), "Expected first sink to have Sync method called.")
   135  	assert.True(t, second.Called(), "Expected call to Sync even with first failure.")
   136  }
   137  

View as plain text