logger_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright (c) 2017 Uber Technologies, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package zaptest
  21. import (
  22. "errors"
  23. "fmt"
  24. "io"
  25. "strings"
  26. "testing"
  27. "go.uber.org/zap"
  28. "go.uber.org/zap/internal/ztest"
  29. "go.uber.org/zap/zapcore"
  30. "github.com/stretchr/testify/assert"
  31. )
  32. func TestTestLogger(t *testing.T) {
  33. ts := newTestLogSpy(t)
  34. defer ts.AssertPassed()
  35. log := NewLogger(ts)
  36. log.Info("received work order")
  37. log.Debug("starting work")
  38. log.Warn("work may fail")
  39. log.Error("work failed", zap.Error(errors.New("great sadness")))
  40. assert.Panics(t, func() {
  41. log.Panic("failed to do work")
  42. }, "log.Panic should panic")
  43. ts.AssertMessages(
  44. "INFO received work order",
  45. "DEBUG starting work",
  46. "WARN work may fail",
  47. `ERROR work failed {"error": "great sadness"}`,
  48. "PANIC failed to do work",
  49. )
  50. }
  51. func TestTestLoggerSupportsLevels(t *testing.T) {
  52. ts := newTestLogSpy(t)
  53. defer ts.AssertPassed()
  54. log := NewLogger(ts, Level(zap.WarnLevel))
  55. log.Info("received work order")
  56. log.Debug("starting work")
  57. log.Warn("work may fail")
  58. log.Error("work failed", zap.Error(errors.New("great sadness")))
  59. assert.Panics(t, func() {
  60. log.Panic("failed to do work")
  61. }, "log.Panic should panic")
  62. ts.AssertMessages(
  63. "WARN work may fail",
  64. `ERROR work failed {"error": "great sadness"}`,
  65. "PANIC failed to do work",
  66. )
  67. }
  68. func TestTestLoggerSupportsWrappedZapOptions(t *testing.T) {
  69. ts := newTestLogSpy(t)
  70. defer ts.AssertPassed()
  71. log := NewLogger(ts, WrapOptions(zap.AddCaller(), zap.Fields(zap.String("k1", "v1"))))
  72. log.Info("received work order")
  73. log.Debug("starting work")
  74. log.Warn("work may fail")
  75. log.Error("work failed", zap.Error(errors.New("great sadness")))
  76. assert.Panics(t, func() {
  77. log.Panic("failed to do work")
  78. }, "log.Panic should panic")
  79. ts.AssertMessages(
  80. `INFO zaptest/logger_test.go:89 received work order {"k1": "v1"}`,
  81. `DEBUG zaptest/logger_test.go:90 starting work {"k1": "v1"}`,
  82. `WARN zaptest/logger_test.go:91 work may fail {"k1": "v1"}`,
  83. `ERROR zaptest/logger_test.go:92 work failed {"k1": "v1", "error": "great sadness"}`,
  84. `PANIC zaptest/logger_test.go:95 failed to do work {"k1": "v1"}`,
  85. )
  86. }
  87. func TestTestingWriter(t *testing.T) {
  88. ts := newTestLogSpy(t)
  89. w := newTestingWriter(ts)
  90. n, err := io.WriteString(w, "hello\n\n")
  91. assert.NoError(t, err, "WriteString must not fail")
  92. assert.Equal(t, 7, n)
  93. }
  94. func TestTestLoggerErrorOutput(t *testing.T) {
  95. // This test verifies that the test logger logs internal messages to the
  96. // testing.T and marks the test as failed.
  97. ts := newTestLogSpy(t)
  98. defer ts.AssertFailed()
  99. log := NewLogger(ts)
  100. // Replace with a core that fails.
  101. log = log.WithOptions(zap.WrapCore(func(zapcore.Core) zapcore.Core {
  102. return zapcore.NewCore(
  103. zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
  104. zapcore.Lock(zapcore.AddSync(ztest.FailWriter{})),
  105. zapcore.DebugLevel,
  106. )
  107. }))
  108. log.Info("foo") // this fails
  109. if assert.Len(t, ts.Messages, 1, "expected a log message") {
  110. assert.Regexp(t, `write error: failed`, ts.Messages[0])
  111. }
  112. }
  113. // testLogSpy is a testing.TB that captures logged messages.
  114. type testLogSpy struct {
  115. testing.TB
  116. failed bool
  117. Messages []string
  118. }
  119. func newTestLogSpy(t testing.TB) *testLogSpy {
  120. return &testLogSpy{TB: t}
  121. }
  122. func (t *testLogSpy) Fail() {
  123. t.failed = true
  124. }
  125. func (t *testLogSpy) Failed() bool {
  126. return t.failed
  127. }
  128. func (t *testLogSpy) FailNow() {
  129. t.Fail()
  130. t.TB.FailNow()
  131. }
  132. func (t *testLogSpy) Logf(format string, args ...interface{}) {
  133. // Log messages are in the format,
  134. //
  135. // 2017-10-27T13:03:01.000-0700 DEBUG your message here {data here}
  136. //
  137. // We strip the first part of these messages because we can't really test
  138. // for the timestamp from these tests.
  139. m := fmt.Sprintf(format, args...)
  140. m = m[strings.IndexByte(m, '\t')+1:]
  141. t.Messages = append(t.Messages, m)
  142. t.TB.Log(m)
  143. }
  144. func (t *testLogSpy) AssertMessages(msgs ...string) {
  145. assert.Equal(t.TB, msgs, t.Messages, "logged messages did not match")
  146. }
  147. func (t *testLogSpy) AssertPassed() {
  148. t.assertFailed(false, "expected test to pass")
  149. }
  150. func (t *testLogSpy) AssertFailed() {
  151. t.assertFailed(true, "expected test to fail")
  152. }
  153. func (t *testLogSpy) assertFailed(v bool, msg string) {
  154. assert.Equal(t.TB, v, t.failed, msg)
  155. }