package logging import ( "os" "strings" "testing" ) // These are provided to ease testing code that uses the logging pkg type mockWriter struct { written []byte } func (w *mockWriter) Write(p []byte) (n int, err os.Error) { w.written = append(w.written, p...) return len(p), nil } func (w *mockWriter) reset() { w.written = w.written[:0] } type writerMap map[LogLevel]*mockWriter // This doesn't create a mock Logger but a Logger that writes to mock outputs func NewMock() (*logger, writerMap) { wMap := writerMap{ Debug: &mockWriter{make([]byte, 0)}, Info: &mockWriter{make([]byte, 0)}, Warn: &mockWriter{make([]byte, 0)}, Error: &mockWriter{make([]byte, 0)}, Fatal: &mockWriter{make([]byte, 0)}, } logMap := make(LogMap) for lv, w := range wMap { logMap[lv] = makeLogger(w) } // Set the default log level high enough that everything will get logged return New(logMap, (1 << 31) - 1, false), wMap } func (m writerMap) CheckNothingWritten(t *testing.T) { for lv, w := range m { if len(w.written) > 0 { t.Errorf("%d bytes logged at level %s, expected none:", len(w.written), logString[lv]) t.Errorf("\t%s", w.written) w.reset() } } } func (m writerMap) CheckWrittenAtLevel(t *testing.T, lv LogLevel, exp string) { var w *mockWriter if _, ok := m[lv]; !ok { w = m[Debug] } else { w = m[lv] } // 20 bytes covers the date and time in // 2011/10/22 10:22:57 log_test.go:: if len(w.written) <= 20 { t.Errorf("Not enough bytes logged at level %s:", LogString(lv)) t.Errorf("exp: %s\ngot: %s", exp, w.written) // Check nothing was written to a different log level here, too. m.CheckNothingWritten(t) return } s := string(w.written[20:]) // consume the log line file:line: and the level prefix idx := strings.Index(s, ":") + 1 idx += strings.Index(s[idx:], ":") + len(LogString(lv)) + 3 // s will end in "\n", so -1 to chop that off too s = s[idx:len(s)-1] if s != exp { t.Errorf("Log message at level %s differed.", LogString(lv)) t.Errorf("exp: %s\ngot: %s", exp, s) t.Errorf("orig: %s", w.written) } w.reset() // Calling checkNothingWritten here both tests that w.reset() works // and verifies that nothing was written at any other levels. m.CheckNothingWritten(t) }