123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- package logx
- import (
- "bytes"
- "encoding/json"
- "errors"
- "log"
- "sync/atomic"
- "testing"
- "github.com/stretchr/testify/assert"
- )
- func TestNewWriter(t *testing.T) {
- const literal = "foo bar"
- var buf bytes.Buffer
- w := NewWriter(&buf)
- w.Info(literal)
- assert.Contains(t, buf.String(), literal)
- buf.Reset()
- w.Debug(literal)
- assert.Contains(t, buf.String(), literal)
- }
- func TestConsoleWriter(t *testing.T) {
- var buf bytes.Buffer
- w := newConsoleWriter()
- lw := newLogWriter(log.New(&buf, "", 0))
- w.(*concreteWriter).errorLog = lw
- w.Alert("foo bar 1")
- var val mockedEntry
- if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, levelAlert, val.Level)
- assert.Equal(t, "foo bar 1", val.Content)
- buf.Reset()
- w.(*concreteWriter).errorLog = lw
- w.Error("foo bar 2")
- if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, levelError, val.Level)
- assert.Equal(t, "foo bar 2", val.Content)
- buf.Reset()
- w.(*concreteWriter).infoLog = lw
- w.Info("foo bar 3")
- if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, levelInfo, val.Level)
- assert.Equal(t, "foo bar 3", val.Content)
- buf.Reset()
- w.(*concreteWriter).severeLog = lw
- w.Severe("foo bar 4")
- if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, levelFatal, val.Level)
- assert.Equal(t, "foo bar 4", val.Content)
- buf.Reset()
- w.(*concreteWriter).slowLog = lw
- w.Slow("foo bar 5")
- if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, levelSlow, val.Level)
- assert.Equal(t, "foo bar 5", val.Content)
- buf.Reset()
- w.(*concreteWriter).statLog = lw
- w.Stat("foo bar 6")
- if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, levelStat, val.Level)
- assert.Equal(t, "foo bar 6", val.Content)
- w.(*concreteWriter).infoLog = hardToCloseWriter{}
- assert.NotNil(t, w.Close())
- w.(*concreteWriter).infoLog = easyToCloseWriter{}
- w.(*concreteWriter).errorLog = hardToCloseWriter{}
- assert.NotNil(t, w.Close())
- w.(*concreteWriter).errorLog = easyToCloseWriter{}
- w.(*concreteWriter).severeLog = hardToCloseWriter{}
- assert.NotNil(t, w.Close())
- w.(*concreteWriter).severeLog = easyToCloseWriter{}
- w.(*concreteWriter).slowLog = hardToCloseWriter{}
- assert.NotNil(t, w.Close())
- w.(*concreteWriter).slowLog = easyToCloseWriter{}
- w.(*concreteWriter).statLog = hardToCloseWriter{}
- assert.NotNil(t, w.Close())
- w.(*concreteWriter).statLog = easyToCloseWriter{}
- }
- func TestNewFileWriter(t *testing.T) {
- t.Run("access", func(t *testing.T) {
- _, err := newFileWriter(LogConf{
- Path: "/not-exists",
- })
- assert.Error(t, err)
- })
- }
- func TestNopWriter(t *testing.T) {
- assert.NotPanics(t, func() {
- var w nopWriter
- w.Alert("foo")
- w.Debug("foo")
- w.Error("foo")
- w.Info("foo")
- w.Severe("foo")
- w.Stack("foo")
- w.Stat("foo")
- w.Slow("foo")
- _ = w.Close()
- })
- }
- func TestWriteJson(t *testing.T) {
- var buf bytes.Buffer
- log.SetOutput(&buf)
- writeJson(nil, "foo")
- assert.Contains(t, buf.String(), "foo")
- buf.Reset()
- writeJson(hardToWriteWriter{}, "foo")
- assert.Contains(t, buf.String(), "write error")
- buf.Reset()
- writeJson(nil, make(chan int))
- assert.Contains(t, buf.String(), "unsupported type")
- buf.Reset()
- type C struct {
- RC func()
- }
- writeJson(nil, C{
- RC: func() {},
- })
- assert.Contains(t, buf.String(), "runtime/debug.Stack")
- }
- func TestWritePlainAny(t *testing.T) {
- var buf bytes.Buffer
- log.SetOutput(&buf)
- writePlainAny(nil, levelInfo, "foo")
- assert.Contains(t, buf.String(), "foo")
- buf.Reset()
- writePlainAny(nil, levelDebug, make(chan int))
- assert.Contains(t, buf.String(), "unsupported type")
- writePlainAny(nil, levelDebug, 100)
- assert.Contains(t, buf.String(), "100")
- buf.Reset()
- writePlainAny(nil, levelError, make(chan int))
- assert.Contains(t, buf.String(), "unsupported type")
- writePlainAny(nil, levelSlow, 100)
- assert.Contains(t, buf.String(), "100")
- buf.Reset()
- writePlainAny(hardToWriteWriter{}, levelStat, 100)
- assert.Contains(t, buf.String(), "write error")
- buf.Reset()
- writePlainAny(hardToWriteWriter{}, levelSevere, "foo")
- assert.Contains(t, buf.String(), "write error")
- buf.Reset()
- writePlainAny(hardToWriteWriter{}, levelAlert, "foo")
- assert.Contains(t, buf.String(), "write error")
- buf.Reset()
- writePlainAny(hardToWriteWriter{}, levelFatal, "foo")
- assert.Contains(t, buf.String(), "write error")
- buf.Reset()
- type C struct {
- RC func()
- }
- writePlainAny(nil, levelError, C{
- RC: func() {},
- })
- assert.Contains(t, buf.String(), "runtime/debug.Stack")
- }
- func TestLogWithLimitContentLength(t *testing.T) {
- maxLen := atomic.LoadUint32(&maxContentLength)
- atomic.StoreUint32(&maxContentLength, 10)
- t.Cleanup(func() {
- atomic.StoreUint32(&maxContentLength, maxLen)
- })
- t.Run("alert", func(t *testing.T) {
- var buf bytes.Buffer
- w := NewWriter(&buf)
- w.Info("1234567890")
- var v1 mockedEntry
- if err := json.Unmarshal(buf.Bytes(), &v1); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, "1234567890", v1.Content)
- assert.False(t, v1.Truncated)
- buf.Reset()
- var v2 mockedEntry
- w.Info("12345678901")
- if err := json.Unmarshal(buf.Bytes(), &v2); err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, "1234567890", v2.Content)
- assert.True(t, v2.Truncated)
- })
- }
- type mockedEntry struct {
- Level string `json:"level"`
- Content string `json:"content"`
- Truncated bool `json:"truncated"`
- }
- type easyToCloseWriter struct{}
- func (h easyToCloseWriter) Write(_ []byte) (_ int, _ error) {
- return
- }
- func (h easyToCloseWriter) Close() error {
- return nil
- }
- type hardToCloseWriter struct{}
- func (h hardToCloseWriter) Write(_ []byte) (_ int, _ error) {
- return
- }
- func (h hardToCloseWriter) Close() error {
- return errors.New("close error")
- }
- type hardToWriteWriter struct{}
- func (h hardToWriteWriter) Write(_ []byte) (_ int, _ error) {
- return 0, errors.New("write error")
- }
|