github.com/ssgreg/logf@v1.4.1/appender_test.go (about) 1 package logf 2 3 import ( 4 "encoding/base64" 5 "errors" 6 "os" 7 "syscall" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestDiscardAppender(t *testing.T) { 14 a := NewDiscardAppender() 15 16 assert.NoError(t, a.Append(Entry{})) 17 assert.NoError(t, a.Flush()) 18 assert.NoError(t, a.Sync()) 19 } 20 21 type testWriterNoSync struct { 22 writeData []byte 23 } 24 25 func (w *testWriterNoSync) Write(p []byte) (n int, err error) { 26 if len(p) == 0 { 27 panic("TestBuffer.Writer buffer can't be empty!") 28 } 29 w.writeData = p 30 31 return 0, nil 32 } 33 34 type testWriter struct { 35 writeData []byte 36 syncCounter int 37 38 e error 39 } 40 41 func (w *testWriter) Write(p []byte) (n int, err error) { 42 if len(p) == 0 { 43 panic("TestBuffer.Writer buffer can't be empty!") 44 } 45 w.writeData = p 46 47 return 0, nil 48 } 49 50 func (w *testWriter) Sync() error { 51 w.syncCounter++ 52 53 return w.e 54 } 55 56 func checkWriterData(t *testing.T, w *testWriter, writeData string, syncCounter int) { 57 assert.Equal(t, writeData, string(w.writeData)) 58 assert.Equal(t, syncCounter, w.syncCounter) 59 60 w.syncCounter = 0 61 w.writeData = nil 62 } 63 64 type failingEncoder struct { 65 e error 66 } 67 68 func (e *failingEncoder) Encode(*Buffer, Entry) error { 69 return e.e 70 } 71 72 type failingWriter struct { 73 e error 74 } 75 76 func (w *failingWriter) Write(p []byte) (n int, err error) { 77 return 0, w.e 78 } 79 80 func (w *failingWriter) Sync() error { 81 return w.e 82 } 83 84 func TestWriteAppenderErrors(t *testing.T) { 85 goldenErr := errors.New("test error") 86 87 w := testWriter{} 88 a := NewWriteAppender(&w, &failingEncoder{goldenErr}) 89 // Sync should be called once in constructor to check sync possibility. 90 checkWriterData(t, &w, "", 1) 91 92 assert.EqualError(t, a.Append(Entry{}), goldenErr.Error()) 93 checkWriterData(t, &w, "", 0) 94 95 a = NewWriteAppender(&failingWriter{goldenErr}, NewJSONEncoder.Default()) 96 assert.NoError(t, a.Append(Entry{})) 97 assert.EqualError(t, a.Flush(), goldenErr.Error()) 98 assert.EqualError(t, a.Sync(), goldenErr.Error()) 99 } 100 101 func TestWriteAppenderNoSync(t *testing.T) { 102 w := testWriterNoSync{} 103 104 a := NewWriteAppender(&w, NewJSONEncoder.Default()) 105 assert.NoError(t, a.Sync()) 106 } 107 108 func TestWriteAppenderInvalidSync(t *testing.T) { 109 // Check for EINVAL - a known error if Writer is bound to a 110 // special File (e.g., a pipe or socket) which does not support 111 // synchronization. 112 113 w := testWriter{e: &os.PathError{Err: syscall.EINVAL}} 114 115 a := NewWriteAppender(&w, NewJSONEncoder.Default()) 116 // Sync should be called once in constructor to check sync possibility. 117 checkWriterData(t, &w, "", 1) 118 119 assert.NoError(t, a.Sync()) 120 // Sync is ignoring now. 121 checkWriterData(t, &w, "", 0) 122 } 123 124 func TestWriteAppender(t *testing.T) { 125 w := testWriter{} 126 127 a := NewWriteAppender(&w, NewJSONEncoder.Default()) 128 // Sync should be called once in constructor to check sync possibility. 129 checkWriterData(t, &w, "", 1) 130 131 assert.NoError(t, a.Sync()) 132 // Expected no buffer because of no data and one sync call. 133 checkWriterData(t, &w, "", 1) 134 135 // Test Append auto flush. 136 137 bigEntry := Entry{ 138 Text: base64.StdEncoding.EncodeToString(make([]byte, PageSize)), 139 } 140 141 assert.NoError(t, a.Append(bigEntry)) 142 // Passed entry is enough to force Appender to call Flush automatically. 143 // Expected specified buffer and no sync calls. 144 checkWriterData(t, &w, `{"level":"error","ts":"0001-01-01T00:00:00Z","msg":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}`+"\n", 0) 145 146 // Test Flush. 147 148 assert.NoError(t, a.Append(Entry{})) 149 // Passed entry size less than Appender buffer size. So no buffer is 150 // expected and no sync calls. 151 checkWriterData(t, &w, "", 0) 152 153 assert.NoError(t, a.Flush()) 154 // Flush forced Appender to commit it's buffer. Expected specified 155 // buffer and no sync calls. 156 checkWriterData(t, &w, `{"level":"error","ts":"0001-01-01T00:00:00Z","msg":""}`+"\n", 0) 157 158 assert.NoError(t, a.Flush()) 159 // Second flush should do nothing. 160 checkWriterData(t, &w, "", 0) 161 162 // Test Sync. 163 164 assert.NoError(t, a.Append(Entry{})) 165 // Passed entry size less than Appender buffer size. So no buffer is 166 // expected and no sync calls. 167 checkWriterData(t, &w, "", 0) 168 169 assert.NoError(t, a.Flush()) 170 assert.NoError(t, a.Sync()) 171 // Sync forced Appender to commit it's buffer. Expected specified 172 // buffer and one sync call. 173 checkWriterData(t, &w, `{"level":"error","ts":"0001-01-01T00:00:00Z","msg":""}`+"\n", 1) 174 }