vitess.io/vitess@v0.16.2/go/event/syslogger/syslogger_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreedto in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package syslogger 18 19 import ( 20 "fmt" 21 "log/syslog" 22 "strings" 23 "testing" 24 25 "vitess.io/vitess/go/event" 26 "vitess.io/vitess/go/vt/log" 27 ) 28 29 type TestEvent struct { 30 triggered bool 31 priority syslog.Priority 32 message string 33 } 34 35 func (ev *TestEvent) Syslog() (syslog.Priority, string) { 36 ev.triggered = true 37 return ev.priority, ev.message 38 } 39 40 var _ Syslogger = (*TestEvent)(nil) // compile-time interface check 41 42 type fakeWriter struct { 43 priority syslog.Priority 44 message string 45 err error // if non-nil, force an error to be returned 46 } 47 48 func (fw *fakeWriter) write(pri syslog.Priority, msg string) error { 49 if fw.err != nil { 50 return fw.err 51 } 52 53 fw.priority = pri 54 fw.message = msg 55 return nil 56 } 57 func (fw *fakeWriter) Alert(msg string) error { return fw.write(syslog.LOG_ALERT, msg) } 58 func (fw *fakeWriter) Crit(msg string) error { return fw.write(syslog.LOG_CRIT, msg) } 59 func (fw *fakeWriter) Debug(msg string) error { return fw.write(syslog.LOG_DEBUG, msg) } 60 func (fw *fakeWriter) Emerg(msg string) error { return fw.write(syslog.LOG_EMERG, msg) } 61 func (fw *fakeWriter) Err(msg string) error { return fw.write(syslog.LOG_ERR, msg) } 62 func (fw *fakeWriter) Info(msg string) error { return fw.write(syslog.LOG_INFO, msg) } 63 func (fw *fakeWriter) Notice(msg string) error { return fw.write(syslog.LOG_NOTICE, msg) } 64 func (fw *fakeWriter) Warning(msg string) error { return fw.write(syslog.LOG_WARNING, msg) } 65 66 type loggerMsg struct { 67 msg string 68 level string 69 } 70 type testLogger struct { 71 logs []loggerMsg 72 savedInfof func(format string, args ...any) 73 savedWarningf func(format string, args ...any) 74 savedErrorf func(format string, args ...any) 75 } 76 77 func newTestLogger() *testLogger { 78 tl := &testLogger{ 79 savedInfof: log.Infof, 80 savedWarningf: log.Warningf, 81 savedErrorf: log.Errorf, 82 } 83 log.Infof = tl.recordInfof 84 log.Warningf = tl.recordWarningf 85 log.Errorf = tl.recordErrorf 86 return tl 87 } 88 89 func (tl *testLogger) Close() { 90 log.Infof = tl.savedInfof 91 log.Warningf = tl.savedWarningf 92 log.Errorf = tl.savedErrorf 93 } 94 95 func (tl *testLogger) recordInfof(format string, args ...any) { 96 msg := fmt.Sprintf(format, args...) 97 tl.logs = append(tl.logs, loggerMsg{msg, "INFO"}) 98 tl.savedInfof(msg) 99 } 100 101 func (tl *testLogger) recordWarningf(format string, args ...any) { 102 msg := fmt.Sprintf(format, args...) 103 tl.logs = append(tl.logs, loggerMsg{msg, "WARNING"}) 104 tl.savedWarningf(msg) 105 } 106 107 func (tl *testLogger) recordErrorf(format string, args ...any) { 108 msg := fmt.Sprintf(format, args...) 109 tl.logs = append(tl.logs, loggerMsg{msg, "ERROR"}) 110 tl.savedErrorf(msg) 111 } 112 113 func (tl *testLogger) getLog() loggerMsg { 114 if len(tl.logs) > 0 { 115 return tl.logs[len(tl.logs)-1] 116 } 117 return loggerMsg{"no logs!", "ERROR"} 118 } 119 120 // TestSyslog checks that our callback works. 121 func TestSyslog(t *testing.T) { 122 writer = &fakeWriter{} 123 124 ev := new(TestEvent) 125 event.Dispatch(ev) 126 127 if !ev.triggered { 128 t.Errorf("Syslog() was not called on event that implements Syslogger") 129 } 130 } 131 132 // TestBadWriter verifies we are still triggering (to normal logs) if 133 // the syslog connection failed 134 func TestBadWriter(t *testing.T) { 135 tl := newTestLogger() 136 defer tl.Close() 137 138 writer = nil 139 wantMsg := "testing message" 140 wantLevel := "ERROR" 141 ev := &TestEvent{priority: syslog.LOG_ALERT, message: wantMsg} 142 event.Dispatch(ev) 143 if !strings.Contains(tl.getLog().msg, wantMsg) { 144 t.Errorf("error log msg [%s], want msg [%s]", tl.getLog().msg, wantMsg) 145 } 146 if !strings.Contains(tl.getLog().level, wantLevel) { 147 t.Errorf("error log level [%s], want level [%s]", tl.getLog().level, wantLevel) 148 } 149 ev = &TestEvent{priority: syslog.LOG_CRIT, message: wantMsg} 150 event.Dispatch(ev) 151 if !strings.Contains(tl.getLog().level, wantLevel) { 152 t.Errorf("error log level [%s], want level [%s]", tl.getLog().level, wantLevel) 153 } 154 ev = &TestEvent{priority: syslog.LOG_ERR, message: wantMsg} 155 event.Dispatch(ev) 156 if !strings.Contains(tl.getLog().level, wantLevel) { 157 t.Errorf("error log level [%s], want level [%s]", tl.getLog().level, wantLevel) 158 } 159 160 wantLevel = "WARNING" 161 ev = &TestEvent{priority: syslog.LOG_WARNING, message: wantMsg} 162 event.Dispatch(ev) 163 if !strings.Contains(tl.getLog().level, wantLevel) { 164 t.Errorf("error log level [%s], want level [%s]", tl.getLog().level, wantLevel) 165 } 166 167 wantLevel = "INFO" 168 ev = &TestEvent{priority: syslog.LOG_INFO, message: wantMsg} 169 event.Dispatch(ev) 170 if !strings.Contains(tl.getLog().level, wantLevel) { 171 t.Errorf("error log level [%s], want level [%s]", tl.getLog().level, wantLevel) 172 } 173 ev = &TestEvent{priority: syslog.LOG_NOTICE, message: wantMsg} 174 event.Dispatch(ev) 175 if !strings.Contains(tl.getLog().level, wantLevel) { 176 t.Errorf("error log level [%s], want level [%s]", tl.getLog().level, wantLevel) 177 } 178 ev = &TestEvent{priority: syslog.LOG_DEBUG, message: wantMsg} 179 event.Dispatch(ev) 180 if !strings.Contains(tl.getLog().level, wantLevel) { 181 t.Errorf("error log level [%s], want level [%s]", tl.getLog().level, wantLevel) 182 } 183 184 if !ev.triggered { 185 t.Errorf("passed nil writer to client") 186 } 187 } 188 189 // TestWriteError checks that we don't panic on a write error. 190 func TestWriteError(t *testing.T) { 191 writer = &fakeWriter{err: fmt.Errorf("forced error")} 192 193 event.Dispatch(&TestEvent{priority: syslog.LOG_EMERG}) 194 } 195 196 func TestInvalidSeverity(t *testing.T) { 197 fw := &fakeWriter{} 198 writer = fw 199 200 event.Dispatch(&TestEvent{priority: syslog.Priority(123), message: "log me"}) 201 202 if fw.message == "log me" { 203 t.Errorf("message was logged despite invalid severity") 204 } 205 } 206 207 func testSeverity(sev syslog.Priority, t *testing.T) { 208 fw := &fakeWriter{} 209 writer = fw 210 211 event.Dispatch(&TestEvent{priority: sev, message: "log me"}) 212 213 if fw.priority != sev { 214 t.Errorf("wrong priority: got %v, want %v", fw.priority, sev) 215 } 216 if fw.message != "log me" { 217 t.Errorf(`wrong message: got "%v", want "%v"`, fw.message, "log me") 218 } 219 } 220 221 func TestEmerg(t *testing.T) { 222 testSeverity(syslog.LOG_EMERG, t) 223 } 224 225 func TestAlert(t *testing.T) { 226 testSeverity(syslog.LOG_ALERT, t) 227 } 228 229 func TestCrit(t *testing.T) { 230 testSeverity(syslog.LOG_CRIT, t) 231 } 232 233 func TestErr(t *testing.T) { 234 testSeverity(syslog.LOG_ERR, t) 235 } 236 237 func TestWarning(t *testing.T) { 238 testSeverity(syslog.LOG_WARNING, t) 239 } 240 241 func TestNotice(t *testing.T) { 242 testSeverity(syslog.LOG_NOTICE, t) 243 } 244 245 func TestInfo(t *testing.T) { 246 testSeverity(syslog.LOG_INFO, t) 247 } 248 249 func TestDebug(t *testing.T) { 250 testSeverity(syslog.LOG_DEBUG, t) 251 }