github.com/Laisky/zap@v1.27.0/zapcore/buffered_write_syncer_test.go (about) 1 // Copyright (c) 2021 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 "testing" 26 "time" 27 28 "github.com/Laisky/zap/internal/ztest" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 ) 32 33 func TestBufferWriter(t *testing.T) { 34 // If we pass a plain io.Writer, make sure that we still get a WriteSyncer 35 // with a no-op Sync. 36 t.Run("sync", func(t *testing.T) { 37 buf := &bytes.Buffer{} 38 ws := &BufferedWriteSyncer{WS: AddSync(buf)} 39 40 requireWriteWorks(t, ws) 41 assert.Empty(t, buf.String(), "Unexpected log calling a no-op Write method.") 42 assert.NoError(t, ws.Sync(), "Unexpected error calling a no-op Sync method.") 43 assert.Equal(t, "foo", buf.String(), "Unexpected log string") 44 assert.NoError(t, ws.Stop()) 45 }) 46 47 t.Run("stop", func(t *testing.T) { 48 buf := &bytes.Buffer{} 49 ws := &BufferedWriteSyncer{WS: AddSync(buf)} 50 requireWriteWorks(t, ws) 51 assert.Empty(t, buf.String(), "Unexpected log calling a no-op Write method.") 52 assert.NoError(t, ws.Stop()) 53 assert.Equal(t, "foo", buf.String(), "Unexpected log string") 54 }) 55 56 t.Run("stop twice", func(t *testing.T) { 57 ws := &BufferedWriteSyncer{WS: &ztest.FailWriter{}} 58 _, err := ws.Write([]byte("foo")) 59 require.NoError(t, err, "Unexpected error writing to WriteSyncer.") 60 assert.Error(t, ws.Stop(), "Expected stop to fail.") 61 assert.NoError(t, ws.Stop(), "Expected stop to not fail.") 62 }) 63 64 t.Run("wrap twice", func(t *testing.T) { 65 buf := &bytes.Buffer{} 66 bufsync := &BufferedWriteSyncer{WS: AddSync(buf)} 67 ws := &BufferedWriteSyncer{WS: bufsync} 68 requireWriteWorks(t, ws) 69 assert.Empty(t, buf.String(), "Unexpected log calling a no-op Write method.") 70 require.NoError(t, ws.Sync()) 71 assert.Equal(t, "foo", buf.String()) 72 assert.NoError(t, ws.Stop()) 73 assert.NoError(t, bufsync.Stop()) 74 assert.Equal(t, "foo", buf.String(), "Unexpected log string") 75 }) 76 77 t.Run("small buffer", func(t *testing.T) { 78 buf := &bytes.Buffer{} 79 ws := &BufferedWriteSyncer{WS: AddSync(buf), Size: 5} 80 81 requireWriteWorks(t, ws) 82 assert.Equal(t, "", buf.String(), "Unexpected log calling a no-op Write method.") 83 requireWriteWorks(t, ws) 84 assert.Equal(t, "foo", buf.String(), "Unexpected log string") 85 assert.NoError(t, ws.Stop()) 86 }) 87 88 t.Run("with lockedWriteSyncer", func(t *testing.T) { 89 buf := &bytes.Buffer{} 90 ws := &BufferedWriteSyncer{WS: Lock(AddSync(buf)), Size: 5} 91 92 requireWriteWorks(t, ws) 93 assert.Equal(t, "", buf.String(), "Unexpected log calling a no-op Write method.") 94 requireWriteWorks(t, ws) 95 assert.Equal(t, "foo", buf.String(), "Unexpected log string") 96 assert.NoError(t, ws.Stop()) 97 }) 98 99 t.Run("flush error", func(t *testing.T) { 100 ws := &BufferedWriteSyncer{WS: &ztest.FailWriter{}, Size: 4} 101 n, err := ws.Write([]byte("foo")) 102 require.NoError(t, err, "Unexpected error writing to WriteSyncer.") 103 require.Equal(t, 3, n, "Wrote an unexpected number of bytes.") 104 _, err = ws.Write([]byte("foo")) 105 assert.Error(t, err, "Expected error writing to WriteSyncer.") 106 assert.Error(t, ws.Stop(), "Expected stop to fail.") 107 }) 108 109 t.Run("flush timer", func(t *testing.T) { 110 buf := &bytes.Buffer{} 111 clock := ztest.NewMockClock() 112 ws := &BufferedWriteSyncer{ 113 WS: AddSync(buf), 114 Size: 6, 115 FlushInterval: time.Microsecond, 116 Clock: clock, 117 } 118 requireWriteWorks(t, ws) 119 clock.Add(10 * time.Microsecond) 120 assert.Equal(t, "foo", buf.String(), "Unexpected log string") 121 122 // flush twice to validate loop logic 123 requireWriteWorks(t, ws) 124 clock.Add(10 * time.Microsecond) 125 assert.Equal(t, "foofoo", buf.String(), "Unexpected log string") 126 assert.NoError(t, ws.Stop()) 127 }) 128 } 129 130 func TestBufferWriterWithoutStart(t *testing.T) { 131 t.Run("stop", func(t *testing.T) { 132 ws := &BufferedWriteSyncer{WS: AddSync(new(bytes.Buffer))} 133 assert.NoError(t, ws.Stop(), "Stop must not fail") 134 }) 135 136 t.Run("Sync", func(t *testing.T) { 137 ws := &BufferedWriteSyncer{WS: AddSync(new(bytes.Buffer))} 138 assert.NoError(t, ws.Sync(), "Sync must not fail") 139 }) 140 }