writer_test.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package logx
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "log"
  7. "sync/atomic"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. func TestNewWriter(t *testing.T) {
  12. const literal = "foo bar"
  13. var buf bytes.Buffer
  14. w := NewWriter(&buf)
  15. w.Info(literal)
  16. assert.Contains(t, buf.String(), literal)
  17. buf.Reset()
  18. w.Debug(literal)
  19. assert.Contains(t, buf.String(), literal)
  20. }
  21. func TestConsoleWriter(t *testing.T) {
  22. var buf bytes.Buffer
  23. w := newConsoleWriter()
  24. lw := newLogWriter(log.New(&buf, "", 0))
  25. w.(*concreteWriter).errorLog = lw
  26. w.Alert("foo bar 1")
  27. var val mockedEntry
  28. if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
  29. t.Fatal(err)
  30. }
  31. assert.Equal(t, levelAlert, val.Level)
  32. assert.Equal(t, "foo bar 1", val.Content)
  33. buf.Reset()
  34. w.(*concreteWriter).errorLog = lw
  35. w.Error("foo bar 2")
  36. if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
  37. t.Fatal(err)
  38. }
  39. assert.Equal(t, levelError, val.Level)
  40. assert.Equal(t, "foo bar 2", val.Content)
  41. buf.Reset()
  42. w.(*concreteWriter).infoLog = lw
  43. w.Info("foo bar 3")
  44. if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
  45. t.Fatal(err)
  46. }
  47. assert.Equal(t, levelInfo, val.Level)
  48. assert.Equal(t, "foo bar 3", val.Content)
  49. buf.Reset()
  50. w.(*concreteWriter).severeLog = lw
  51. w.Severe("foo bar 4")
  52. if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
  53. t.Fatal(err)
  54. }
  55. assert.Equal(t, levelFatal, val.Level)
  56. assert.Equal(t, "foo bar 4", val.Content)
  57. buf.Reset()
  58. w.(*concreteWriter).slowLog = lw
  59. w.Slow("foo bar 5")
  60. if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
  61. t.Fatal(err)
  62. }
  63. assert.Equal(t, levelSlow, val.Level)
  64. assert.Equal(t, "foo bar 5", val.Content)
  65. buf.Reset()
  66. w.(*concreteWriter).statLog = lw
  67. w.Stat("foo bar 6")
  68. if err := json.Unmarshal(buf.Bytes(), &val); err != nil {
  69. t.Fatal(err)
  70. }
  71. assert.Equal(t, levelStat, val.Level)
  72. assert.Equal(t, "foo bar 6", val.Content)
  73. w.(*concreteWriter).infoLog = hardToCloseWriter{}
  74. assert.NotNil(t, w.Close())
  75. w.(*concreteWriter).infoLog = easyToCloseWriter{}
  76. w.(*concreteWriter).errorLog = hardToCloseWriter{}
  77. assert.NotNil(t, w.Close())
  78. w.(*concreteWriter).errorLog = easyToCloseWriter{}
  79. w.(*concreteWriter).severeLog = hardToCloseWriter{}
  80. assert.NotNil(t, w.Close())
  81. w.(*concreteWriter).severeLog = easyToCloseWriter{}
  82. w.(*concreteWriter).slowLog = hardToCloseWriter{}
  83. assert.NotNil(t, w.Close())
  84. w.(*concreteWriter).slowLog = easyToCloseWriter{}
  85. w.(*concreteWriter).statLog = hardToCloseWriter{}
  86. assert.NotNil(t, w.Close())
  87. w.(*concreteWriter).statLog = easyToCloseWriter{}
  88. }
  89. func TestNopWriter(t *testing.T) {
  90. assert.NotPanics(t, func() {
  91. var w nopWriter
  92. w.Alert("foo")
  93. w.Debug("foo")
  94. w.Error("foo")
  95. w.Info("foo")
  96. w.Severe("foo")
  97. w.Stack("foo")
  98. w.Stat("foo")
  99. w.Slow("foo")
  100. _ = w.Close()
  101. })
  102. }
  103. func TestWriteJson(t *testing.T) {
  104. var buf bytes.Buffer
  105. log.SetOutput(&buf)
  106. writeJson(nil, "foo")
  107. assert.Contains(t, buf.String(), "foo")
  108. buf.Reset()
  109. writeJson(nil, make(chan int))
  110. assert.Contains(t, buf.String(), "unsupported type")
  111. }
  112. func TestWritePlainAny(t *testing.T) {
  113. var buf bytes.Buffer
  114. log.SetOutput(&buf)
  115. writePlainAny(nil, levelInfo, "foo")
  116. assert.Contains(t, buf.String(), "foo")
  117. buf.Reset()
  118. writePlainAny(nil, levelDebug, make(chan int))
  119. assert.Contains(t, buf.String(), "unsupported type")
  120. writePlainAny(nil, levelDebug, 100)
  121. assert.Contains(t, buf.String(), "100")
  122. buf.Reset()
  123. writePlainAny(nil, levelError, make(chan int))
  124. assert.Contains(t, buf.String(), "unsupported type")
  125. writePlainAny(nil, levelSlow, 100)
  126. assert.Contains(t, buf.String(), "100")
  127. buf.Reset()
  128. writePlainAny(hardToWriteWriter{}, levelStat, 100)
  129. assert.Contains(t, buf.String(), "write error")
  130. buf.Reset()
  131. writePlainAny(hardToWriteWriter{}, levelSevere, "foo")
  132. assert.Contains(t, buf.String(), "write error")
  133. buf.Reset()
  134. writePlainAny(hardToWriteWriter{}, levelAlert, "foo")
  135. assert.Contains(t, buf.String(), "write error")
  136. buf.Reset()
  137. writePlainAny(hardToWriteWriter{}, levelFatal, "foo")
  138. assert.Contains(t, buf.String(), "write error")
  139. }
  140. func TestLogWithLimitContentLength(t *testing.T) {
  141. maxLen := atomic.LoadUint32(&maxContentLength)
  142. atomic.StoreUint32(&maxContentLength, 10)
  143. t.Cleanup(func() {
  144. atomic.StoreUint32(&maxContentLength, maxLen)
  145. })
  146. t.Run("alert", func(t *testing.T) {
  147. var buf bytes.Buffer
  148. w := NewWriter(&buf)
  149. w.Info("1234567890")
  150. var v1 mockedEntry
  151. if err := json.Unmarshal(buf.Bytes(), &v1); err != nil {
  152. t.Fatal(err)
  153. }
  154. assert.Equal(t, "1234567890", v1.Content)
  155. assert.False(t, v1.Truncated)
  156. buf.Reset()
  157. var v2 mockedEntry
  158. w.Info("12345678901")
  159. if err := json.Unmarshal(buf.Bytes(), &v2); err != nil {
  160. t.Fatal(err)
  161. }
  162. assert.Equal(t, "1234567890", v2.Content)
  163. assert.True(t, v2.Truncated)
  164. })
  165. }
  166. type mockedEntry struct {
  167. Level string `json:"level"`
  168. Content string `json:"content"`
  169. Truncated bool `json:"truncated"`
  170. }
  171. type easyToCloseWriter struct{}
  172. func (h easyToCloseWriter) Write(_ []byte) (_ int, _ error) {
  173. return
  174. }
  175. func (h easyToCloseWriter) Close() error {
  176. return nil
  177. }
  178. type hardToCloseWriter struct{}
  179. func (h hardToCloseWriter) Write(_ []byte) (_ int, _ error) {
  180. return
  181. }
  182. func (h hardToCloseWriter) Close() error {
  183. return errors.New("close error")
  184. }
  185. type hardToWriteWriter struct{}
  186. func (h hardToWriteWriter) Write(_ []byte) (_ int, _ error) {
  187. return 0, errors.New("write error")
  188. }