colog/colog_test.go

233 lines
4.4 KiB
Go

package colog
import (
"fmt"
"log"
"math/rand"
"sync"
"testing"
)
type outputTest struct {
in string
out string
}
var outputTests = []outputTest{
{"Info should be green %s", "[INF] Info should be green %s\n"},
}
func TestColors(t *testing.T) {
log.SetFlags(log.LstdFlags)
Register()
Get().SetMinLevel(LDebug)
Get().SetDefaultLevel(LDebug)
for _, tt := range outputTests {
tt.in = fmt.Sprintf(tt.in, "")
log.Println(tt.in)
}
}
func TestDefaultLevel(t *testing.T) {
tw := new(mockWriter)
log.SetFlags(0)
Register()
Get().SetOutput(tw)
Get().SetFormatter(&StdFormatter{Colors: false})
Get().SetDefaultLevel(LDebug)
log.Println("no prefix text")
if "[INF] no prefix text\n" != tw.String() {
t.Fatalf("Default level failed: %s", tw.String())
}
}
func TestMinDefaultLevel(t *testing.T) {
tw := new(mockWriter)
log.SetFlags(0)
Register()
Get().SetOutput(tw)
Get().SetFormatter(&StdFormatter{Colors: false})
Get().SetMinLevel(LDebug)
Get().SetDefaultLevel(LDebug)
log.Println("no prefix text")
if "[INF] no prefix text\n" != tw.String() {
t.Fatalf("Default level failed: %s", tw.String())
}
Get().SetMinLevel(LError)
log.Println("should not print")
if "[INF] no prefix text\n" != tw.String() {
t.Fatalf("Default level failed: %s", tw.String())
}
}
func TestPrefix(t *testing.T) {
tw := new(mockWriter)
cl := NewCoLog(tw, "abc ", 0)
cl.SetFormatter(&StdFormatter{Colors: false})
logger := cl.NewLogger()
logger.Println("some text")
if "[INF] abc some text\n" != tw.String() {
t.Fatalf("Prefix output failed: %s", tw.String())
}
}
func TestSimpleOutput(t *testing.T) {
tw := new(mockWriter)
cl := NewCoLog(tw, "", 0)
cl.SetFormatter(&StdFormatter{Colors: false})
logger := cl.NewLogger()
for k, tt := range outputTests {
seq := randSeq(k)
tt.in = fmt.Sprintf(tt.in, seq)
tt.out = fmt.Sprintf(tt.out, seq)
logger.Println(tt.in)
if tt.out != tw.String() {
t.Fatalf("Simple output not found:\n %s\n %s", tt.out, string(tw.Data))
}
}
}
func TestOutputRace(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(1)
go testStdLoggerOutput(t, &wg)
for i := 0; i < 100; i++ {
wg.Add(1)
go testNewLoggerOutput(t, &wg)
}
wg.Wait()
}
func testStdLoggerOutput(t *testing.T, wg *sync.WaitGroup) {
tb := new(mockBufferWriter)
tb.Data = make(map[string][]byte, len(outputTests))
log.SetFlags(0)
Register()
Get().SetOutput(tb)
Get().SetMinLevel(LDebug)
Get().SetDefaultLevel(LDebug)
Get().SetFormatter(&StdFormatter{Colors: false})
for k, tt := range outputTests {
wg.Add(1)
go func(tt outputTest, k int) {
seq := randSeq(k)
tt.in = fmt.Sprintf(tt.in, seq)
tt.out = fmt.Sprintf(tt.out, seq)
log.Println(tt.in)
if !tb.IsWritten(tt.out) {
t.Errorf("Raced std output not found: %s", tt.out)
}
wg.Done()
}(tt, k)
}
wg.Done()
}
func testNewLoggerOutput(t *testing.T, wg *sync.WaitGroup) {
tb := new(mockBufferWriter)
tb.Data = make(map[string][]byte, len(outputTests))
cl := NewCoLog(tb, "", 0)
cl.SetFormatter(&StdFormatter{Colors: false})
logger := cl.NewLogger()
for k, tt := range outputTests {
wg.Add(1)
go func(tt outputTest, k int) {
seq := randSeq(k)
tt.in = fmt.Sprintf(tt.in, seq)
tt.out = fmt.Sprintf(tt.out, seq)
logger.Println(tt.in)
if !tb.IsWritten(tt.out) {
t.Errorf("Raced logger output not found: %s", tt.out)
}
wg.Done()
}(tt, k)
}
wg.Done()
}
type mockWriter struct {
mux sync.Mutex
Data []byte
}
func (tw *mockWriter) Write(p []byte) (n int, err error) {
tw.mux.Lock()
defer tw.mux.Unlock()
tw.Data = p
return len(p), nil
}
func (tw *mockWriter) String() string {
tw.mux.Lock()
defer tw.mux.Unlock()
return string(tw.Data)
}
type mockBufferWriter struct {
mux sync.Mutex
Data map[string][]byte
}
func (tb *mockBufferWriter) Write(p []byte) (n int, err error) {
tb.mux.Lock()
defer tb.mux.Unlock()
tb.Data[string(p)] = p
return len(p), nil
}
func (tb *mockBufferWriter) IsWritten(s string) bool {
tb.mux.Lock()
defer tb.mux.Unlock()
_, ok := tb.Data[s]
return ok
}
type mockHook struct {
entry *Entry
levels []Level
}
func (h *mockHook) Levels() []Level {
return h.levels
}
func (h *mockHook) Fire(e *Entry) error {
h.entry = e
return nil
}
func randSeq(n int) string {
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}